@nifrajs/core 2.14.1 → 3.2.0
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 +25 -0
- package/dist/assurance.d.ts +16 -8
- package/dist/assurance.d.ts.map +1 -1
- package/dist/assurance.js +33 -0
- package/dist/assurance.js.map +1 -1
- package/dist/durable-adapters.d.ts.map +1 -1
- package/dist/durable-adapters.js +26 -3
- package/dist/durable-adapters.js.map +1 -1
- package/dist/durable-approval.d.ts +56 -0
- package/dist/durable-approval.d.ts.map +1 -0
- package/dist/durable-approval.js +233 -0
- package/dist/durable-approval.js.map +1 -0
- package/dist/durable-effect.d.ts +42 -0
- package/dist/durable-effect.d.ts.map +1 -0
- package/dist/durable-effect.js +234 -0
- package/dist/durable-effect.js.map +1 -0
- package/dist/durable-execution.d.ts +8 -346
- package/dist/durable-execution.d.ts.map +1 -1
- package/dist/durable-execution.js +7 -1150
- package/dist/durable-execution.js.map +1 -1
- package/dist/durable-saga.d.ts +94 -0
- package/dist/durable-saga.d.ts.map +1 -0
- package/dist/durable-saga.js +550 -0
- package/dist/durable-saga.js.map +1 -0
- package/dist/edge-kit.d.ts +27 -0
- package/dist/edge-kit.d.ts.map +1 -0
- package/dist/edge-kit.js +24 -0
- package/dist/edge-kit.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/durable-approval-protocol.d.ts +1 -1
- package/dist/internal/durable-approval-protocol.d.ts.map +1 -1
- package/dist/internal/durable-effect-protocol.d.ts +1 -1
- package/dist/internal/durable-effect-protocol.d.ts.map +1 -1
- package/dist/internal/durable-saga-protocol.d.ts +1 -1
- package/dist/internal/durable-saga-protocol.d.ts.map +1 -1
- package/dist/internal/durable-shared.d.ts +26 -0
- package/dist/internal/durable-shared.d.ts.map +1 -0
- package/dist/internal/durable-shared.js +131 -0
- package/dist/internal/durable-shared.js.map +1 -0
- package/dist/internal/durable-types.d.ts +159 -0
- package/dist/internal/durable-types.d.ts.map +1 -0
- package/dist/internal/durable-types.js +2 -0
- package/dist/internal/durable-types.js.map +1 -0
- package/dist/internal/route-compiler.d.ts +61 -0
- package/dist/internal/route-compiler.d.ts.map +1 -0
- package/dist/internal/route-compiler.js +121 -0
- package/dist/internal/route-compiler.js.map +1 -0
- package/dist/internal/route-execution.d.ts +17 -9
- package/dist/internal/route-execution.d.ts.map +1 -1
- package/dist/internal/route-execution.js +4 -18
- package/dist/internal/route-execution.js.map +1 -1
- package/dist/internal/route-lanes.d.ts +35 -0
- package/dist/internal/route-lanes.d.ts.map +1 -0
- package/dist/internal/route-lanes.js +150 -0
- package/dist/internal/route-lanes.js.map +1 -0
- package/dist/internal/route-program.d.ts +67 -0
- package/dist/internal/route-program.d.ts.map +1 -0
- package/dist/internal/route-program.js +199 -0
- package/dist/internal/route-program.js.map +1 -0
- package/dist/response-observer.d.ts +25 -0
- package/dist/response-observer.d.ts.map +1 -0
- package/dist/response-observer.js +40 -0
- package/dist/response-observer.js.map +1 -0
- package/dist/security/baseline.d.ts +68 -0
- package/dist/security/baseline.d.ts.map +1 -0
- package/dist/security/baseline.js +118 -0
- package/dist/security/baseline.js.map +1 -0
- package/dist/server/bare-error-lane.d.ts +26 -0
- package/dist/server/bare-error-lane.d.ts.map +1 -0
- package/dist/server/bare-error-lane.js +60 -0
- package/dist/server/bare-error-lane.js.map +1 -0
- package/dist/server/body-lane.d.ts +13 -0
- package/dist/server/body-lane.d.ts.map +1 -0
- package/dist/server/body-lane.js +134 -0
- package/dist/server/body-lane.js.map +1 -0
- package/dist/server/body.d.ts +7 -0
- package/dist/server/body.d.ts.map +1 -1
- package/dist/server/body.js +7 -0
- package/dist/server/body.js.map +1 -1
- package/dist/server/bridge-markers.d.ts +25 -0
- package/dist/server/bridge-markers.d.ts.map +1 -0
- package/dist/server/bridge-markers.js +25 -0
- package/dist/server/bridge-markers.js.map +1 -0
- package/dist/server/context.d.ts +6 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/contract.d.ts +40 -14
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +7 -0
- package/dist/server/contract.js.map +1 -1
- package/dist/server/cookies.d.ts.map +1 -1
- package/dist/server/cookies.js +16 -2
- package/dist/server/cookies.js.map +1 -1
- package/dist/server/header-case.d.ts.map +1 -1
- package/dist/server/header-case.js +2 -1
- package/dist/server/header-case.js.map +1 -1
- package/dist/server/http.d.ts +36 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +49 -3
- package/dist/server/http.js.map +1 -1
- package/dist/server/install.d.ts +6 -8
- package/dist/server/install.d.ts.map +1 -1
- package/dist/server/install.js +7 -0
- package/dist/server/install.js.map +1 -1
- package/dist/server/node-outcome-hook.d.ts +2 -1
- package/dist/server/node-outcome-hook.d.ts.map +1 -1
- package/dist/server/node-outcome-hook.js.map +1 -1
- package/dist/server/node-outcome.d.ts +17 -2
- package/dist/server/node-outcome.d.ts.map +1 -1
- package/dist/server/node-outcome.js +37 -3
- package/dist/server/node-outcome.js.map +1 -1
- package/dist/server/plugin.d.ts +2 -2
- package/dist/server/plugin.d.ts.map +1 -1
- package/dist/server/plugin.js +6 -1
- package/dist/server/plugin.js.map +1 -1
- package/dist/server/query.d.ts +7 -1
- package/dist/server/query.d.ts.map +1 -1
- package/dist/server/query.js +8 -3
- package/dist/server/query.js.map +1 -1
- package/dist/server/registry.d.ts +40 -12
- package/dist/server/registry.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +2 -13
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +18 -159
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/respond.d.ts.map +1 -1
- package/dist/server/respond.js +58 -4
- package/dist/server/respond.js.map +1 -1
- package/dist/server/response-contract-lane.d.ts.map +1 -1
- package/dist/server/response-contract-lane.js +5 -2
- package/dist/server/response-contract-lane.js.map +1 -1
- package/dist/server/response-observer-runtime.d.ts +20 -0
- package/dist/server/response-observer-runtime.d.ts.map +1 -0
- package/dist/server/response-observer-runtime.js +95 -0
- package/dist/server/response-observer-runtime.js.map +1 -0
- package/dist/server/runtime-core.d.ts +76 -0
- package/dist/server/runtime-core.d.ts.map +1 -1
- package/dist/server/runtime-core.js +42 -1
- package/dist/server/runtime-core.js.map +1 -1
- package/dist/server/server-types.d.ts +6 -1
- package/dist/server/server-types.d.ts.map +1 -1
- package/dist/server/server.d.ts +158 -116
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +707 -844
- package/dist/server/server.js.map +1 -1
- package/dist/server/validation.d.ts +5 -0
- package/dist/server/validation.d.ts.map +1 -0
- package/dist/server/validation.js +13 -0
- package/dist/server/validation.js.map +1 -0
- package/dist/server/websocket.d.ts +20 -4
- package/dist/server/websocket.d.ts.map +1 -1
- package/dist/server/websocket.js +81 -11
- package/dist/server/websocket.js.map +1 -1
- package/dist/server/ws-bun.d.ts +12 -4
- package/dist/server/ws-bun.d.ts.map +1 -1
- package/dist/server/ws-bun.js +50 -16
- package/dist/server/ws-bun.js.map +1 -1
- package/dist/server/ws-hook.d.ts +3 -2
- package/dist/server/ws-hook.d.ts.map +1 -1
- package/dist/server.d.ts +3 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/single-copy-register.d.ts +2 -0
- package/dist/single-copy-register.d.ts.map +1 -0
- package/dist/single-copy-register.js +24 -0
- package/dist/single-copy-register.js.map +1 -0
- package/dist/single-copy.d.ts +156 -0
- package/dist/single-copy.d.ts.map +1 -0
- package/dist/single-copy.js +472 -0
- package/dist/single-copy.js.map +1 -0
- package/package.json +28 -3
- package/src/assurance.ts +58 -1
- package/src/durable-adapters.ts +20 -0
- package/src/durable-approval.ts +281 -0
- package/src/durable-effect.ts +300 -0
- package/src/durable-execution.ts +8 -1627
- package/src/durable-saga.ts +744 -0
- package/src/edge-kit.ts +27 -0
- package/src/errors.ts +1 -0
- package/src/index.ts +129 -2
- package/src/internal/durable-approval-protocol.ts +1 -1
- package/src/internal/durable-effect-protocol.ts +1 -1
- package/src/internal/durable-saga-protocol.ts +1 -1
- package/src/internal/durable-shared.ts +157 -0
- package/src/internal/durable-types.ts +194 -0
- package/src/internal/route-compiler.ts +234 -0
- package/src/internal/route-execution.ts +53 -96
- package/src/internal/route-lanes.ts +221 -0
- package/src/internal/route-program.ts +404 -0
- package/src/response-observer.ts +64 -0
- package/src/security/baseline.ts +172 -0
- package/src/server/bare-error-lane.ts +77 -0
- package/src/server/body-lane.ts +203 -0
- package/src/server/body.ts +8 -0
- package/src/server/bridge-markers.ts +24 -0
- package/src/server/context.ts +6 -1
- package/src/server/contract.ts +70 -20
- package/src/server/cookies.ts +16 -2
- package/src/server/header-case.ts +3 -1
- package/src/server/http.ts +53 -3
- package/src/server/install.ts +14 -0
- package/src/server/node-outcome-hook.ts +2 -1
- package/src/server/node-outcome.ts +44 -3
- package/src/server/plugin.ts +11 -5
- package/src/server/query.ts +10 -4
- package/src/server/registry.ts +71 -16
- package/src/server/request-context.ts +13 -216
- package/src/server/respond.ts +71 -3
- package/src/server/response-contract-lane.ts +6 -2
- package/src/server/response-observer-runtime.ts +135 -0
- package/src/server/runtime-core.ts +124 -1
- package/src/server/server-types.ts +6 -1
- package/src/server/server.ts +1446 -1485
- package/src/server/validation.ts +19 -0
- package/src/server/websocket.ts +127 -17
- package/src/server/ws-bun.ts +67 -15
- package/src/server/ws-hook.ts +3 -2
- package/src/server.ts +8 -2
- package/src/single-copy-register.ts +24 -0
- package/src/single-copy.ts +526 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
import { createEffectScope } from "./effect-scope.js";
|
|
2
|
+
import { validCapabilityId } from "./internal/capability-runtime.js";
|
|
3
|
+
import { durableSagaProtocol } from "./internal/durable-saga-protocol.js";
|
|
4
|
+
import { addDuration, assertPositiveMs, assertTimestamp, assertToken, bucketAdd, bucketMove, cloneValue, ERROR_CODE, indexedScan, MAX_RECONCILIATION_LIMIT, memoryScan, readClock, reconciliationLimit, } from "./internal/durable-shared.js";
|
|
5
|
+
// Durable saga + compensation state machine
|
|
6
|
+
function assertSagaDefinition(definition) {
|
|
7
|
+
if (typeof definition !== "object" || definition === null)
|
|
8
|
+
throw new TypeError("saga definition must be an object");
|
|
9
|
+
assertToken(definition.name, "saga definition", 128);
|
|
10
|
+
if (definition.capability !== undefined && !validCapabilityId(definition.capability))
|
|
11
|
+
throw new TypeError("saga capability is invalid");
|
|
12
|
+
if (typeof definition.run !== "function")
|
|
13
|
+
throw new TypeError("saga run must be a function");
|
|
14
|
+
if (typeof definition.compensators !== "object" ||
|
|
15
|
+
definition.compensators === null ||
|
|
16
|
+
Array.isArray(definition.compensators)) {
|
|
17
|
+
throw new TypeError("saga compensators must be an object");
|
|
18
|
+
}
|
|
19
|
+
for (const [name, compensator] of Object.entries(definition.compensators)) {
|
|
20
|
+
assertToken(name, "saga compensator name", 128);
|
|
21
|
+
if (typeof compensator !== "function")
|
|
22
|
+
throw new TypeError(`saga compensator ${name} must be a function`);
|
|
23
|
+
}
|
|
24
|
+
if (definition.retry !== undefined) {
|
|
25
|
+
if (typeof definition.retry !== "object" || definition.retry === null)
|
|
26
|
+
throw new TypeError("saga retry must be an object");
|
|
27
|
+
if (definition.retry.maxAttempts !== undefined)
|
|
28
|
+
assertPositiveMs(definition.retry.maxAttempts, "saga maxAttempts");
|
|
29
|
+
if (definition.retry.backoffMs !== undefined &&
|
|
30
|
+
typeof definition.retry.backoffMs !== "function")
|
|
31
|
+
throw new TypeError("saga backoffMs must be a function");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function defineSaga(definition) {
|
|
35
|
+
assertSagaDefinition(definition);
|
|
36
|
+
return Object.freeze({
|
|
37
|
+
...definition,
|
|
38
|
+
compensators: Object.freeze({ ...definition.compensators }),
|
|
39
|
+
...(definition.retry === undefined ? {} : { retry: Object.freeze({ ...definition.retry }) }),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export class SagaConcurrencyError extends Error {
|
|
43
|
+
sagaId;
|
|
44
|
+
constructor(sagaId) {
|
|
45
|
+
super(`saga ${sagaId}: concurrent transition rejected`);
|
|
46
|
+
this.sagaId = sagaId;
|
|
47
|
+
this.name = "SagaConcurrencyError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export class SagaAmbiguousStepError extends Error {
|
|
51
|
+
sagaId;
|
|
52
|
+
step;
|
|
53
|
+
effectId;
|
|
54
|
+
constructor(sagaId, step, effectId) {
|
|
55
|
+
super(`saga ${sagaId}: step ${step} has an ambiguous effect`);
|
|
56
|
+
this.sagaId = sagaId;
|
|
57
|
+
this.step = step;
|
|
58
|
+
this.effectId = effectId;
|
|
59
|
+
this.name = "SagaAmbiguousStepError";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export class SagaResolutionError extends Error {
|
|
63
|
+
sagaId;
|
|
64
|
+
step;
|
|
65
|
+
constructor(sagaId, step, message) {
|
|
66
|
+
super(`saga ${sagaId}: step ${step} ${message}`);
|
|
67
|
+
this.sagaId = sagaId;
|
|
68
|
+
this.step = step;
|
|
69
|
+
this.name = "SagaResolutionError";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Throw this only when a provider conclusively proves that no effect committed. */
|
|
73
|
+
export class SagaStepNotCommittedError extends Error {
|
|
74
|
+
code;
|
|
75
|
+
constructor(code = "not_committed") {
|
|
76
|
+
super("saga step conclusively did not commit");
|
|
77
|
+
this.code = code;
|
|
78
|
+
this.name = "SagaStepNotCommittedError";
|
|
79
|
+
if (!ERROR_CODE.test(code))
|
|
80
|
+
throw new TypeError("saga step error code is invalid");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let neverAbortSignal;
|
|
84
|
+
function signalOrNever(signal) {
|
|
85
|
+
neverAbortSignal ??= new AbortController().signal;
|
|
86
|
+
return signal ?? neverAbortSignal;
|
|
87
|
+
}
|
|
88
|
+
function throwIfAborted(signal) {
|
|
89
|
+
if (signal.aborted) {
|
|
90
|
+
throw signal.reason instanceof Error ? signal.reason : new Error("saga execution aborted");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function createSagaEngine(options) {
|
|
94
|
+
if (options.store.durability !== "durable" && options.allowMemoryStore !== true)
|
|
95
|
+
throw new TypeError('saga engine requires store.durability === "durable"');
|
|
96
|
+
const clock = options.now ?? Date.now;
|
|
97
|
+
const now = () => readClock(clock, "saga clock");
|
|
98
|
+
const observer = options.observer;
|
|
99
|
+
const load = async (sagaId) => {
|
|
100
|
+
const record = await options.store.get(sagaId);
|
|
101
|
+
if (record === undefined)
|
|
102
|
+
throw new Error(`saga ${sagaId}: not found`);
|
|
103
|
+
if (record.sagaId !== sagaId ||
|
|
104
|
+
!["running", "compensating", "completed", "compensated", "manual-review"].includes(record.state) ||
|
|
105
|
+
!Array.isArray(record.steps) ||
|
|
106
|
+
!Number.isSafeInteger(record.version) ||
|
|
107
|
+
record.version < 1) {
|
|
108
|
+
throw new TypeError(`saga ${sagaId}: store returned an invalid record`);
|
|
109
|
+
}
|
|
110
|
+
assertToken(record.definition, "stored saga definition", 128);
|
|
111
|
+
assertTimestamp(record.createdAt, "stored saga createdAt");
|
|
112
|
+
assertTimestamp(record.updatedAt, "stored saga updatedAt");
|
|
113
|
+
if (record.createdAt > record.updatedAt)
|
|
114
|
+
throw new TypeError(`saga ${sagaId}: updatedAt precedes createdAt`);
|
|
115
|
+
const names = new Set();
|
|
116
|
+
const effectIds = new Set();
|
|
117
|
+
for (const step of record.steps) {
|
|
118
|
+
assertToken(step.name, "stored saga step", 128);
|
|
119
|
+
assertToken(step.effectId, "stored saga effect id", 64);
|
|
120
|
+
assertToken(step.compensationEffectId, "stored saga compensation effect id", 64);
|
|
121
|
+
if (![
|
|
122
|
+
"executing",
|
|
123
|
+
"committed",
|
|
124
|
+
"failed",
|
|
125
|
+
"ambiguous",
|
|
126
|
+
"compensating",
|
|
127
|
+
"compensation-failed",
|
|
128
|
+
"compensated",
|
|
129
|
+
].includes(step.state) ||
|
|
130
|
+
!Number.isSafeInteger(step.attempts) ||
|
|
131
|
+
step.attempts < 0 ||
|
|
132
|
+
names.has(step.name) ||
|
|
133
|
+
effectIds.has(step.effectId) ||
|
|
134
|
+
effectIds.has(step.compensationEffectId)) {
|
|
135
|
+
throw new TypeError(`saga ${sagaId}: store returned an invalid step record`);
|
|
136
|
+
}
|
|
137
|
+
names.add(step.name);
|
|
138
|
+
effectIds.add(step.effectId);
|
|
139
|
+
effectIds.add(step.compensationEffectId);
|
|
140
|
+
if (step.nextAttemptAt !== undefined)
|
|
141
|
+
assertTimestamp(step.nextAttemptAt, "stored saga nextAttemptAt");
|
|
142
|
+
if (step.errorCode !== undefined && !ERROR_CODE.test(step.errorCode))
|
|
143
|
+
throw new TypeError(`saga ${sagaId}: store returned an invalid error code`);
|
|
144
|
+
}
|
|
145
|
+
return record;
|
|
146
|
+
};
|
|
147
|
+
const save = async (current, update) => {
|
|
148
|
+
const next = durableSagaProtocol.transition(current, {
|
|
149
|
+
sagaId: current.sagaId,
|
|
150
|
+
version: current.version,
|
|
151
|
+
record: Object.freeze({ ...update, version: current.version + 1 }),
|
|
152
|
+
});
|
|
153
|
+
if (next === undefined)
|
|
154
|
+
throw new SagaConcurrencyError(current.sagaId);
|
|
155
|
+
if (!(await options.store.compareAndSet({
|
|
156
|
+
sagaId: current.sagaId,
|
|
157
|
+
version: current.version,
|
|
158
|
+
record: next,
|
|
159
|
+
})))
|
|
160
|
+
throw new SagaConcurrencyError(current.sagaId);
|
|
161
|
+
return next;
|
|
162
|
+
};
|
|
163
|
+
const withStep = (record, index, step, state = record.state) => durableSagaProtocol.withStep(record, index, step, state, now());
|
|
164
|
+
const effectScope = createEffectScope({
|
|
165
|
+
...(observer === undefined ? {} : { observers: [observer] }),
|
|
166
|
+
});
|
|
167
|
+
const compensate = async (definition, sagaId, runOptions = {}) => {
|
|
168
|
+
assertSagaDefinition(definition);
|
|
169
|
+
assertToken(sagaId, "saga id", 128);
|
|
170
|
+
const signal = signalOrNever(runOptions.signal);
|
|
171
|
+
throwIfAborted(signal);
|
|
172
|
+
let record = await load(sagaId);
|
|
173
|
+
if (record.definition !== definition.name)
|
|
174
|
+
throw new TypeError("saga definition mismatch");
|
|
175
|
+
if (record.state === "completed" || record.state === "compensated")
|
|
176
|
+
return record;
|
|
177
|
+
if (record.steps.some((step) => step.state === "ambiguous" || step.state === "executing" || step.state === "compensating")) {
|
|
178
|
+
if (record.state !== "manual-review")
|
|
179
|
+
record = await save(record, { ...record, state: "manual-review", updatedAt: now() });
|
|
180
|
+
const ambiguous = record.steps.find((step) => step.state === "ambiguous" || step.state === "executing" || step.state === "compensating");
|
|
181
|
+
throw new SagaAmbiguousStepError(sagaId, ambiguous.name, ambiguous.state === "compensating" ? ambiguous.compensationEffectId : ambiguous.effectId);
|
|
182
|
+
}
|
|
183
|
+
if (record.state !== "compensating")
|
|
184
|
+
record = await save(record, { ...record, state: "compensating", updatedAt: now() });
|
|
185
|
+
const maxAttempts = definition.retry?.maxAttempts ?? 3;
|
|
186
|
+
assertPositiveMs(maxAttempts, "saga maxAttempts");
|
|
187
|
+
const backoff = definition.retry?.backoffMs ??
|
|
188
|
+
((attempt) => Math.min(60_000, 100 * 2 ** (attempt - 1)));
|
|
189
|
+
for (let index = record.steps.length - 1; index >= 0; index--) {
|
|
190
|
+
throwIfAborted(signal);
|
|
191
|
+
let step = record.steps[index];
|
|
192
|
+
if (step.state === "compensated" || step.state === "failed")
|
|
193
|
+
continue;
|
|
194
|
+
if (step.state !== "committed" && step.state !== "compensation-failed")
|
|
195
|
+
continue;
|
|
196
|
+
if (step.nextAttemptAt !== undefined && step.nextAttemptAt > now())
|
|
197
|
+
return record;
|
|
198
|
+
const compensator = definition.compensators[step.name];
|
|
199
|
+
if (typeof compensator !== "function") {
|
|
200
|
+
record = await save(record, { ...record, state: "manual-review", updatedAt: now() });
|
|
201
|
+
return record;
|
|
202
|
+
}
|
|
203
|
+
if (step.attempts >= maxAttempts) {
|
|
204
|
+
if (record.state !== "manual-review")
|
|
205
|
+
record = await save(record, { ...record, state: "manual-review", updatedAt: now() });
|
|
206
|
+
return record;
|
|
207
|
+
}
|
|
208
|
+
const attempt = step.attempts + 1;
|
|
209
|
+
const { errorCode: _errorCode, nextAttemptAt: _nextAttemptAt, ...stepBase } = step;
|
|
210
|
+
step = { ...stepBase, state: "compensating", attempts: attempt };
|
|
211
|
+
let transitionError;
|
|
212
|
+
try {
|
|
213
|
+
await effectScope.run({
|
|
214
|
+
effectId: step.compensationEffectId,
|
|
215
|
+
capability: definition.capability ?? "saga.compensate",
|
|
216
|
+
stage: "compensation",
|
|
217
|
+
signal,
|
|
218
|
+
attempt,
|
|
219
|
+
failurePhase: () => "failed",
|
|
220
|
+
errorCode: () => "compensation_failed",
|
|
221
|
+
transitions: {
|
|
222
|
+
async executing() {
|
|
223
|
+
record = await save(record, withStep(record, index, step));
|
|
224
|
+
},
|
|
225
|
+
async committed() {
|
|
226
|
+
step = { ...step, state: "compensated" };
|
|
227
|
+
record = await save(record, withStep(record, index, step));
|
|
228
|
+
},
|
|
229
|
+
async failed() {
|
|
230
|
+
const exhausted = attempt >= maxAttempts;
|
|
231
|
+
try {
|
|
232
|
+
const delay = exhausted ? undefined : backoff(attempt);
|
|
233
|
+
if (delay !== undefined && (!Number.isSafeInteger(delay) || delay < 0))
|
|
234
|
+
throw new RangeError("saga backoff must return a non-negative safe integer");
|
|
235
|
+
const failed = {
|
|
236
|
+
...step,
|
|
237
|
+
state: "compensation-failed",
|
|
238
|
+
errorCode: "compensation_failed",
|
|
239
|
+
...(delay === undefined
|
|
240
|
+
? {}
|
|
241
|
+
: { nextAttemptAt: addDuration(now(), delay, "saga next retry") }),
|
|
242
|
+
};
|
|
243
|
+
record = await save(record, withStep(record, index, failed, exhausted ? "manual-review" : "compensating"));
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
transitionError = error;
|
|
247
|
+
const failed = {
|
|
248
|
+
...step,
|
|
249
|
+
state: "compensation-failed",
|
|
250
|
+
errorCode: "invalid_retry_policy",
|
|
251
|
+
};
|
|
252
|
+
record = await save(record, withStep(record, index, failed, "manual-review"));
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
}, async (owned) => {
|
|
257
|
+
await compensator(cloneValue(step.compensationArgs), {
|
|
258
|
+
effectId: owned.effectId,
|
|
259
|
+
sagaId,
|
|
260
|
+
attempt,
|
|
261
|
+
signal: owned.signal,
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
if (transitionError !== undefined)
|
|
267
|
+
throw transitionError;
|
|
268
|
+
return record;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return await save(record, { ...record, state: "compensated", updatedAt: now() });
|
|
272
|
+
};
|
|
273
|
+
const resume = async (definition, sagaId, runOptions = {}) => {
|
|
274
|
+
assertSagaDefinition(definition);
|
|
275
|
+
assertToken(sagaId, "saga id", 128);
|
|
276
|
+
const signal = signalOrNever(runOptions.signal);
|
|
277
|
+
throwIfAborted(signal);
|
|
278
|
+
let record = await load(sagaId);
|
|
279
|
+
if (record.definition !== definition.name)
|
|
280
|
+
throw new TypeError("saga definition mismatch");
|
|
281
|
+
if (record.state !== "running")
|
|
282
|
+
return record;
|
|
283
|
+
const context = {
|
|
284
|
+
async step(name, compensationArgs, execute) {
|
|
285
|
+
throwIfAborted(signal);
|
|
286
|
+
assertToken(name, "saga step", 128);
|
|
287
|
+
if (typeof execute !== "function")
|
|
288
|
+
throw new TypeError("saga step execute must be a function");
|
|
289
|
+
if (typeof definition.compensators[name] !== "function")
|
|
290
|
+
throw new TypeError(`saga step ${name} has no compensator`);
|
|
291
|
+
record = await load(sagaId);
|
|
292
|
+
const existingIndex = record.steps.findIndex((step) => step.name === name);
|
|
293
|
+
if (existingIndex >= 0) {
|
|
294
|
+
const existing = record.steps[existingIndex];
|
|
295
|
+
if (existing.state === "committed")
|
|
296
|
+
return cloneValue(existing.result);
|
|
297
|
+
if (existing.state === "executing" || existing.state === "ambiguous") {
|
|
298
|
+
if (record.state !== "manual-review")
|
|
299
|
+
record = await save(record, { ...record, state: "manual-review", updatedAt: now() });
|
|
300
|
+
throw new SagaAmbiguousStepError(sagaId, name, existing.effectId);
|
|
301
|
+
}
|
|
302
|
+
throw new Error(`saga ${sagaId}: step ${name} cannot resume from ${existing.state}`);
|
|
303
|
+
}
|
|
304
|
+
const effectId = crypto.randomUUID();
|
|
305
|
+
const step = Object.freeze({
|
|
306
|
+
name,
|
|
307
|
+
effectId,
|
|
308
|
+
compensationEffectId: crypto.randomUUID(),
|
|
309
|
+
state: "executing",
|
|
310
|
+
compensationArgs: cloneValue(compensationArgs),
|
|
311
|
+
attempts: 0,
|
|
312
|
+
});
|
|
313
|
+
return await effectScope.run({
|
|
314
|
+
effectId,
|
|
315
|
+
capability: definition.capability ?? "saga.execute",
|
|
316
|
+
stage: "execution",
|
|
317
|
+
signal,
|
|
318
|
+
failurePhase: (error) => error instanceof SagaStepNotCommittedError ? "failed" : "ambiguous",
|
|
319
|
+
errorCode: (error, began) => error instanceof SagaStepNotCommittedError
|
|
320
|
+
? error.code
|
|
321
|
+
: began
|
|
322
|
+
? "execution_unknown"
|
|
323
|
+
: "aborted_before_execution",
|
|
324
|
+
transitions: {
|
|
325
|
+
async intent() {
|
|
326
|
+
record = await save(record, {
|
|
327
|
+
...record,
|
|
328
|
+
steps: Object.freeze([...record.steps, step]),
|
|
329
|
+
updatedAt: now(),
|
|
330
|
+
});
|
|
331
|
+
},
|
|
332
|
+
async committed(_owned, result) {
|
|
333
|
+
record = await load(sagaId);
|
|
334
|
+
const index = record.steps.findIndex((candidate) => candidate.effectId === effectId);
|
|
335
|
+
const committed = {
|
|
336
|
+
...record.steps[index],
|
|
337
|
+
state: "committed",
|
|
338
|
+
result: cloneValue(result),
|
|
339
|
+
};
|
|
340
|
+
record = await save(record, withStep(record, index, committed));
|
|
341
|
+
},
|
|
342
|
+
async failed(_owned, failure) {
|
|
343
|
+
record = await load(sagaId);
|
|
344
|
+
const index = record.steps.findIndex((candidate) => candidate.effectId === effectId);
|
|
345
|
+
const known = failure.error instanceof SagaStepNotCommittedError || !failure.began;
|
|
346
|
+
const failed = {
|
|
347
|
+
...record.steps[index],
|
|
348
|
+
state: known ? "failed" : "ambiguous",
|
|
349
|
+
errorCode: failure.error instanceof SagaStepNotCommittedError
|
|
350
|
+
? failure.error.code
|
|
351
|
+
: failure.began
|
|
352
|
+
? "execution_unknown"
|
|
353
|
+
: "aborted_before_execution",
|
|
354
|
+
};
|
|
355
|
+
record = await save(record, withStep(record, index, failed, known ? "compensating" : "manual-review"));
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
}, (owned) => execute({ effectId: owned.effectId, signal: owned.signal }));
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
try {
|
|
362
|
+
throwIfAborted(signal);
|
|
363
|
+
await definition.run(context, cloneValue(record.input));
|
|
364
|
+
record = await load(sagaId);
|
|
365
|
+
if (record.state === "running")
|
|
366
|
+
record = await save(record, { ...record, state: "completed", updatedAt: now() });
|
|
367
|
+
return record;
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
record = await load(sagaId);
|
|
371
|
+
if (record.state === "manual-review")
|
|
372
|
+
throw error;
|
|
373
|
+
await compensate(definition, sagaId, runOptions);
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const resolveAmbiguity = async (definition, sagaId, resolution) => {
|
|
378
|
+
assertSagaDefinition(definition);
|
|
379
|
+
assertToken(sagaId, "saga id", 128);
|
|
380
|
+
if (typeof resolution !== "object" || resolution === null)
|
|
381
|
+
throw new TypeError("saga resolution must be an object");
|
|
382
|
+
if ((resolution.kind === "execution" &&
|
|
383
|
+
resolution.outcome !== "committed" &&
|
|
384
|
+
resolution.outcome !== "not-committed") ||
|
|
385
|
+
(resolution.kind === "compensation" &&
|
|
386
|
+
resolution.outcome !== "compensated" &&
|
|
387
|
+
resolution.outcome !== "not-compensated") ||
|
|
388
|
+
(resolution.kind !== "execution" && resolution.kind !== "compensation")) {
|
|
389
|
+
throw new TypeError("saga resolution kind or outcome is invalid");
|
|
390
|
+
}
|
|
391
|
+
assertToken(resolution.step, "saga resolution step", 128);
|
|
392
|
+
assertToken(resolution.effectId, "saga resolution effect id", 64);
|
|
393
|
+
let record = await load(sagaId);
|
|
394
|
+
if (record.definition !== definition.name)
|
|
395
|
+
throw new TypeError("saga definition mismatch");
|
|
396
|
+
const index = record.steps.findIndex((step) => step.name === resolution.step);
|
|
397
|
+
if (index < 0)
|
|
398
|
+
throw new SagaResolutionError(sagaId, resolution.step, "does not exist");
|
|
399
|
+
const current = record.steps[index];
|
|
400
|
+
let step;
|
|
401
|
+
let state;
|
|
402
|
+
if (resolution.kind === "execution") {
|
|
403
|
+
if (current.effectId !== resolution.effectId)
|
|
404
|
+
throw new SagaResolutionError(sagaId, resolution.step, "execution effect id does not match");
|
|
405
|
+
if (current.state !== "executing" && current.state !== "ambiguous")
|
|
406
|
+
throw new SagaResolutionError(sagaId, resolution.step, `is not awaiting an execution resolution (${current.state})`);
|
|
407
|
+
const { errorCode: _errorCode, result: _result, ...base } = current;
|
|
408
|
+
if (resolution.outcome === "committed") {
|
|
409
|
+
step = { ...base, state: "committed", result: cloneValue(resolution.result) };
|
|
410
|
+
state = "running";
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
const errorCode = resolution.errorCode ?? "not_committed";
|
|
414
|
+
if (!ERROR_CODE.test(errorCode))
|
|
415
|
+
throw new TypeError("saga resolution errorCode is invalid");
|
|
416
|
+
step = { ...base, state: "failed", errorCode };
|
|
417
|
+
state = "compensating";
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
if (current.compensationEffectId !== resolution.effectId)
|
|
422
|
+
throw new SagaResolutionError(sagaId, resolution.step, "compensation effect id does not match");
|
|
423
|
+
if (current.state !== "compensating")
|
|
424
|
+
throw new SagaResolutionError(sagaId, resolution.step, `is not awaiting a compensation resolution (${current.state})`);
|
|
425
|
+
const { errorCode: _errorCode, nextAttemptAt: _nextAttemptAt, ...base } = current;
|
|
426
|
+
step = {
|
|
427
|
+
...base,
|
|
428
|
+
state: resolution.outcome === "compensated" ? "compensated" : "compensation-failed",
|
|
429
|
+
};
|
|
430
|
+
state =
|
|
431
|
+
resolution.outcome === "not-compensated" &&
|
|
432
|
+
current.attempts >= (definition.retry?.maxAttempts ?? 3)
|
|
433
|
+
? "manual-review"
|
|
434
|
+
: "compensating";
|
|
435
|
+
}
|
|
436
|
+
record = await save(record, withStep(record, index, Object.freeze(step), state));
|
|
437
|
+
return record;
|
|
438
|
+
};
|
|
439
|
+
const engine = {
|
|
440
|
+
async execute(definition, sagaId, input, runOptions = {}) {
|
|
441
|
+
assertSagaDefinition(definition);
|
|
442
|
+
assertToken(sagaId, "saga id", 128);
|
|
443
|
+
throwIfAborted(signalOrNever(runOptions.signal));
|
|
444
|
+
const at = now();
|
|
445
|
+
const accepted = await options.store.create(Object.freeze({
|
|
446
|
+
sagaId,
|
|
447
|
+
definition: definition.name,
|
|
448
|
+
state: "running",
|
|
449
|
+
input: cloneValue(input),
|
|
450
|
+
steps: Object.freeze([]),
|
|
451
|
+
createdAt: at,
|
|
452
|
+
updatedAt: at,
|
|
453
|
+
version: 1,
|
|
454
|
+
}));
|
|
455
|
+
if (!accepted)
|
|
456
|
+
throw new Error(`saga ${sagaId}: already exists`);
|
|
457
|
+
return await resume(definition, sagaId, runOptions);
|
|
458
|
+
},
|
|
459
|
+
resume,
|
|
460
|
+
compensate,
|
|
461
|
+
resolveAmbiguity,
|
|
462
|
+
};
|
|
463
|
+
return Object.freeze(engine);
|
|
464
|
+
}
|
|
465
|
+
export class MemorySagaStore {
|
|
466
|
+
durability = "memory";
|
|
467
|
+
records = new Map();
|
|
468
|
+
// Secondary index: sagaIds grouped by state, so reconciliation scans only the requested (few,
|
|
469
|
+
// non-terminal) states instead of walking every retained record. See {@link indexedScan}.
|
|
470
|
+
byState = new Map();
|
|
471
|
+
create(record) {
|
|
472
|
+
if (this.records.has(record.sagaId))
|
|
473
|
+
return false;
|
|
474
|
+
this.records.set(record.sagaId, Object.freeze(cloneValue(record)));
|
|
475
|
+
bucketAdd(this.byState, record.state, record.sagaId);
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
get(sagaId) {
|
|
479
|
+
const record = this.records.get(sagaId);
|
|
480
|
+
return record === undefined ? undefined : Object.freeze(cloneValue(record));
|
|
481
|
+
}
|
|
482
|
+
compareAndSet(input) {
|
|
483
|
+
const current = this.records.get(input.sagaId);
|
|
484
|
+
const next = durableSagaProtocol.transition(current, input);
|
|
485
|
+
if (next === undefined)
|
|
486
|
+
return false;
|
|
487
|
+
if (current === undefined)
|
|
488
|
+
return false;
|
|
489
|
+
this.records.set(input.sagaId, Object.freeze(next));
|
|
490
|
+
bucketMove(this.byState, current.state, input.record.state, input.sagaId);
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
list() {
|
|
494
|
+
return Object.freeze([...this.records.values()].map((record) => Object.freeze(cloneValue(record))));
|
|
495
|
+
}
|
|
496
|
+
scan(input) {
|
|
497
|
+
return indexedScan(this.byState, (id) => this.records.get(id), input);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async function scanSagaRecords(store, input) {
|
|
501
|
+
if (store.scan !== undefined)
|
|
502
|
+
return await store.scan(input);
|
|
503
|
+
if (store.list === undefined)
|
|
504
|
+
throw new TypeError("saga store does not support reconciliation");
|
|
505
|
+
return memoryScan(await store.list(), input);
|
|
506
|
+
}
|
|
507
|
+
export async function reconcileSagasPage(store, options) {
|
|
508
|
+
const findings = [];
|
|
509
|
+
const page = await scanSagaRecords(store, {
|
|
510
|
+
states: ["running", "compensating", "manual-review"],
|
|
511
|
+
...(options.cursor === undefined ? {} : { cursor: options.cursor }),
|
|
512
|
+
limit: reconciliationLimit(options.limit),
|
|
513
|
+
});
|
|
514
|
+
for (const record of page.records) {
|
|
515
|
+
const ambiguous = record.steps.find((step) => step.state === "executing" || step.state === "ambiguous" || step.state === "compensating");
|
|
516
|
+
if (ambiguous !== undefined) {
|
|
517
|
+
findings.push(Object.freeze({
|
|
518
|
+
sagaId: record.sagaId,
|
|
519
|
+
state: record.state,
|
|
520
|
+
step: ambiguous.name,
|
|
521
|
+
effectId: ambiguous.state === "compensating"
|
|
522
|
+
? ambiguous.compensationEffectId
|
|
523
|
+
: ambiguous.effectId,
|
|
524
|
+
reason: ambiguous.state === "compensating" ? "ambiguous-compensation" : "ambiguous-execution",
|
|
525
|
+
}));
|
|
526
|
+
}
|
|
527
|
+
else if (record.state === "manual-review") {
|
|
528
|
+
findings.push(Object.freeze({ sagaId: record.sagaId, state: record.state, reason: "manual-review" }));
|
|
529
|
+
}
|
|
530
|
+
else if ((record.state === "running" || record.state === "compensating") &&
|
|
531
|
+
record.updatedAt <= options.staleBefore) {
|
|
532
|
+
findings.push(Object.freeze({ sagaId: record.sagaId, state: record.state, reason: "stale-running" }));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return Object.freeze({
|
|
536
|
+
findings: Object.freeze(findings),
|
|
537
|
+
...(page.cursor === undefined ? {} : { cursor: page.cursor }),
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
export async function reconcileSagas(store, options) {
|
|
541
|
+
const page = await reconcileSagasPage(store, {
|
|
542
|
+
...options,
|
|
543
|
+
limit: MAX_RECONCILIATION_LIMIT,
|
|
544
|
+
});
|
|
545
|
+
if (page.cursor !== undefined) {
|
|
546
|
+
throw new RangeError(`saga reconciliation exceeds ${MAX_RECONCILIATION_LIMIT} records; use reconcileSagasPage()`);
|
|
547
|
+
}
|
|
548
|
+
return page.findings;
|
|
549
|
+
}
|
|
550
|
+
//# sourceMappingURL=durable-saga.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-saga.js","sourceRoot":"","sources":["../src/durable-saga.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge kit - the moat-neutral free functions a compact fetch-handler server needs to enforce the
|
|
3
|
+
* SAME request trust boundary the full `Server` does, without pulling in the full builder.
|
|
4
|
+
*
|
|
5
|
+
* A minimal edge entrypoint (`@nifrajs/edge`) is not allowed to re-derive the body lane: the assembly
|
|
6
|
+
* order of the content-type dispatch, the bounded read, the Content-Length pre-reject, and the
|
|
7
|
+
* prototype-poisoning guard is a security contract, and a second copy of it would drift. This subpath
|
|
8
|
+
* exposes the one lane the fused body runner already calls, so a compact server reuses it verbatim:
|
|
9
|
+
*
|
|
10
|
+
* - {@link readBodyFramed} read + cap + proto-guard + content-type framing (JSON / urlencoded / 415)
|
|
11
|
+
* - {@link toResponse} render a {@link ResponseResult} (e.g. a 413 / 415 rejection) to a `Response`
|
|
12
|
+
* - {@link plainError} the structured rejection envelope the lane returns
|
|
13
|
+
* - {@link queryObjectOf} / {@link searchOf} query parse without a full WHATWG URL construction
|
|
14
|
+
*
|
|
15
|
+
* Everything here carries only structure - bytes, guards, and envelopes - never routing, lifecycle,
|
|
16
|
+
* or app state. It is the interface, not the framework.
|
|
17
|
+
*/
|
|
18
|
+
export { readBodyFramed } from "./server/body-lane.js";
|
|
19
|
+
export { plainError } from "./server/http.js";
|
|
20
|
+
export type { ProtoPoisoning } from "./server/proto-guard.js";
|
|
21
|
+
export { type QueryValue, queryObjectOf, searchOf } from "./server/query.js";
|
|
22
|
+
export { toResponse } from "./server/respond.js";
|
|
23
|
+
export type { ResponseResult } from "./server/runtime-core.js";
|
|
24
|
+
export { EMPTY_RESPONSE_CONTROLS } from "./server/runtime-core.js";
|
|
25
|
+
export type { CtxSet, MaybePromise, RequestSource } from "./server/server.js";
|
|
26
|
+
export { plainValidationError } from "./server/validation.js";
|
|
27
|
+
//# sourceMappingURL=edge-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-kit.d.ts","sourceRoot":"","sources":["../src/edge-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA"}
|
package/dist/edge-kit.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge kit - the moat-neutral free functions a compact fetch-handler server needs to enforce the
|
|
3
|
+
* SAME request trust boundary the full `Server` does, without pulling in the full builder.
|
|
4
|
+
*
|
|
5
|
+
* A minimal edge entrypoint (`@nifrajs/edge`) is not allowed to re-derive the body lane: the assembly
|
|
6
|
+
* order of the content-type dispatch, the bounded read, the Content-Length pre-reject, and the
|
|
7
|
+
* prototype-poisoning guard is a security contract, and a second copy of it would drift. This subpath
|
|
8
|
+
* exposes the one lane the fused body runner already calls, so a compact server reuses it verbatim:
|
|
9
|
+
*
|
|
10
|
+
* - {@link readBodyFramed} read + cap + proto-guard + content-type framing (JSON / urlencoded / 415)
|
|
11
|
+
* - {@link toResponse} render a {@link ResponseResult} (e.g. a 413 / 415 rejection) to a `Response`
|
|
12
|
+
* - {@link plainError} the structured rejection envelope the lane returns
|
|
13
|
+
* - {@link queryObjectOf} / {@link searchOf} query parse without a full WHATWG URL construction
|
|
14
|
+
*
|
|
15
|
+
* Everything here carries only structure - bytes, guards, and envelopes - never routing, lifecycle,
|
|
16
|
+
* or app state. It is the interface, not the framework.
|
|
17
|
+
*/
|
|
18
|
+
export { readBodyFramed } from "./server/body-lane.js";
|
|
19
|
+
export { plainError } from "./server/http.js";
|
|
20
|
+
export { queryObjectOf, searchOf } from "./server/query.js";
|
|
21
|
+
export { toResponse } from "./server/respond.js";
|
|
22
|
+
export { EMPTY_RESPONSE_CONTROLS } from "./server/runtime-core.js";
|
|
23
|
+
export { plainValidationError } from "./server/validation.js";
|
|
24
|
+
//# sourceMappingURL=edge-kit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-kit.js","sourceRoot":"","sources":["../src/edge-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAmB,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA"}
|