@ontemper/sdk 0.4.10-rc.1 → 0.4.12-pr-5977.1
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.
- package/README.md +24 -0
- package/dist/Answer.d.ts +69 -0
- package/dist/Answer.d.ts.map +1 -0
- package/dist/Answer.js +290 -0
- package/dist/Answer.js.map +1 -0
- package/dist/Contract/EarlyAnswer.d.ts +40 -0
- package/dist/Contract/EarlyAnswer.d.ts.map +1 -0
- package/dist/Contract/EarlyAnswer.js +26 -0
- package/dist/Contract/EarlyAnswer.js.map +1 -0
- package/dist/Contract/Invocation.d.ts +6 -0
- package/dist/Contract/Invocation.d.ts.map +1 -1
- package/dist/Contract/Manifest.d.ts +46 -167
- package/dist/Contract/Manifest.d.ts.map +1 -1
- package/dist/Contract/Manifest.js +37 -65
- package/dist/Contract/Manifest.js.map +1 -1
- package/dist/Contract/index.d.ts +2 -1
- package/dist/Contract/index.d.ts.map +1 -1
- package/dist/Contract/index.js +2 -1
- package/dist/Contract/index.js.map +1 -1
- package/dist/Manifest.d.ts +1 -1
- package/dist/Manifest.d.ts.map +1 -1
- package/dist/Manifest.js +6 -4
- package/dist/Manifest.js.map +1 -1
- package/dist/Middleware.d.ts.map +1 -1
- package/dist/Middleware.js +20 -3
- package/dist/Middleware.js.map +1 -1
- package/dist/Trigger.d.ts +2 -55
- package/dist/Trigger.d.ts.map +1 -1
- package/dist/Trigger.js +0 -29
- package/dist/Trigger.js.map +1 -1
- package/dist/Workflow.d.ts.map +1 -1
- package/dist/Workflow.js +4 -1
- package/dist/Workflow.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +18 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +96 -1
- package/dist/testing.js.map +1 -1
- 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
|
package/dist/Answer.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
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`, `205`, or `304` answer carries a body, which the caller never receives (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
|
+
/** The body, read at most one byte past the limit; `undefined` when it is over the limit. */
|
|
48
|
+
export declare const readBounded: (response: Response, signal: AbortSignal) => Promise<Uint8Array | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Sends `response` to the caller now; the handler keeps running, and its return value sets only the Run
|
|
51
|
+
* outcome (EAR-4). Returns once the answer is on the response stream; fails, writing nothing, on the
|
|
52
|
+
* conditions each `EarlyAnswerError` names.
|
|
53
|
+
*/
|
|
54
|
+
declare const early: (response: HttpServerResponse.HttpServerResponse | Response) => Effect.Effect<void, EarlyAnswerError, Invocation | HttpServerRequest.HttpServerRequest>;
|
|
55
|
+
export declare const Answer: {
|
|
56
|
+
readonly early: typeof early;
|
|
57
|
+
};
|
|
58
|
+
/** Records why the handler failed, so a trailer after an early answer names it. A no-op for other policies. */
|
|
59
|
+
export declare const recordAnswerFailure: (request: HttpServerRequest.HttpServerRequest, failure: AnswerTrailerError) => void;
|
|
60
|
+
/** `<L: u32 big-endian><L bytes of JSON>`, the end of a framed body. */
|
|
61
|
+
export declare const encodeTrailer: (trailer: AnswerTrailer) => Uint8Array;
|
|
62
|
+
/**
|
|
63
|
+
* Serves one `early` invocation. When the handler calls `Answer.early` first, the response is framed:
|
|
64
|
+
* transport status 200, the answer head and bytes at once, then the trailer when the handler ends.
|
|
65
|
+
* When the handler returns first, its complete response goes out unframed, as on every other policy.
|
|
66
|
+
*/
|
|
67
|
+
export declare const serveEarly: (request: Request, run: (request: Request) => Promise<Response>) => Promise<Response>;
|
|
68
|
+
export {};
|
|
69
|
+
//# 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,EAIL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAKxB,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,gGAAgG;AAChG,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;AAyCjC,6FAA6F;AAC7F,eAAO,MAAM,WAAW,aAAoB,QAAQ,UAAU,WAAW,KAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAoCzG,CAAC;AAoDF;;;;GAIG;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;AAKF,wEAAwE;AACxE,eAAO,MAAM,aAAa,YAAa,aAAa,KAAG,UAOtD,CAAC;AAwCF;;;;GAIG;AACH,eAAO,MAAM,UAAU,YAAmB,OAAO,OAAO,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAG,OAAO,CAAC,QAAQ,CA6CjH,CAAC"}
|
package/dist/Answer.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { HttpServerRequest, HttpServerResponse } from 'effect/unstable/http';
|
|
3
|
+
import { ANSWER_LENGTH_HEADER, ANSWER_PREAMBLE_HEADER, ANSWER_STATUS_HEADER, EARLY_ANSWER_PROTOCOL_VERSION, MAX_ANSWER_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`, `205`, or `304` answer carries a body, which the caller never receives (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
|
+
/** Starts cancelling a body without waiting: a tee'd peer nobody reads can hold cancellation forever. */
|
|
51
|
+
const release = (cancel) => {
|
|
52
|
+
cancel().catch(() => undefined);
|
|
53
|
+
};
|
|
54
|
+
/** The body, read at most one byte past the limit; `undefined` when it is over the limit. */
|
|
55
|
+
export const readBounded = async (response, signal) => {
|
|
56
|
+
if (response.body === null)
|
|
57
|
+
return new Uint8Array();
|
|
58
|
+
const reader = response.body.getReader();
|
|
59
|
+
// An interrupted answer (the deadline) cancels the read, so its stream source is not kept pending.
|
|
60
|
+
const onAbort = () => release(() => reader.cancel());
|
|
61
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
62
|
+
const chunks = [];
|
|
63
|
+
let total = 0;
|
|
64
|
+
try {
|
|
65
|
+
while (true) {
|
|
66
|
+
const next = await reader.read();
|
|
67
|
+
if (next.done)
|
|
68
|
+
break;
|
|
69
|
+
// An empty chunk adds no bytes; keeping it would let an endless stream of them grow memory unbounded.
|
|
70
|
+
if (next.value.byteLength === 0) {
|
|
71
|
+
// A source that enqueues empty chunks at once settles reads in microtasks only; a macrotask runs the deadline.
|
|
72
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
73
|
+
if (signal.aborted)
|
|
74
|
+
break;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
total += next.value.byteLength;
|
|
78
|
+
if (total > MAX_ANSWER_BYTES) {
|
|
79
|
+
release(() => reader.cancel());
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
chunks.push(next.value);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
signal.removeEventListener('abort', onAbort);
|
|
87
|
+
}
|
|
88
|
+
const bytes = new Uint8Array(total);
|
|
89
|
+
let offset = 0;
|
|
90
|
+
for (const chunk of chunks) {
|
|
91
|
+
bytes.set(chunk, offset);
|
|
92
|
+
offset += chunk.byteLength;
|
|
93
|
+
}
|
|
94
|
+
return bytes;
|
|
95
|
+
};
|
|
96
|
+
/** The answer as bytes. The status is set to 200 only to build a web body, which a 204 or 304 forbids. */
|
|
97
|
+
const encodeAnswer = (response, status) => Effect.gen(function* () {
|
|
98
|
+
const web = response instanceof Response ? response : HttpServerResponse.toWeb(HttpServerResponse.setStatus(response, 200));
|
|
99
|
+
const body = yield* Effect.promise((signal) => readBounded(web, signal));
|
|
100
|
+
if (body === undefined) {
|
|
101
|
+
return yield* Effect.fail(new AnswerTooLarge({
|
|
102
|
+
limitBytes: MAX_ANSWER_BYTES,
|
|
103
|
+
message: `The answer body is over ${MAX_ANSWER_BYTES} bytes.`,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
if ((status === 204 || status === 205 || status === 304) && body.byteLength > 0) {
|
|
107
|
+
return yield* Effect.fail(new AnswerBodyNotAllowed({ status, message: `A ${status} answer must have an empty body.` }));
|
|
108
|
+
}
|
|
109
|
+
// `Connection` names more hop-by-hop fields; they go with it, since the gateway sees no marker.
|
|
110
|
+
const nominated = new Set((web.headers.get('connection') ?? '')
|
|
111
|
+
.split(',')
|
|
112
|
+
.map((token) => token.trim().toLowerCase())
|
|
113
|
+
.filter((token) => token !== ''));
|
|
114
|
+
// A fetched body is already decoded, but `fetch` keeps `Content-Encoding`; the caller would decode it twice.
|
|
115
|
+
// `HttpServerResponse.raw(fetched)` converts back to the fetched `Response`, so the check reads `web`.
|
|
116
|
+
const decoded = web.type !== 'default';
|
|
117
|
+
const headers = new Headers();
|
|
118
|
+
for (const [name, value] of web.headers) {
|
|
119
|
+
const lower = name.toLowerCase();
|
|
120
|
+
if (decoded && lower === 'content-encoding')
|
|
121
|
+
continue;
|
|
122
|
+
if (!ownedHeader(lower) && !nominated.has(lower))
|
|
123
|
+
headers.append(name, value);
|
|
124
|
+
}
|
|
125
|
+
return { status, headers, body };
|
|
126
|
+
});
|
|
127
|
+
/** The trace and message ids the SDK echoes on every response, as `EventRequestMiddleware` does. */
|
|
128
|
+
const echoIds = (headers) => Effect.gen(function* () {
|
|
129
|
+
const context = yield* CurrentLogContext;
|
|
130
|
+
if (context === undefined || context.messageId === '')
|
|
131
|
+
return;
|
|
132
|
+
if (!headers.has(TRACE_HEADER))
|
|
133
|
+
headers.set(TRACE_HEADER, context.traceId);
|
|
134
|
+
if (context.messageId !== undefined && !headers.has('x-message-id'))
|
|
135
|
+
headers.set('x-message-id', context.messageId);
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Sends `response` to the caller now; the handler keeps running, and its return value sets only the Run
|
|
139
|
+
* outcome (EAR-4). Returns once the answer is on the response stream; fails, writing nothing, on the
|
|
140
|
+
* conditions each `EarlyAnswerError` names.
|
|
141
|
+
*/
|
|
142
|
+
const early = (response) => Effect.gen(function* () {
|
|
143
|
+
const invocation = yield* Invocation;
|
|
144
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
145
|
+
const policy = invocation.responsePolicy ?? '';
|
|
146
|
+
const notEnabled = new EarlyAnswerNotEnabled({
|
|
147
|
+
responsePolicy: policy,
|
|
148
|
+
message: `Answer.early needs the route's response policy to be 'early'; it is '${policy}'.`,
|
|
149
|
+
});
|
|
150
|
+
if (policy !== 'early')
|
|
151
|
+
return yield* Effect.fail(notEnabled);
|
|
152
|
+
if (request.method === 'HEAD') {
|
|
153
|
+
return yield* Effect.fail(new EarlyAnswerUnsupportedMethod({
|
|
154
|
+
method: request.method,
|
|
155
|
+
message: 'A HEAD request gets the complete response, never an early answer.',
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
// Only the SDK's own `fetch` opens a slot; a request served any other way cannot answer early.
|
|
159
|
+
const slot = slotOf(request);
|
|
160
|
+
if (slot === undefined)
|
|
161
|
+
return yield* Effect.fail(notEnabled);
|
|
162
|
+
if (slot.state !== 'open') {
|
|
163
|
+
return yield* Effect.fail(new AnswerAlreadySent({ message: 'This invocation already answered.' }));
|
|
164
|
+
}
|
|
165
|
+
const status = response.status;
|
|
166
|
+
if (!Number.isInteger(status) || status < 200 || status > 599) {
|
|
167
|
+
return yield* Effect.fail(new AnswerStatusInvalid({ status, message: `The answer status ${status} is outside 200-599.` }));
|
|
168
|
+
}
|
|
169
|
+
slot.state = 'pending';
|
|
170
|
+
const answer = yield* encodeAnswer(response, status).pipe(Effect.tap((encoded) => echoIds(encoded.headers)), Effect.onExit(() => Effect.sync(() => {
|
|
171
|
+
if (slot.state === 'pending')
|
|
172
|
+
slot.state = 'open';
|
|
173
|
+
})), Effect.flatMap((encoded) => Effect.suspend(() => {
|
|
174
|
+
// A complete response that won the race already answered the caller.
|
|
175
|
+
if (slot.state !== 'open')
|
|
176
|
+
return Effect.fail(new AnswerAlreadySent({ message: 'This invocation already answered.' }));
|
|
177
|
+
slot.state = 'sent';
|
|
178
|
+
return Effect.succeed(encoded);
|
|
179
|
+
})));
|
|
180
|
+
slot.answered.resolve(answer);
|
|
181
|
+
yield* Effect.promise(() => slot.written.promise);
|
|
182
|
+
});
|
|
183
|
+
export const Answer = { early };
|
|
184
|
+
/** Records why the handler failed, so a trailer after an early answer names it. A no-op for other policies. */
|
|
185
|
+
export const recordAnswerFailure = (request, failure) => {
|
|
186
|
+
const slot = slotOf(request);
|
|
187
|
+
if (slot !== undefined && slot.failure === undefined) {
|
|
188
|
+
slot.failure = { tag: failure.tag.slice(0, 256), message: failure.message.slice(0, 4_096) };
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const encoder = new TextEncoder();
|
|
192
|
+
const EMPTY_ANSWER_PREAMBLE = new Uint8Array([0]);
|
|
193
|
+
/** `<L: u32 big-endian><L bytes of JSON>`, the end of a framed body. */
|
|
194
|
+
export const encodeTrailer = (trailer) => {
|
|
195
|
+
// `recordAnswerFailure` caps the error fields, so the JSON stays far under the 64 KiB trailer limit.
|
|
196
|
+
const json = encoder.encode(JSON.stringify(trailer));
|
|
197
|
+
const frame = new Uint8Array(TRAILER_LENGTH_BYTES + json.byteLength);
|
|
198
|
+
new DataView(frame.buffer).setUint32(0, json.byteLength);
|
|
199
|
+
frame.set(json, TRAILER_LENGTH_BYTES);
|
|
200
|
+
return frame;
|
|
201
|
+
};
|
|
202
|
+
/** The trailer for the handler's final value: a declared `x-temper-run-outcome`, else its status class. */
|
|
203
|
+
const trailerOf = async (completed, slot) => {
|
|
204
|
+
const settled = await completed;
|
|
205
|
+
if (settled.status === 'rejected') {
|
|
206
|
+
return {
|
|
207
|
+
v: EARLY_ANSWER_PROTOCOL_VERSION,
|
|
208
|
+
outcome: 'failed',
|
|
209
|
+
status: 500,
|
|
210
|
+
error: slot.failure ?? { tag: 'WorkflowRequestFailed', message: 'Workflow request failed.' },
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const final = settled.value;
|
|
214
|
+
// The final value never reaches the caller; releasing its body ends the request scope.
|
|
215
|
+
if (final.body !== null)
|
|
216
|
+
release(() => final.body?.cancel() ?? Promise.resolve());
|
|
217
|
+
const declared = final.headers.get(RUN_OUTCOME_HEADER);
|
|
218
|
+
const outcome = slot.failure !== undefined
|
|
219
|
+
? 'failed'
|
|
220
|
+
: declared === 'succeeded' || declared === 'failed'
|
|
221
|
+
? declared
|
|
222
|
+
: final.status < 400
|
|
223
|
+
? 'succeeded'
|
|
224
|
+
: 'failed';
|
|
225
|
+
return { v: EARLY_ANSWER_PROTOCOL_VERSION, outcome, status: final.status, error: slot.failure ?? null };
|
|
226
|
+
};
|
|
227
|
+
/** A complete response must not look framed: the gateway reads any `x-temper-answer-*` header as a frame. */
|
|
228
|
+
const withoutFrameHeaders = (response) => {
|
|
229
|
+
const names = [...response.headers.keys()].filter((name) => name.toLowerCase().startsWith('x-temper-answer-'));
|
|
230
|
+
if (names.length === 0)
|
|
231
|
+
return response;
|
|
232
|
+
const headers = new Headers(response.headers);
|
|
233
|
+
for (const name of names)
|
|
234
|
+
headers.delete(name);
|
|
235
|
+
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Serves one `early` invocation. When the handler calls `Answer.early` first, the response is framed:
|
|
239
|
+
* transport status 200, the answer head and bytes at once, then the trailer when the handler ends.
|
|
240
|
+
* When the handler returns first, its complete response goes out unframed, as on every other policy.
|
|
241
|
+
*/
|
|
242
|
+
export const serveEarly = async (request, run) => {
|
|
243
|
+
// A per-call Request keys the slot, so overlapping calls that reuse one Request never share an answer.
|
|
244
|
+
// It takes over the body stream: Bun copies a Request's streamed body with tee, which buffers it twice.
|
|
245
|
+
const init = {
|
|
246
|
+
method: request.method,
|
|
247
|
+
headers: request.headers,
|
|
248
|
+
body: request.body,
|
|
249
|
+
signal: request.signal,
|
|
250
|
+
duplex: 'half',
|
|
251
|
+
};
|
|
252
|
+
const own = new Request(request.url, init);
|
|
253
|
+
const slot = {
|
|
254
|
+
state: 'open',
|
|
255
|
+
failure: undefined,
|
|
256
|
+
answered: Promise.withResolvers(),
|
|
257
|
+
written: Promise.withResolvers(),
|
|
258
|
+
};
|
|
259
|
+
slots.set(own, slot);
|
|
260
|
+
const completed = Promise.allSettled([run(own)]).then(([settled]) => settled);
|
|
261
|
+
const first = await Promise.race([
|
|
262
|
+
completed.then((settled) => ({ _tag: 'complete', settled })),
|
|
263
|
+
slot.answered.promise.then((answer) => ({ _tag: 'answer', answer })),
|
|
264
|
+
]);
|
|
265
|
+
if (first._tag === 'complete') {
|
|
266
|
+
slot.state = 'closed';
|
|
267
|
+
slot.written.resolve(undefined);
|
|
268
|
+
if (first.settled.status === 'rejected')
|
|
269
|
+
throw first.settled.reason;
|
|
270
|
+
return withoutFrameHeaders(first.settled.value);
|
|
271
|
+
}
|
|
272
|
+
const { answer } = first;
|
|
273
|
+
const headers = new Headers(answer.headers);
|
|
274
|
+
headers.set(ANSWER_STATUS_HEADER, String(answer.status));
|
|
275
|
+
headers.set(ANSWER_LENGTH_HEADER, String(answer.body.byteLength));
|
|
276
|
+
if (answer.body.byteLength === 0)
|
|
277
|
+
headers.set(ANSWER_PREAMBLE_HEADER, '1');
|
|
278
|
+
const body = new ReadableStream({
|
|
279
|
+
start(controller) {
|
|
280
|
+
controller.enqueue(answer.body.byteLength > 0 ? answer.body : EMPTY_ANSWER_PREAMBLE);
|
|
281
|
+
slot.written.resolve(undefined);
|
|
282
|
+
},
|
|
283
|
+
async pull(controller) {
|
|
284
|
+
controller.enqueue(encodeTrailer(await trailerOf(completed, slot)));
|
|
285
|
+
controller.close();
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
return new Response(body, { status: 200, headers });
|
|
289
|
+
};
|
|
290
|
+
//# 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,40 @@
|
|
|
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
|
+
/**
|
|
13
|
+
* `1` when one `0x00` byte precedes an empty answer: Bun and Node send a response head only with
|
|
14
|
+
* its first body byte, so an empty answer would otherwise reach the gateway at the trailer.
|
|
15
|
+
*/
|
|
16
|
+
export declare const ANSWER_PREAMBLE_HEADER = "x-temper-answer-preamble";
|
|
17
|
+
/** A handler's declared Run outcome (RUN-8); on a framed response the trailer carries it instead. */
|
|
18
|
+
export declare const RUN_OUTCOME_HEADER = "x-temper-run-outcome";
|
|
19
|
+
export declare const EARLY_ANSWER_PROTOCOL_VERSION = 1;
|
|
20
|
+
/** Largest answer body: 1 MiB. */
|
|
21
|
+
export declare const MAX_ANSWER_BYTES = 1048576;
|
|
22
|
+
/** Largest trailer JSON: 64 KiB. */
|
|
23
|
+
export declare const MAX_TRAILER_BYTES = 65536;
|
|
24
|
+
/** Bytes of the big-endian trailer length prefix. */
|
|
25
|
+
export declare const TRAILER_LENGTH_BYTES = 4;
|
|
26
|
+
/** The policy the platform admitted this invocation under; `''` comes from a host that predates EAR-19. */
|
|
27
|
+
export type InvocationResponsePolicy = 'wait' | 'ack' | 'early' | '';
|
|
28
|
+
export interface AnswerTrailerError {
|
|
29
|
+
readonly tag: string;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
}
|
|
32
|
+
/** The JSON that ends a framed body. `outcome` sets the Run outcome; the answer status does not (EAR-6). */
|
|
33
|
+
export interface AnswerTrailer {
|
|
34
|
+
readonly v: typeof EARLY_ANSWER_PROTOCOL_VERSION;
|
|
35
|
+
readonly outcome: 'succeeded' | 'failed';
|
|
36
|
+
/** The final handler status, recorded as `http_status`. */
|
|
37
|
+
readonly status: number;
|
|
38
|
+
readonly error: AnswerTrailerError | null;
|
|
39
|
+
}
|
|
40
|
+
//# 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;;;GAGG;AACH,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,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,26 @@
|
|
|
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
|
+
/**
|
|
13
|
+
* `1` when one `0x00` byte precedes an empty answer: Bun and Node send a response head only with
|
|
14
|
+
* its first body byte, so an empty answer would otherwise reach the gateway at the trailer.
|
|
15
|
+
*/
|
|
16
|
+
export const ANSWER_PREAMBLE_HEADER = 'x-temper-answer-preamble';
|
|
17
|
+
/** A handler's declared Run outcome (RUN-8); on a framed response the trailer carries it instead. */
|
|
18
|
+
export const RUN_OUTCOME_HEADER = 'x-temper-run-outcome';
|
|
19
|
+
export const EARLY_ANSWER_PROTOCOL_VERSION = 1;
|
|
20
|
+
/** Largest answer body: 1 MiB. */
|
|
21
|
+
export const MAX_ANSWER_BYTES = 1_048_576;
|
|
22
|
+
/** Largest trailer JSON: 64 KiB. */
|
|
23
|
+
export const MAX_TRAILER_BYTES = 65_536;
|
|
24
|
+
/** Bytes of the big-endian trailer length prefix. */
|
|
25
|
+
export const TRAILER_LENGTH_BYTES = 4;
|
|
26
|
+
//# 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;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AACjE,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;
|
|
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"}
|