@ontemper/sdk 0.4.10-rc.1 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +24 -0
  2. package/dist/Answer.d.ts +68 -0
  3. package/dist/Answer.d.ts.map +1 -0
  4. package/dist/Answer.js +239 -0
  5. package/dist/Answer.js.map +1 -0
  6. package/dist/Contract/EarlyAnswer.d.ts +35 -0
  7. package/dist/Contract/EarlyAnswer.d.ts.map +1 -0
  8. package/dist/Contract/EarlyAnswer.js +21 -0
  9. package/dist/Contract/EarlyAnswer.js.map +1 -0
  10. package/dist/Contract/Invocation.d.ts +6 -0
  11. package/dist/Contract/Invocation.d.ts.map +1 -1
  12. package/dist/Contract/Manifest.d.ts +20 -167
  13. package/dist/Contract/Manifest.d.ts.map +1 -1
  14. package/dist/Contract/Manifest.js +8 -65
  15. package/dist/Contract/Manifest.js.map +1 -1
  16. package/dist/Contract/index.d.ts +2 -1
  17. package/dist/Contract/index.d.ts.map +1 -1
  18. package/dist/Contract/index.js +2 -1
  19. package/dist/Contract/index.js.map +1 -1
  20. package/dist/Manifest.d.ts +1 -1
  21. package/dist/Manifest.d.ts.map +1 -1
  22. package/dist/Manifest.js +1 -2
  23. package/dist/Manifest.js.map +1 -1
  24. package/dist/Middleware.d.ts.map +1 -1
  25. package/dist/Middleware.js +19 -3
  26. package/dist/Middleware.js.map +1 -1
  27. package/dist/Trigger.d.ts +1 -55
  28. package/dist/Trigger.d.ts.map +1 -1
  29. package/dist/Trigger.js +0 -29
  30. package/dist/Trigger.js.map +1 -1
  31. package/dist/Workflow.d.ts.map +1 -1
  32. package/dist/Workflow.js +4 -1
  33. package/dist/Workflow.js.map +1 -1
  34. package/dist/cli.d.ts.map +1 -1
  35. package/dist/cli.js +17 -7
  36. package/dist/cli.js.map +1 -1
  37. package/dist/index.d.ts +4 -2
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +2 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/testing.d.ts +17 -0
  42. package/dist/testing.d.ts.map +1 -1
  43. package/dist/testing.js +66 -0
  44. package/dist/testing.js.map +1 -1
  45. package/package.json +2 -2
package/README.md CHANGED
@@ -84,6 +84,7 @@ type InvocationContext = {
84
84
  triggerKind: 'http' | 'schedule' | 'manual' | 'agent' | 'as2' | 'sftp' | 'kafka' | 'child';
85
85
  deadline: number; // epoch milliseconds
86
86
  token: string; // run-scoped platform token
87
+ responsePolicy?: 'wait' | 'ack' | 'early' | ''; // the route's stored policy; '' from an older host
87
88
  };
