Files
tasks/pkg/sdk/client/helpers_test.go
zeekay 6112841b1e feat(sdk/client): native user-facing RPC surface, zero upstream deps
Implements pkg/sdk/client — the Temporal-replacement surface base,
commerce, and ta call when migrating off go.temporal.io/sdk/client.
Transport is luxfi/zap; zero go.temporal.io/* and zero
google.golang.org/grpc imports.

Opcode allocation (append-only, never reuse):
  0x0050-0x005F pkg/tasks legacy (submit / schedule), reserved
  0x0060-0x006F workflow lifecycle (start, signal, cancel,
                terminate, describe, list)
  0x0070-0x007F schedule ops (create, list, delete, pause)
  0x0080-0x008F namespace ops (register, describe, list)
  0x0090-0x009F health + meta
  0x00A0-0x00AF worker poll / respond (moved up from 0x0070
                to avoid collision with schedule ops)

Wire (v1): request and response bodies are a JSON document wrapped
in a ZAP envelope with three fields:
  field 0  (Bytes)  — body
  field 8  (Uint32) — status (0/200 = ok)
  field 12 (Bytes)  — error detail on non-zero status
Opcode is stamped on the ZAP frame flags (high byte). Native ZAP
serde replaces JSON in a follow-up without changing opcodes.

Files:
- client.go      — Client interface (Close/ExecuteWorkflow/SignalWorkflow/
                   CancelWorkflow/Terminate/Describe/List + schedule +
                   namespace + health), Dial, Transport abstraction,
                   luxfi/zap default transport, envelope codec.
- options.go     — Options, StartWorkflowOptions (RetryPolicy via
                   pkg/sdk/temporal, no upstream import).
- workflow.go    — ExecuteWorkflow, Signal/Cancel/Terminate/Describe/List,
                   WorkflowRun with reflect-based type-name resolution.
- namespace.go   — Register/Describe/List + wire duration-ms codec.
- schedule.go    — Create/List/Delete/Pause + wire duration-ms codec.
- transport.go   — WorkerTransport + PollWorkflowTaskRequest etc. +
                   the worker-opcode constants (now 0x00A0+).
- client_test.go — Dial/Close test, ExecuteWorkflow round-trip with a
                   fake Transport capturing the request and replaying
                   a canned response (same pattern as pkg/tasks).

Worker bridge helpers (worker_bridge.go, worker_transport.go) were
added concurrently on feat/zap-internal; they import and wrap the
Transport this commit defines.

WorkflowRun.Get gap: the v1 schema does not yet declare a
GetWorkflowHistory / GetWorkflowResult RPC, so Get polls
DescribeWorkflow and returns ErrNotImplementedLocally when the
caller asks for a result from a completed workflow. This is marked
in the doc comment and will be filled in when pkg/sdk/worker lands
the history-fetch opcode.

Verification:
  go vet ./pkg/sdk/client/...    — clean
  go test ./pkg/sdk/client/...   — 7/7 pass
  go list -deps ./pkg/sdk/client/...  — no go.temporal.io/*, no
                                        google.golang.org/grpc
2026-04-23 10:38:02 -07:00

32 lines
1.0 KiB
Go

package client
import (
"encoding/json"
"github.com/luxfi/zap"
)
// encodeTestResponseFrame builds the ZAP envelope frame that the
// production zap.Node would return from a server handler. Kept in the
// test file so the production file carries no test-only code paths.
func encodeTestResponseFrame(opcode uint16, status uint32, detail string, body []byte) []byte {
b := zap.NewBuilder(len(body) + envelopeObjectSize + 64)
obj := b.StartObject(envelopeObjectSize)
obj.SetBytes(envelopeBody, body)
obj.SetUint32(envelopeStatus, status)
if detail != "" {
obj.SetBytes(envelopeError, []byte(detail))
}
obj.FinishAsRoot()
return b.FinishWithFlags(uint16(opcode) << 8)
}
// decodeStubRequestBody decodes the JSON body that clientImpl.roundTrip
// hands to Transport.Call. Requests are delivered to Transport as raw
// JSON bytes (the envelope is applied inside the zapTransport Call
// implementation), so tests can inspect the payload without parsing a
// ZAP frame.
func decodeStubRequestBody(body []byte, out any) error {
return json.Unmarshal(body, out)
}