88
89
  ```
89
90
 
@@ -96,6 +97,29 @@ The SDK owns three runtime behaviours around every handler:
96
97
  ahead of the host's own timer.
97
98
  3. Headers: platform `x-temper-*` request headers are removed before the handler runs.
98
99
 
100
+ ## Answer early, then keep working
101
+
102
+ 🟡 Proposed ([early-answer Runs](../../docs/specs/early-answer-runs.md), A4 open). On a route whose
103
+ stored response policy is `early`, `Answer.early(response)` sends the caller its answer now. The
104
+ handler keeps running in the same Run, and the value it returns sets only the Run outcome:
105
+
106
+ ```ts
107
+ .handle('createOrder', ({ payload }) =>
108
+ Effect.gen(function* () {
109
+ yield* Answer.early(HttpServerResponse.jsonUnsafe({ accepted: true }, { status: 202 }));
110
+ yield* callPartner(payload); // the caller already has its 202
111
+ return { delivered: true };
112
+ }),
113
+ )
114
+ ```
115
+
116
+ It fails without writing anything with `EarlyAnswerNotEnabled` (the policy is not `early`),
117
+ `EarlyAnswerUnsupportedMethod` (`HEAD`), `AnswerAlreadySent`, `AnswerStatusInvalid` (outside
118
+ 200–599), `AnswerTooLarge` (over 1 MiB), or `AnswerBodyNotAllowed` (a `204` or `304` with a body).
119
+ The deadline still applies to the work: after the answer it ends the Run `failed` with
120
+ `InvocationDeadlineExceeded`. In a test, `readEarlyAnswer(response)` from `@temper/workflow/testing`
121
+ reads the answer and then the trailer.
122
+
99
123
  ## Resources and variables
100
124
 
101
125
  Declare each resource, variable, and resource type that the workflow reads once. The class is both
@@ -0,0 +1,68 @@
1
+ import { Effect, Schema } from 'effect';
2
+ import { HttpServerRequest, HttpServerResponse } from 'effect/unstable/http';
3
+ import { type AnswerTrailer, type AnswerTrailerError } from './Contract/EarlyAnswer.js';
4
+ import { Invocation } from './Invocation.js';
5
+ declare const EarlyAnswerNotEnabled_base: Schema.Class<EarlyAnswerNotEnabled, Schema.TaggedStruct<"EarlyAnswerNotEnabled", {
6
+ readonly responsePolicy: Schema.String;
7
+ readonly message: Schema.String;
8
+ }>, import("effect/Cause").YieldableError>;
9
+ /** The route's stored response policy is not `early`, so the caller gets the complete response. */
10
+ export declare class EarlyAnswerNotEnabled extends EarlyAnswerNotEnabled_base {
11
+ }
12
+ declare const AnswerAlreadySent_base: Schema.Class<AnswerAlreadySent, Schema.TaggedStruct<"AnswerAlreadySent", {
13
+ readonly message: Schema.String;
14
+ }>, import("effect/Cause").YieldableError>;
15
+ /** This invocation already answered; the caller keeps the first answer. */
16
+ export declare class AnswerAlreadySent extends AnswerAlreadySent_base {
17
+ }
18
+ declare const AnswerTooLarge_base: Schema.Class<AnswerTooLarge, Schema.TaggedStruct<"AnswerTooLarge", {
19
+ readonly limitBytes: Schema.Number;
20
+ readonly message: Schema.String;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ /** The answer body is over the 1 MiB limit. */
23
+ export declare class AnswerTooLarge extends AnswerTooLarge_base {
24
+ }
25
+ declare const AnswerBodyNotAllowed_base: Schema.Class<AnswerBodyNotAllowed, Schema.TaggedStruct<"AnswerBodyNotAllowed", {
26
+ readonly status: Schema.Number;
27
+ readonly message: Schema.String;
28
+ }>, import("effect/Cause").YieldableError>;
29
+ /** A `204` or `304` answer carries a body, which HTTP forbids (EAR-17). */
30
+ export declare class AnswerBodyNotAllowed extends AnswerBodyNotAllowed_base {
31
+ }
32
+ declare const AnswerStatusInvalid_base: Schema.Class<AnswerStatusInvalid, Schema.TaggedStruct<"AnswerStatusInvalid", {
33
+ readonly status: Schema.Number;
34
+ readonly message: Schema.String;
35
+ }>, import("effect/Cause").YieldableError>;
36
+ /** The answer status is outside 200–599. */
37
+ export declare class AnswerStatusInvalid extends AnswerStatusInvalid_base {
38
+ }
39
+ declare const EarlyAnswerUnsupportedMethod_base: Schema.Class<EarlyAnswerUnsupportedMethod, Schema.TaggedStruct<"EarlyAnswerUnsupportedMethod", {
40
+ readonly method: Schema.String;
41
+ readonly message: Schema.String;
42
+ }>, import("effect/Cause").YieldableError>;
43
+ /** A `HEAD` request never gets a framed response; the complete response answers it (EAR-17). */
44
+ export declare class EarlyAnswerUnsupportedMethod extends EarlyAnswerUnsupportedMethod_base {
45
+ }
46
+ export type EarlyAnswerError = EarlyAnswerNotEnabled | AnswerAlreadySent | AnswerTooLarge | AnswerBodyNotAllowed | AnswerStatusInvalid | EarlyAnswerUnsupportedMethod;
47
+ /**
48
+ * Sends `response` to the caller now; the handler keeps running in the same Run, and its return value
49
+ * sets only the Run outcome (EAR-4). It returns once the answer bytes are on the response stream, and
50
+ * fails without writing anything when the route is not `early`, the request is `HEAD`, an answer was
51
+ * already sent, the status is outside 200–599, the body is over 1 MiB, or a 204 or 304 carries a body.
52
+ */
53
+ declare const early: (response: HttpServerResponse.HttpServerResponse | Response) => Effect.Effect<void, EarlyAnswerError, Invocation | HttpServerRequest.HttpServerRequest>;
54
+ export declare const Answer: {
55
+ readonly early: typeof early;
56
+ };
57
+ /** Records why the handler failed, so a trailer after an early answer names it. A no-op for other policies. */
58
+ export declare const recordAnswerFailure: (request: HttpServerRequest.HttpServerRequest, failure: AnswerTrailerError) => void;
59
+ /** `<L: u32 big-endian><L bytes of JSON>`, the end of a framed body. */
60
+ export declare const encodeTrailer: (trailer: AnswerTrailer) => Uint8Array;
61
+ /**
62
+ * Serves one `early` invocation. When the handler calls `Answer.early` first, the response is framed:
63
+ * transport status 200, the answer head and bytes at once, then the trailer when the handler ends.
64
+ * When the handler returns first, its complete response goes out unframed, as on every other policy.
65
+ */
66
+ export declare const serveEarly: (request: Request, run: () => Promise<Response>) => Promise<Response>;
67
+ export {};
68
+ //# sourceMappingURL=Answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Answer.d.ts","sourceRoot":"","sources":["../src/Answer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAMxB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;;;;;AAG7C,mGAAmG;AACnG,qBAAa,qBAAsB,SAAQ,0BAGzC;CAAG;;;;AAEL,2EAA2E;AAC3E,qBAAa,iBAAkB,SAAQ,sBAErC;CAAG;;;;;AAEL,+CAA+C;AAC/C,qBAAa,cAAe,SAAQ,mBAGlC;CAAG;;;;;AAEL,2EAA2E;AAC3E,qBAAa,oBAAqB,SAAQ,yBAGxC;CAAG;;;;;AAEL,4CAA4C;AAC5C,qBAAa,mBAAoB,SAAQ,wBAGvC;CAAG;;;;;AAEL,gGAAgG;AAChG,qBAAa,4BAA6B,SAAQ,iCAGjD;CAAG;AAEJ,MAAM,MAAM,gBAAgB,GACxB,qBAAqB,GACrB,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,mBAAmB,GACnB,4BAA4B,CAAC;AAmGjC;;;;;GAKG;AACH,QAAA,MAAM,KAAK,aACC,kBAAkB,CAAC,kBAAkB,GAAG,QAAQ,KACzD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,EAAE,UAAU,GAAG,iBAAiB,CAAC,iBAAiB,CAkDrF,CAAC;AAEL,eAAO,MAAM,MAAM;;CAAqB,CAAC;AAEzC,+GAA+G;AAC/G,eAAO,MAAM,mBAAmB,YACrB,iBAAiB,CAAC,iBAAiB,WACnC,kBAAkB,KAC1B,IAKF,CAAC;AAIF,wEAAwE;AACxE,eAAO,MAAM,aAAa,YAAa,aAAa,KAAG,UAStD,CAAC;AA+BF;;;;GAIG;AACH,eAAO,MAAM,UAAU,YAAmB,OAAO,OAAO,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAG,OAAO,CAAC,QAAQ,CAkCjG,CAAC"}
package/dist/Answer.js ADDED
@@ -0,0 +1,239 @@
1
+ import { Effect, Schema } from 'effect';
2
+ import { HttpServerRequest, HttpServerResponse } from 'effect/unstable/http';
3
+ import { ANSWER_LENGTH_HEADER, ANSWER_STATUS_HEADER, EARLY_ANSWER_PROTOCOL_VERSION, MAX_ANSWER_BYTES, MAX_TRAILER_BYTES, RUN_OUTCOME_HEADER, TRAILER_LENGTH_BYTES, } from './Contract/EarlyAnswer.js';
4
+ import { Invocation } from './Invocation.js';
5
+ import { CurrentLogContext, TRACE_HEADER } from './LogContext.js';
6
+ /** The route's stored response policy is not `early`, so the caller gets the complete response. */
7
+ export class EarlyAnswerNotEnabled extends Schema.TaggedError()('EarlyAnswerNotEnabled', {
8
+ responsePolicy: Schema.String,
9
+ message: Schema.String,
10
+ }) {
11
+ }
12
+ /** This invocation already answered; the caller keeps the first answer. */
13
+ export class AnswerAlreadySent extends Schema.TaggedError()('AnswerAlreadySent', {
14
+ message: Schema.String,
15
+ }) {
16
+ }
17
+ /** The answer body is over the 1 MiB limit. */
18
+ export class AnswerTooLarge extends Schema.TaggedError()('AnswerTooLarge', {
19
+ limitBytes: Schema.Number,
20
+ message: Schema.String,
21
+ }) {
22
+ }
23
+ /** A `204` or `304` answer carries a body, which HTTP forbids (EAR-17). */
24
+ export class AnswerBodyNotAllowed extends Schema.TaggedError()('AnswerBodyNotAllowed', {
25
+ status: Schema.Number,
26
+ message: Schema.String,
27
+ }) {
28
+ }
29
+ /** The answer status is outside 200–599. */
30
+ export class AnswerStatusInvalid extends Schema.TaggedError()('AnswerStatusInvalid', {
31
+ status: Schema.Number,
32
+ message: Schema.String,
33
+ }) {
34
+ }
35
+ /** A `HEAD` request never gets a framed response; the complete response answers it (EAR-17). */
36
+ export class EarlyAnswerUnsupportedMethod extends Schema.TaggedError()('EarlyAnswerUnsupportedMethod', { method: Schema.String, message: Schema.String }) {
37
+ }
38
+ /** Keyed by the web `Request` the SDK serves, which `HttpServerRequest.source` carries into the handler. */
39
+ const slots = new WeakMap();
40
+ const slotOf = (request) => request.source instanceof Request ? slots.get(request.source) : undefined;
41
+ /** Answer headers the platform owns: hop-by-hop framing, and the frame's own and outcome headers. */
42
+ const ownedHeader = (name) => name === 'content-length' ||
43
+ name === 'transfer-encoding' ||
44
+ name === 'connection' ||
45
+ name === 'keep-alive' ||
46
+ name === 'trailer' ||
47
+ name === 'upgrade' ||
48
+ name === RUN_OUTCOME_HEADER ||
49
+ name.startsWith('x-temper-answer-');
50
+ /** The body, read at most one byte past the limit; `undefined` when it is over the limit. */
51
+ const readBounded = async (response) => {
52
+ if (response.body === null)
53
+ return new Uint8Array();
54
+ const reader = response.body.getReader();
55
+ const chunks = [];
56
+ let total = 0;
57
+ while (true) {
58
+ const next = await reader.read();
59
+ if (next.done)
60
+ break;
61
+ total += next.value.byteLength;
62
+ if (total > MAX_ANSWER_BYTES) {
63
+ await reader.cancel().catch(() => undefined);
64
+ return undefined;
65
+ }
66
+ chunks.push(next.value);
67
+ }
68
+ const bytes = new Uint8Array(total);
69
+ let offset = 0;
70
+ for (const chunk of chunks) {
71
+ bytes.set(chunk, offset);
72
+ offset += chunk.byteLength;
73
+ }
74
+ return bytes;
75
+ };
76
+ /** The answer as bytes. The status is set to 200 only to build a web body, which a 204 or 304 forbids. */
77
+ const encodeAnswer = (response, status) => Effect.gen(function* () {
78
+ const web = response instanceof Response ? response : HttpServerResponse.toWeb(HttpServerResponse.setStatus(response, 200));
79
+ const body = yield* Effect.promise(() => readBounded(web));
80
+ if (body === undefined) {
81
+ return yield* Effect.fail(new AnswerTooLarge({
82
+ limitBytes: MAX_ANSWER_BYTES,
83
+ message: `The answer body is over ${MAX_ANSWER_BYTES} bytes.`,
84
+ }));
85
+ }
86
+ if ((status === 204 || status === 304) && body.byteLength > 0) {
87
+ return yield* Effect.fail(new AnswerBodyNotAllowed({ status, message: `A ${status} answer must have an empty body.` }));
88
+ }
89
+ const headers = new Headers();
90
+ for (const [name, value] of web.headers) {
91
+ if (!ownedHeader(name.toLowerCase()))
92
+ headers.append(name, value);
93
+ }
94
+ return { status, headers, body };
95
+ });
96
+ /** The trace and message ids the SDK echoes on every response, as `EventRequestMiddleware` does. */
97
+ const echoIds = (headers) => Effect.gen(function* () {
98
+ const context = yield* CurrentLogContext;
99
+ if (context === undefined || context.messageId === '')
100
+ return;
101
+ if (!headers.has(TRACE_HEADER))
102
+ headers.set(TRACE_HEADER, context.traceId);
103
+ if (context.messageId !== undefined && !headers.has('x-message-id'))
104
+ headers.set('x-message-id', context.messageId);
105
+ });
106
+ /**
107
+ * Sends `response` to the caller now; the handler keeps running in the same Run, and its return value
108
+ * sets only the Run outcome (EAR-4). It returns once the answer bytes are on the response stream, and
109
+ * fails without writing anything when the route is not `early`, the request is `HEAD`, an answer was
110
+ * already sent, the status is outside 200–599, the body is over 1 MiB, or a 204 or 304 carries a body.
111
+ */
112
+ const early = (response) => Effect.gen(function* () {
113
+ const invocation = yield* Invocation;
114
+ const request = yield* HttpServerRequest.HttpServerRequest;
115
+ const policy = invocation.responsePolicy ?? '';
116
+ const notEnabled = new EarlyAnswerNotEnabled({
117
+ responsePolicy: policy,
118
+ message: `Answer.early needs the route's response policy to be 'early'; it is '${policy}'.`,
119
+ });
120
+ if (policy !== 'early')
121
+ return yield* Effect.fail(notEnabled);
122
+ if (request.method === 'HEAD') {
123
+ return yield* Effect.fail(new EarlyAnswerUnsupportedMethod({
124
+ method: request.method,
125
+ message: 'A HEAD request gets the complete response, never an early answer.',
126
+ }));
127
+ }
128
+ // Only the SDK's own `fetch` opens a slot; a request served any other way cannot answer early.
129
+ const slot = slotOf(request);
130
+ if (slot === undefined)
131
+ return yield* Effect.fail(notEnabled);
132
+ if (slot.state !== 'open') {
133
+ return yield* Effect.fail(new AnswerAlreadySent({ message: 'This invocation already answered.' }));
134
+ }
135
+ const status = response.status;
136
+ if (!Number.isInteger(status) || status < 200 || status > 599) {
137
+ return yield* Effect.fail(new AnswerStatusInvalid({ status, message: `The answer status ${status} is outside 200-599.` }));
138
+ }
139
+ slot.state = 'pending';
140
+ const answer = yield* encodeAnswer(response, status).pipe(Effect.tap((encoded) => echoIds(encoded.headers)), Effect.onExit(() => Effect.sync(() => {
141
+ if (slot.state === 'pending')
142
+ slot.state = 'open';
143
+ })), Effect.flatMap((encoded) => Effect.suspend(() => {
144
+ // A complete response that won the race already answered the caller.
145
+ if (slot.state !== 'open')
146
+ return Effect.fail(new AnswerAlreadySent({ message: 'This invocation already answered.' }));
147
+ slot.state = 'sent';
148
+ return Effect.succeed(encoded);
149
+ })));
150
+ slot.answered.resolve(answer);
151
+ yield* Effect.promise(() => slot.written.promise);
152
+ });
153
+ export const Answer = { early };
154
+ /** Records why the handler failed, so a trailer after an early answer names it. A no-op for other policies. */
155
+ export const recordAnswerFailure = (request, failure) => {
156
+ const slot = slotOf(request);
157
+ if (slot !== undefined && slot.failure === undefined) {
158
+ slot.failure = { tag: failure.tag.slice(0, 256), message: failure.message.slice(0, 4_096) };
159
+ }
160
+ };
161
+ const encoder = new TextEncoder();
162
+ /** `<L: u32 big-endian><L bytes of JSON>`, the end of a framed body. */
163
+ export const encodeTrailer = (trailer) => {
164
+ let json = encoder.encode(JSON.stringify(trailer));
165
+ if (json.byteLength > MAX_TRAILER_BYTES && trailer.error !== null) {
166
+ json = encoder.encode(JSON.stringify({ ...trailer, error: { tag: trailer.error.tag, message: '' } }));
167
+ }
168
+ const frame = new Uint8Array(TRAILER_LENGTH_BYTES + json.byteLength);
169
+ new DataView(frame.buffer).setUint32(0, json.byteLength);
170
+ frame.set(json, TRAILER_LENGTH_BYTES);
171
+ return frame;
172
+ };
173
+ /** The trailer for the handler's final value: a declared `x-temper-run-outcome`, else its status class. */
174
+ const trailerOf = async (completed, slot) => {
175
+ const settled = await completed;
176
+ if (settled.status === 'rejected') {
177
+ return {
178
+ v: EARLY_ANSWER_PROTOCOL_VERSION,
179
+ outcome: 'failed',
180
+ status: 500,
181
+ error: slot.failure ?? { tag: 'WorkflowRequestFailed', message: 'Workflow request failed.' },
182
+ };
183
+ }
184
+ const final = settled.value;
185
+ // The final value never reaches the caller; releasing its body ends the request scope.
186
+ await final.body?.cancel().catch(() => undefined);
187
+ const declared = final.headers.get(RUN_OUTCOME_HEADER);
188
+ const outcome = slot.failure !== undefined
189
+ ? 'failed'
190
+ : declared === 'succeeded' || declared === 'failed'
191
+ ? declared
192
+ : final.status < 400
193
+ ? 'succeeded'
194
+ : 'failed';
195
+ return { v: EARLY_ANSWER_PROTOCOL_VERSION, outcome, status: final.status, error: slot.failure ?? null };
196
+ };
197
+ /**
198
+ * Serves one `early` invocation. When the handler calls `Answer.early` first, the response is framed:
199
+ * transport status 200, the answer head and bytes at once, then the trailer when the handler ends.
200
+ * When the handler returns first, its complete response goes out unframed, as on every other policy.
201
+ */
202
+ export const serveEarly = async (request, run) => {
203
+ const slot = {
204
+ state: 'open',
205
+ failure: undefined,
206
+ answered: Promise.withResolvers(),
207
+ written: Promise.withResolvers(),
208
+ };
209
+ slots.set(request, slot);
210
+ const completed = Promise.allSettled([run()]).then(([settled]) => settled);
211
+ const first = await Promise.race([
212
+ completed.then((settled) => ({ _tag: 'complete', settled })),
213
+ slot.answered.promise.then((answer) => ({ _tag: 'answer', answer })),
214
+ ]);
215
+ if (first._tag === 'complete') {
216
+ slot.state = 'closed';
217
+ slot.written.resolve(undefined);
218
+ if (first.settled.status === 'rejected')
219
+ throw first.settled.reason;
220
+ return first.settled.value;
221
+ }
222
+ const { answer } = first;
223
+ const headers = new Headers(answer.headers);
224
+ headers.set(ANSWER_STATUS_HEADER, String(answer.status));
225
+ headers.set(ANSWER_LENGTH_HEADER, String(answer.body.byteLength));
226
+ const body = new ReadableStream({
227
+ start(controller) {
228
+ if (answer.body.byteLength > 0)
229
+ controller.enqueue(answer.body);
230
+ slot.written.resolve(undefined);
231
+ },
232
+ async pull(controller) {
233
+ controller.enqueue(encodeTrailer(await trailerOf(completed, slot)));
234
+ controller.close();
235
+ },
236
+ });
237
+ return new Response(body, { status: 200, headers });
238
+ };
239
+ //# sourceMappingURL=Answer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Answer.js","sourceRoot":"","sources":["../src/Answer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Early-answer wire protocol, version 1 (docs/specs/early-answer-runs.md#wire-protocol). One HTTP
3
+ * response carries the partner answer and then a trailer that sets the Run outcome:
4
+ * `<N answer bytes><L: u32 big-endian><L bytes of UTF-8 JSON trailer>`.
5
+ */
6
+ /** The response policy the executor sends the runtime on every invocation (EAR-19). */
7
+ export declare const RESPONSE_POLICY_HEADER = "x-temper-response-policy";
8
+ /** The partner status of a framed response; the transport status is always 200 (EAR-17). */
9
+ export declare const ANSWER_STATUS_HEADER = "x-temper-answer-status";
10
+ /** Decimal byte count of the answer that starts the framed body. Its presence marks a framed response. */
11
+ export declare const ANSWER_LENGTH_HEADER = "x-temper-answer-length";
12
+ /** A handler's declared Run outcome (RUN-8); on a framed response the trailer carries it instead. */
13
+ export declare const RUN_OUTCOME_HEADER = "x-temper-run-outcome";
14
+ export declare const EARLY_ANSWER_PROTOCOL_VERSION = 1;
15
+ /** Largest answer body: 1 MiB. */
16
+ export declare const MAX_ANSWER_BYTES = 1048576;
17
+ /** Largest trailer JSON: 64 KiB. */
18
+ export declare const MAX_TRAILER_BYTES = 65536;
19
+ /** Bytes of the big-endian trailer length prefix. */
20
+ export declare const TRAILER_LENGTH_BYTES = 4;
21
+ /** The policy the platform admitted this invocation under; `''` comes from a host that predates EAR-19. */
22
+ export type InvocationResponsePolicy = 'wait' | 'ack' | 'early' | '';
23
+ export interface AnswerTrailerError {
24
+ readonly tag: string;
25
+ readonly message: string;
26
+ }
27
+ /** The JSON that ends a framed body. `outcome` sets the Run outcome; the answer status does not (EAR-6). */
28
+ export interface AnswerTrailer {
29
+ readonly v: typeof EARLY_ANSWER_PROTOCOL_VERSION;
30
+ readonly outcome: 'succeeded' | 'failed';
31
+ /** The final handler status, recorded as `http_status`. */
32
+ readonly status: number;
33
+ readonly error: AnswerTrailerError | null;
34
+ }
35
+ //# sourceMappingURL=EarlyAnswer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EarlyAnswer.d.ts","sourceRoot":"","sources":["../../src/Contract/EarlyAnswer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAEzD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,UAAY,CAAC;AAC1C,oCAAoC;AACpC,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,2GAA2G;AAC3G,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,EAAE,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,4GAA4G;AAC5G,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,CAAC,EAAE,OAAO,6BAA6B,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,QAAQ,CAAC;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC3C"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Early-answer wire protocol, version 1 (docs/specs/early-answer-runs.md#wire-protocol). One HTTP
3
+ * response carries the partner answer and then a trailer that sets the Run outcome:
4
+ * `<N answer bytes><L: u32 big-endian><L bytes of UTF-8 JSON trailer>`.
5
+ */
6
+ /** The response policy the executor sends the runtime on every invocation (EAR-19). */
7
+ export const RESPONSE_POLICY_HEADER = 'x-temper-response-policy';
8
+ /** The partner status of a framed response; the transport status is always 200 (EAR-17). */
9
+ export const ANSWER_STATUS_HEADER = 'x-temper-answer-status';
10
+ /** Decimal byte count of the answer that starts the framed body. Its presence marks a framed response. */
11
+ export const ANSWER_LENGTH_HEADER = 'x-temper-answer-length';
12
+ /** A handler's declared Run outcome (RUN-8); on a framed response the trailer carries it instead. */
13
+ export const RUN_OUTCOME_HEADER = 'x-temper-run-outcome';
14
+ export const EARLY_ANSWER_PROTOCOL_VERSION = 1;
15
+ /** Largest answer body: 1 MiB. */
16
+ export const MAX_ANSWER_BYTES = 1_048_576;
17
+ /** Largest trailer JSON: 64 KiB. */
18
+ export const MAX_TRAILER_BYTES = 65_536;
19
+ /** Bytes of the big-endian trailer length prefix. */
20
+ export const TRAILER_LENGTH_BYTES = 4;
21
+ //# sourceMappingURL=EarlyAnswer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EarlyAnswer.js","sourceRoot":"","sources":["../../src/Contract/EarlyAnswer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uFAAuF;AACvF,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AACjE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAC7D,0GAA0G;AAC1G,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAC7D,qGAAqG;AACrG,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAC/C,kCAAkC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAC1C,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { InvocationResponsePolicy } from './EarlyAnswer.js';
1
2
  /** Who admitted this invocation. Mirrors the platform `RunTriggerKind`; `http` is the guest default. */
2
3
  export type InvocationTriggerKind = 'http' | 'schedule' | 'manual' | 'agent' | 'as2' | 'sftp' | 'kafka' | 'child';
3
4
  /**
@@ -17,5 +18,10 @@ export interface InvocationContext {
17
18
  readonly deadline: number;
18
19
  /** Run-scoped platform token for AS2, EDI, and Resource calls. Empty outside a platform host. */
19
20
  readonly token: string;
21
+ /**
22
+ * The route's stored response policy, from `x-temper-response-policy`. Absent or `''` from a host
23
+ * that predates early answers; `Answer.early` works only under `early`.
24
+ */
25
+ readonly responsePolicy?: InvocationResponsePolicy | undefined;
20
26
  }
21
27
  //# sourceMappingURL=Invocation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Invocation.d.ts","sourceRoot":"","sources":["../../src/Contract/Invocation.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAElH;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC5C,gHAAgH;IAChH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"Invocation.d.ts","sourceRoot":"","sources":["../../src/Contract/Invocation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,wGAAwG;AACxG,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAElH;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC5C,gHAAgH;IAChH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CAChE"}