stitchkit 0.60.0 → 0.61.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/dist/agent-runtime/coordinator.d.ts +10 -0
- package/dist/agent-runtime/coordinator.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/schemas.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts.map +1 -1
- package/dist/agent-runtime.js +97 -12
- package/dist/application/grammy.d.ts +12 -6
- package/dist/application/grammy.d.ts.map +1 -1
- package/dist/application/kernel.d.ts +35 -2
- package/dist/application/kernel.d.ts.map +1 -1
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application-grammy.js +5 -3
- package/dist/application.d.ts +1 -1
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +12 -6
- package/dist/browser/socket-io.d.ts +47 -0
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/browser/stream.d.ts +23 -0
- package/dist/browser/stream.d.ts.map +1 -1
- package/dist/cli.js +5 -4
- package/dist/contract/errors.d.ts +1 -0
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/index.js +1 -1
- package/dist/{index-8pc5s3pz.js → index-1pgeyyee.js} +3 -3
- package/dist/{index-9h1vba8n.js → index-413xk7ga.js} +2 -1
- package/dist/{index-8es1hrv4.js → index-6taryy00.js} +1 -1
- package/dist/{index-1zencgcb.js → index-eabpd4tb.js} +61 -10
- package/dist/{index-3w74r08v.js → index-mfw1pec7.js} +7 -5
- package/dist/{index-f7521k0x.js → index-s1tywej8.js} +95 -24
- package/dist/{index-6fbp58g8.js → index-tvwcrx2d.js} +4 -2
- package/dist/{index-v6e8hnkx.js → index-wd8g8z6e.js} +1 -84
- package/dist/{index-2akar0rq.js → index-wrhf06ak.js} +7 -5
- package/dist/index-xxye8j3k.js +85 -0
- package/dist/{index-3hn10n4c.js → index-y91zd0ch.js} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +213 -17
- package/dist/internal/optional-peer.d.ts +14 -0
- package/dist/internal/optional-peer.d.ts.map +1 -0
- package/dist/node.js +8 -7
- package/dist/observability/index.js +4 -3
- package/dist/realtime/contract.d.ts +7 -1
- package/dist/realtime/contract.d.ts.map +1 -1
- package/dist/realtime/index.d.ts +2 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/rejected-frame.d.ts +86 -0
- package/dist/realtime/rejected-frame.d.ts.map +1 -0
- package/dist/realtime/request.d.ts +24 -0
- package/dist/realtime/request.d.ts.map +1 -1
- package/dist/realtime/socket.d.ts.map +1 -1
- package/dist/remote.js +4 -2
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +209 -15
- package/dist/server/socket-io.d.ts.map +1 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/streaming-route.d.ts +130 -0
- package/dist/server/streaming-route.d.ts.map +1 -0
- package/dist/testing.js +2 -1
- package/dist/tools.js +11 -9
- package/llms-full.txt +422 -79
- package/package.json +5 -5
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rejection the SENDER can see.
|
|
3
|
+
*
|
|
4
|
+
* A frame that fails the receiver's schema used to be dropped where it landed:
|
|
5
|
+
* the receiving side reported `onRejected` and the sending side learned
|
|
6
|
+
* nothing at all — it waited out its deadline and reported a timeout. For a
|
|
7
|
+
* distributed pair that is the worst diagnostic shape there is. The machines
|
|
8
|
+
* are healthy, the sockets are up, and every request times out in both
|
|
9
|
+
* directions at once, which reads as a network fault rather than as two peers
|
|
10
|
+
* disagreeing about a contract.
|
|
11
|
+
*
|
|
12
|
+
* It also quietly removed the point of putting a protocol generation in the
|
|
13
|
+
* envelope: the check ran, and its answer could not reach the only party able
|
|
14
|
+
* to act on it. There is no deployment order in which two generations coexist
|
|
15
|
+
* if neither can tell the other why it is being refused.
|
|
16
|
+
*
|
|
17
|
+
* So when a refused frame carries an acknowledgement callback — the one
|
|
18
|
+
* back-channel that already exists — the refusal is sent through it. A
|
|
19
|
+
* fire-and-forget event still has nowhere to answer; that boundary is real and
|
|
20
|
+
* is documented rather than papered over.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The reserved key. Namespaced because it travels on the application's own
|
|
24
|
+
* acknowledgement channel: this envelope is delivered INSTEAD of a value the
|
|
25
|
+
* application's `ack` schema would accept, and the sender recognises it before
|
|
26
|
+
* parsing. An application whose acknowledgement is an object carrying this
|
|
27
|
+
* exact key would be ambiguous — hence a key nobody writes by accident.
|
|
28
|
+
*/
|
|
29
|
+
export declare const REALTIME_REJECTION_KEY = "@stitchkit/realtime-rejected";
|
|
30
|
+
/**
|
|
31
|
+
* One field the peer refused, already flattened.
|
|
32
|
+
*
|
|
33
|
+
* `path` is dotted and tuple-aware: the first payload's `v` field is `'0.v'`,
|
|
34
|
+
* because event arguments are a tuple. This is what replaces reading a
|
|
35
|
+
* `ZodError`'s internals on the receiving end — three conditions about somebody
|
|
36
|
+
* else's object shape, for a fact that is binary.
|
|
37
|
+
*/
|
|
38
|
+
export interface RealtimeRejectionIssue {
|
|
39
|
+
path: string;
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* At most this many issues travel; a refusal is a signal, not a report.
|
|
45
|
+
*
|
|
46
|
+
* Applied on BOTH sides. On the reading side it bounds what a peer can make
|
|
47
|
+
* this process hold; on the writing side it bounds what a peer can make this
|
|
48
|
+
* process send — and that one matters more, because the number of issues is
|
|
49
|
+
* chosen by whoever sent the bad frame.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MAX_REJECTION_ISSUES = 20;
|
|
52
|
+
/**
|
|
53
|
+
* What the sender is told: which event, why, and the issues if there were any.
|
|
54
|
+
*
|
|
55
|
+
* `reason` is a union of one today, and deliberately a union: `invalid-arguments`
|
|
56
|
+
* is the only refusal that CAN be answered. An event the receiver's contract
|
|
57
|
+
* does not contain has no listener at all, so there is nothing on that side to
|
|
58
|
+
* answer with; a frame missing its acknowledgement callback has no channel by
|
|
59
|
+
* definition. Both stay reported locally, and both are honest gaps rather than
|
|
60
|
+
* reasons this envelope is never sent.
|
|
61
|
+
*/
|
|
62
|
+
export interface RealtimeRejectionReport {
|
|
63
|
+
event: string;
|
|
64
|
+
/**
|
|
65
|
+
* Why the peer refused it. `invalid-arguments` is what this version sends and
|
|
66
|
+
* the shape a protocol-generation mismatch takes.
|
|
67
|
+
*
|
|
68
|
+
* Typed as a string rather than as a closed union **on the wire**, because a
|
|
69
|
+
* closed union is a mechanism that cannot version itself forward: a peer on a
|
|
70
|
+
* later release refusing for a reason this one has never heard of would fail
|
|
71
|
+
* recognition, fall through to the application's acknowledgement schema, and
|
|
72
|
+
* surface as "the peer answered with something invalid" — the precise
|
|
73
|
+
* mischaracterisation this envelope exists to prevent. An unknown reason is
|
|
74
|
+
* still a refusal, and is reported as one.
|
|
75
|
+
*/
|
|
76
|
+
reason: string;
|
|
77
|
+
message: string;
|
|
78
|
+
issues?: RealtimeRejectionIssue[];
|
|
79
|
+
}
|
|
80
|
+
export interface RealtimeRejectionEnvelope {
|
|
81
|
+
[REALTIME_REJECTION_KEY]: RealtimeRejectionReport;
|
|
82
|
+
}
|
|
83
|
+
export declare function realtimeRejectionEnvelope(report: RealtimeRejectionReport): RealtimeRejectionEnvelope;
|
|
84
|
+
/** Whether an acknowledgement value is a peer's refusal rather than a value. */
|
|
85
|
+
export declare function asRealtimeRejection(value: unknown): RealtimeRejectionReport | null;
|
|
86
|
+
//# sourceMappingURL=rejected-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rejected-frame.d.ts","sourceRoot":"","sources":["../../src/realtime/rejected-frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,yBAAyB;IACxC,CAAC,sBAAsB,CAAC,EAAE,uBAAuB,CAAC;CACnD;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,uBAAuB,GAC9B,yBAAyB,CAE3B;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAgBlF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RealtimeRejectionIssue } from './rejected-frame';
|
|
1
2
|
export interface RealtimeRequestOptions {
|
|
2
3
|
/** Maximum acknowledgement wait in milliseconds. Must be finite and > 0. */
|
|
3
4
|
timeoutMs: number;
|
|
@@ -18,4 +19,27 @@ export declare class RealtimeRequestInvalidAcknowledgementError extends Error {
|
|
|
18
19
|
readonly event: string;
|
|
19
20
|
constructor(event: string, cause: unknown);
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* The peer refused the frame against its own copy of the contract, and said so.
|
|
24
|
+
*
|
|
25
|
+
* Distinct from `RealtimeRequestTimeoutError` on purpose, and that distinction
|
|
26
|
+
* is the whole point: a refusal used to BE a timeout, so a version skew looked
|
|
27
|
+
* exactly like a network fault — symmetrically, on every plane at once. It is
|
|
28
|
+
* also distinct from `RealtimeRequestInvalidAcknowledgementError`, which means
|
|
29
|
+
* the peer answered with something its own contract does not allow; this one
|
|
30
|
+
* means the peer never got as far as answering.
|
|
31
|
+
*/
|
|
32
|
+
export declare class RealtimeRequestRejectedError extends Error {
|
|
33
|
+
readonly code = "REALTIME_REQUEST_REJECTED";
|
|
34
|
+
readonly event: string;
|
|
35
|
+
/**
|
|
36
|
+
* Why the peer refused it. `invalid-arguments` is the version-skew shape and
|
|
37
|
+
* what a peer on this release sends; a later release may name others, so
|
|
38
|
+
* compare rather than exhaustively switch.
|
|
39
|
+
*/
|
|
40
|
+
readonly reason: string;
|
|
41
|
+
/** The fields the peer refused, when it named any — validated on arrival. */
|
|
42
|
+
readonly issues: RealtimeRejectionIssue[] | undefined;
|
|
43
|
+
constructor(event: string, reason: string, detail: string, issues?: RealtimeRejectionIssue[]);
|
|
44
|
+
}
|
|
21
45
|
//# sourceMappingURL=request.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/realtime/request.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAK3C;CACF;AAED,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,mCAAmC;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAIxB;CACF;AAED,qBAAa,0CAA2C,SAAQ,KAAK;IACnE,QAAQ,CAAC,IAAI,8CAA8C;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAIxC;CACF"}
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/realtime/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAK3C;CACF;AAED,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,mCAAmC;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAIxB;CACF;AAED,qBAAa,0CAA2C,SAAQ,KAAK;IACnE,QAAQ,CAAC,IAAI,8CAA8C;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAIxC;CACF;AAED;;;;;;;;;GASG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,sBAAsB,EAAE,GAAG,SAAS,CAAC;IAEtD,YACE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,sBAAsB,EAAE,EAOlC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/realtime/socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/realtime/socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,qBAAqB,EAErB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EAEvB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAapB,UAAU,8BAA8B,CACtC,QAAQ,SAAS,qBAAqB,EACtC,SAAS,SAAS,qBAAqB;IAEvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CAClF;AAED,8FAA8F;AAC9F,eAAO,MAAM,qBAAqB;;;;;;;;;IAOhC,CAAC;AAEH,MAAM,WAAW,uBAAuB,CACtC,QAAQ,SAAS,qBAAqB,EACtC,SAAS,SAAS,qBAAqB;IAEvC,EAAE,CAAC,MAAM,SAAS,MAAM,QAAQ,GAAG,MAAM,EACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAC9C,MAAM,IAAI,CAAC;IACd;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,SAAS,MAAM,SAAS,GAAG,MAAM,EAC1C,KAAK,EAAE,MAAM,EACb,GAAG,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAChD,OAAO,CAAC;CACZ;AA+GD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,qBAAqB,EAC/B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,uBAAuB,EAClC,IAAI,EAAE,OAAO,EAAE,GACd,OAAO,EAAE,CAuBX;AAED,wBAAgB,mCAAmC,CAAC,IAAI,SAAS,CAAC,CAAC,OAAO,EACxE,MAAM,EAAE,IAAI,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,uBAAuB,EAClC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,yBAAyB,GAAG,SAAS,EAC3C,MAAM,EAAE,YAAY,GAAG,SAAS,GAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAqChB;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,CAAC,QAAQ,SAAS,qBAAqB,EAC5C,KAAK,CAAC,SAAS,SAAS,qBAAqB,EAC7C,EACA,MAAM,EACN,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,8BAA8B,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,uBAAuB,CAC9E,QAAQ,EACR,SAAS,CACV,CAwKA"}
|
package/dist/remote.js
CHANGED
|
@@ -4,14 +4,16 @@ import {
|
|
|
4
4
|
} from "./index-svqhcrrj.js";
|
|
5
5
|
import"./index-48ffdxgk.js";
|
|
6
6
|
import {
|
|
7
|
-
AppError,
|
|
8
7
|
mergeMeta
|
|
9
|
-
} from "./index-
|
|
8
|
+
} from "./index-wd8g8z6e.js";
|
|
10
9
|
import"./index-6k1937bx.js";
|
|
11
10
|
import"./index-pzyt11ch.js";
|
|
12
11
|
import {
|
|
13
12
|
isRecord
|
|
14
13
|
} from "./index-smpbdg6k.js";
|
|
14
|
+
import {
|
|
15
|
+
AppError
|
|
16
|
+
} from "./index-xxye8j3k.js";
|
|
15
17
|
|
|
16
18
|
// src/tools/remote.ts
|
|
17
19
|
var HTTP_ONLY = Object.freeze(["HTTP"]);
|
package/dist/server/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export { type ManagedServerHandle, type ShutdownOptions, ShutdownOptionsSchema,
|
|
|
25
25
|
export type { SocketIOHandshakeConfig, SocketIOPeerLoaders, SocketIORequestPolicy, SocketIOServerConfig, SocketIOServerHandle, SocketIOServerLifecycle, } from './socket-io';
|
|
26
26
|
export { createSocketIOServer, socketIoLane } from './socket-io';
|
|
27
27
|
export { type ParseSSEOptions, parseSSE, streamSSE } from './stream';
|
|
28
|
+
export { DEFAULT_STREAM_HEARTBEAT_MS, ndjsonRoute, type StreamingFormat, type StreamingRouteOptions, type StreamingSourceContext, sseRoute, streamingRoute, } from './streaming-route';
|
|
28
29
|
export type { AuthorizationContext, EffectiveScope, EndpointHandlerContext, Handlers, LifecycleHooks, LoggingConfig, LogOutcome, MethodDef, MultipartFileMetadata, MultipartReceiver, MultipartReceiverResult, OperationIdentity, RouteGroup, ScopeContexts, ScopedHandlers, ServiceDef, StitchLogger, StreamingMultipartImplementation, } from './types';
|
|
29
30
|
export { type ComposedLane, composeWebSocketHandlers, type WebSocketComposeConfig, type WebSocketLane, webSocketLane, } from './websocket';
|
|
30
31
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
parseMultipart,
|
|
8
8
|
socketIoLane,
|
|
9
9
|
webSocketLane
|
|
10
|
-
} from "../index-
|
|
10
|
+
} from "../index-s1tywej8.js";
|
|
11
11
|
import {
|
|
12
12
|
composeAuthHooks,
|
|
13
13
|
createAuthHook,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
signJwt,
|
|
21
21
|
verifyJwt,
|
|
22
22
|
verifyPkce
|
|
23
|
-
} from "../index-
|
|
23
|
+
} from "../index-mfw1pec7.js";
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_CORS_ALLOW_HEADERS,
|
|
26
26
|
DEFAULT_CORS_EXPOSE_HEADERS,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
defineMultipartStream,
|
|
35
35
|
implement,
|
|
36
36
|
implementRegistry
|
|
37
|
-
} from "../index-
|
|
37
|
+
} from "../index-y91zd0ch.js";
|
|
38
38
|
import {
|
|
39
39
|
isWithinDir,
|
|
40
40
|
realPathWithinDir
|
|
@@ -65,7 +65,16 @@ import {
|
|
|
65
65
|
resolveSocketIp,
|
|
66
66
|
resolveTraceId,
|
|
67
67
|
zodIssues
|
|
68
|
-
} from "../index-
|
|
68
|
+
} from "../index-tvwcrx2d.js";
|
|
69
|
+
import"../index-wd8g8z6e.js";
|
|
70
|
+
import"../index-6k1937bx.js";
|
|
71
|
+
import {
|
|
72
|
+
joinRoutePath,
|
|
73
|
+
parseTrailingWildcard
|
|
74
|
+
} from "../index-pzyt11ch.js";
|
|
75
|
+
import {
|
|
76
|
+
isRecord
|
|
77
|
+
} from "../index-smpbdg6k.js";
|
|
69
78
|
import {
|
|
70
79
|
AppError,
|
|
71
80
|
STITCH_ERROR_STATUS,
|
|
@@ -77,15 +86,7 @@ import {
|
|
|
77
86
|
notFound,
|
|
78
87
|
rateLimited,
|
|
79
88
|
unauthorized
|
|
80
|
-
} from "../index-
|
|
81
|
-
import"../index-6k1937bx.js";
|
|
82
|
-
import {
|
|
83
|
-
joinRoutePath,
|
|
84
|
-
parseTrailingWildcard
|
|
85
|
-
} from "../index-pzyt11ch.js";
|
|
86
|
-
import {
|
|
87
|
-
isRecord
|
|
88
|
-
} from "../index-smpbdg6k.js";
|
|
89
|
+
} from "../index-xxye8j3k.js";
|
|
89
90
|
// src/server/bun.ts
|
|
90
91
|
import { chmodSync, statSync, unlinkSync } from "node:fs";
|
|
91
92
|
function reclaimStaleUnixSocket(path) {
|
|
@@ -972,9 +973,11 @@ function streamSSE(generator) {
|
|
|
972
973
|
controller.close();
|
|
973
974
|
}
|
|
974
975
|
},
|
|
975
|
-
|
|
976
|
+
cancel() {
|
|
976
977
|
cancelled = true;
|
|
977
|
-
|
|
978
|
+
generator.return(undefined).catch(() => {
|
|
979
|
+
return;
|
|
980
|
+
});
|
|
978
981
|
}
|
|
979
982
|
});
|
|
980
983
|
return new Response(stream, {
|
|
@@ -1018,10 +1021,198 @@ async function* parseSSE(response, options) {
|
|
|
1018
1021
|
reader.releaseLock();
|
|
1019
1022
|
}
|
|
1020
1023
|
}
|
|
1024
|
+
// src/server/streaming-route.ts
|
|
1025
|
+
var DEFAULT_STREAM_HEARTBEAT_MS = 5000;
|
|
1026
|
+
var FRAMINGS = {
|
|
1027
|
+
ndjson: {
|
|
1028
|
+
contentType: "application/x-ndjson",
|
|
1029
|
+
keepAlive: `
|
|
1030
|
+
`,
|
|
1031
|
+
frame: (value) => `${JSON.stringify(value)}
|
|
1032
|
+
`
|
|
1033
|
+
},
|
|
1034
|
+
sse: {
|
|
1035
|
+
contentType: "text/event-stream",
|
|
1036
|
+
keepAlive: `: keep-alive
|
|
1037
|
+
|
|
1038
|
+
`,
|
|
1039
|
+
frame: (value) => `data: ${JSON.stringify(value)}
|
|
1040
|
+
|
|
1041
|
+
`,
|
|
1042
|
+
done: `data: [DONE]
|
|
1043
|
+
|
|
1044
|
+
`
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
function applyIdleTimeout(server, request, seconds) {
|
|
1048
|
+
if (typeof server !== "object" || server === null)
|
|
1049
|
+
return;
|
|
1050
|
+
const timeout = Reflect.get(server, "timeout");
|
|
1051
|
+
if (typeof timeout !== "function")
|
|
1052
|
+
return;
|
|
1053
|
+
try {
|
|
1054
|
+
Reflect.apply(timeout, server, [request, seconds]);
|
|
1055
|
+
} catch {}
|
|
1056
|
+
}
|
|
1057
|
+
function unrefTimer(timer) {
|
|
1058
|
+
if (typeof timer !== "object" || timer === null)
|
|
1059
|
+
return;
|
|
1060
|
+
const unref = Reflect.get(timer, "unref");
|
|
1061
|
+
if (typeof unref === "function")
|
|
1062
|
+
Reflect.apply(unref, timer, []);
|
|
1063
|
+
}
|
|
1064
|
+
var MAX_BUFFERED_FRAMES = 16;
|
|
1065
|
+
function responseHeaders(framing, extra) {
|
|
1066
|
+
const headers = new Headers(extra);
|
|
1067
|
+
headers.set("Content-Type", framing.contentType);
|
|
1068
|
+
headers.set("Cache-Control", "no-cache");
|
|
1069
|
+
headers.set("Connection", "keep-alive");
|
|
1070
|
+
headers.set("X-Accel-Buffering", "no");
|
|
1071
|
+
return headers;
|
|
1072
|
+
}
|
|
1073
|
+
function streamingRoute(options) {
|
|
1074
|
+
const heartbeatMs = options.heartbeatMs ?? DEFAULT_STREAM_HEARTBEAT_MS;
|
|
1075
|
+
if (!Number.isFinite(heartbeatMs) || heartbeatMs <= 0) {
|
|
1076
|
+
throw new TypeError("heartbeatMs must be a finite positive number of milliseconds");
|
|
1077
|
+
}
|
|
1078
|
+
const idleTimeoutSeconds = options.idleTimeoutSeconds ?? 0;
|
|
1079
|
+
if (!Number.isInteger(idleTimeoutSeconds) || idleTimeoutSeconds < 0) {
|
|
1080
|
+
throw new TypeError("idleTimeoutSeconds must be a non-negative integer");
|
|
1081
|
+
}
|
|
1082
|
+
const framing = FRAMINGS[options.format ?? "ndjson"];
|
|
1083
|
+
return {
|
|
1084
|
+
method: options.method ?? "GET",
|
|
1085
|
+
path: options.path,
|
|
1086
|
+
handler: async (request, context) => {
|
|
1087
|
+
applyIdleTimeout(context.server, request, idleTimeoutSeconds);
|
|
1088
|
+
const departed = new AbortController;
|
|
1089
|
+
const iterable = await options.source(request, { ...context, signal: departed.signal });
|
|
1090
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
1091
|
+
const encoder = new TextEncoder;
|
|
1092
|
+
let heartbeat = null;
|
|
1093
|
+
let closed = false;
|
|
1094
|
+
const stopHeartbeat = () => {
|
|
1095
|
+
if (heartbeat === null)
|
|
1096
|
+
return;
|
|
1097
|
+
clearInterval(heartbeat);
|
|
1098
|
+
heartbeat = null;
|
|
1099
|
+
};
|
|
1100
|
+
const release = () => {
|
|
1101
|
+
if (closed)
|
|
1102
|
+
return;
|
|
1103
|
+
closed = true;
|
|
1104
|
+
try {
|
|
1105
|
+
stopHeartbeat();
|
|
1106
|
+
signalDemand();
|
|
1107
|
+
departed.abort();
|
|
1108
|
+
Promise.resolve(iterator.return?.(undefined)).catch(() => {
|
|
1109
|
+
return;
|
|
1110
|
+
});
|
|
1111
|
+
} catch {}
|
|
1112
|
+
};
|
|
1113
|
+
let demand = null;
|
|
1114
|
+
const signalDemand = () => {
|
|
1115
|
+
const resolve2 = demand;
|
|
1116
|
+
demand = null;
|
|
1117
|
+
resolve2?.();
|
|
1118
|
+
};
|
|
1119
|
+
const stream = new ReadableStream({
|
|
1120
|
+
start(controller) {
|
|
1121
|
+
const send = (text) => {
|
|
1122
|
+
if (closed)
|
|
1123
|
+
return false;
|
|
1124
|
+
try {
|
|
1125
|
+
controller.enqueue(encoder.encode(text));
|
|
1126
|
+
return true;
|
|
1127
|
+
} catch {
|
|
1128
|
+
release();
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
};
|
|
1132
|
+
const finish = () => {
|
|
1133
|
+
try {
|
|
1134
|
+
controller.close();
|
|
1135
|
+
} catch {}
|
|
1136
|
+
};
|
|
1137
|
+
if (request.signal.aborted) {
|
|
1138
|
+
release();
|
|
1139
|
+
finish();
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
request.signal.addEventListener("abort", () => {
|
|
1143
|
+
release();
|
|
1144
|
+
finish();
|
|
1145
|
+
});
|
|
1146
|
+
send(framing.keepAlive);
|
|
1147
|
+
heartbeat = setInterval(() => {
|
|
1148
|
+
if ((controller.desiredSize ?? 1) > 0)
|
|
1149
|
+
send(framing.keepAlive);
|
|
1150
|
+
}, heartbeatMs);
|
|
1151
|
+
unrefTimer(heartbeat);
|
|
1152
|
+
const awaitDemand = async () => {
|
|
1153
|
+
while (!closed && (controller.desiredSize ?? 1) <= 0) {
|
|
1154
|
+
await new Promise((resolve2) => {
|
|
1155
|
+
demand = resolve2;
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
let sinceYield = 0;
|
|
1160
|
+
(async () => {
|
|
1161
|
+
try {
|
|
1162
|
+
for (;; ) {
|
|
1163
|
+
await awaitDemand();
|
|
1164
|
+
if (closed)
|
|
1165
|
+
return;
|
|
1166
|
+
const next = await iterator.next();
|
|
1167
|
+
if (closed)
|
|
1168
|
+
return;
|
|
1169
|
+
if (next.done)
|
|
1170
|
+
break;
|
|
1171
|
+
if (!send(framing.frame(next.value)))
|
|
1172
|
+
return;
|
|
1173
|
+
sinceYield += 1;
|
|
1174
|
+
if (sinceYield >= MAX_BUFFERED_FRAMES) {
|
|
1175
|
+
sinceYield = 0;
|
|
1176
|
+
await new Promise((resolve2) => {
|
|
1177
|
+
setTimeout(resolve2, 0);
|
|
1178
|
+
});
|
|
1179
|
+
if (closed)
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
if (framing.done)
|
|
1184
|
+
send(framing.done);
|
|
1185
|
+
} catch (error) {
|
|
1186
|
+
if (!closed)
|
|
1187
|
+
send(framing.frame(normalizeError(error).toJSON()));
|
|
1188
|
+
} finally {
|
|
1189
|
+
release();
|
|
1190
|
+
finish();
|
|
1191
|
+
}
|
|
1192
|
+
})();
|
|
1193
|
+
},
|
|
1194
|
+
pull() {
|
|
1195
|
+
signalDemand();
|
|
1196
|
+
},
|
|
1197
|
+
cancel() {
|
|
1198
|
+
release();
|
|
1199
|
+
}
|
|
1200
|
+
}, { highWaterMark: MAX_BUFFERED_FRAMES });
|
|
1201
|
+
return new Response(stream, { headers: responseHeaders(framing, options.headers) });
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
function ndjsonRoute(options) {
|
|
1206
|
+
return streamingRoute({ ...options, format: "ndjson" });
|
|
1207
|
+
}
|
|
1208
|
+
function sseRoute(options) {
|
|
1209
|
+
return streamingRoute({ ...options, format: "sse" });
|
|
1210
|
+
}
|
|
1021
1211
|
export {
|
|
1022
1212
|
AppError,
|
|
1023
1213
|
DEFAULT_CORS_ALLOW_HEADERS,
|
|
1024
1214
|
DEFAULT_CORS_EXPOSE_HEADERS,
|
|
1215
|
+
DEFAULT_STREAM_HEARTBEAT_MS,
|
|
1025
1216
|
STITCH_ERROR_STATUS,
|
|
1026
1217
|
ShutdownOptionsSchema,
|
|
1027
1218
|
ShutdownResultSchema,
|
|
@@ -1068,6 +1259,7 @@ export {
|
|
|
1068
1259
|
implementRegistry,
|
|
1069
1260
|
isStitchErrorCode,
|
|
1070
1261
|
isWithinDir,
|
|
1262
|
+
ndjsonRoute,
|
|
1071
1263
|
normalizeError,
|
|
1072
1264
|
notFound,
|
|
1073
1265
|
openApiRoute,
|
|
@@ -1084,8 +1276,10 @@ export {
|
|
|
1084
1276
|
serveFile,
|
|
1085
1277
|
signJwt,
|
|
1086
1278
|
socketIoLane,
|
|
1279
|
+
sseRoute,
|
|
1087
1280
|
staticRoute,
|
|
1088
1281
|
streamSSE,
|
|
1282
|
+
streamingRoute,
|
|
1089
1283
|
unauthorized,
|
|
1090
1284
|
verifyJwt,
|
|
1091
1285
|
verifyPkce,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/server/socket-io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EACV,MAAM,IAAI,SAAS,EAEpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,gBAAgB,EAChB,MAAM,IAAI,cAAc,EAGzB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/server/socket-io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EACV,MAAM,IAAI,SAAS,EAEpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,gBAAgB,EAChB,MAAM,IAAI,cAAc,EAGzB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAA2B,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAc/D,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACzD;;;;;OAKG;IACH,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,aAAa,IAAI,IAAI,CAAC;IACtB,8EAA8E;IAC9E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sEAAsE;IACtE,WAAW,IAAI,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB,CACnC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc,EACpC,KAAK,GAAG,GAAG,CACX,SAAQ,uBAAuB;IAC/B,+EAA+E;IAC/E,EAAE,EAAE,cAAc,CAAC,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;CAC3E;AA8HD,wBAAsB,oBAAoB,CACxC,aAAa,SAAS,cAAc,EACpC,aAAa,SAAS,cAAc,EAKpC,OAAO,GAAG,GAAG,EACb,KAAK,GAAG,OAAO,EAEf,MAAM,EAAE,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,GAC3C,OAAO,CAAC,oBAAoB,CAAC,aAAa,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,CAmKpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,oBAAoB,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,WAAW,CAAC,GAC3E,YAAY,CAMd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/server/stream.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CA2CtE;AAED,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAuB,QAAQ,CAAC,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,cAAc,CAAC,CAAC,CAAC,CAmCnB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A long-lived response, with the three things everyone has to remember.
|
|
3
|
+
*
|
|
4
|
+
* `RawRoute` + `ctx.server` already gave every capability needed to serve a
|
|
5
|
+
* continuing NDJSON or SSE body. The problem was never capability — it was that
|
|
6
|
+
* the author of each such route had to independently remember three unrelated
|
|
7
|
+
* things, and forgetting any one of them breaks the stream **silently**:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Clear the generic HTTP idle timeout.** Without `server.timeout(req, 0)`
|
|
10
|
+
* Bun resets the connection after ten seconds. For a stream whose normal
|
|
11
|
+
* state is silence — a subscription to a rare event, the log of an idle
|
|
12
|
+
* process — that is a healthy connection being severed on a schedule.
|
|
13
|
+
* 2. **Send a heartbeat.** Even with the timeout cleared, intermediate proxies
|
|
14
|
+
* and client stacks are under no obligation to hold a connection carrying no
|
|
15
|
+
* bytes.
|
|
16
|
+
* 3. **Flush the headers at open.** A runtime does not send the response until
|
|
17
|
+
* the body produces something, so the consumer's `fetch` does not return
|
|
18
|
+
* until the first frame. On a quiet stream "subscribed and silent" becomes
|
|
19
|
+
* indistinguishable from "not answering" — and there is nothing to inspect,
|
|
20
|
+
* because there is no response yet.
|
|
21
|
+
*
|
|
22
|
+
* Each is obvious alone. Together they are a checklist that lived in the head
|
|
23
|
+
* of whoever wrote the route rather than in the types — and a route written
|
|
24
|
+
* later, doing the same job for another plane, got none of the three. Reviews
|
|
25
|
+
* did not catch it and neither did the tests, because every test published an
|
|
26
|
+
* event immediately and never lived long enough to reach the threshold. The
|
|
27
|
+
* shape of the defect is the point: not "done wrong", but "done incompletely,
|
|
28
|
+
* and the incompleteness is invisible".
|
|
29
|
+
*
|
|
30
|
+
* They are not independent, and the measurement is worth keeping: with a
|
|
31
|
+
* heartbeat under the threshold, point 1 does not change the outcome in
|
|
32
|
+
* process — either measure alone kept a connection alive through twelve
|
|
33
|
+
* seconds of silence, and only dropping both killed it. Point 1 earns its place
|
|
34
|
+
* against what a heartbeat cannot reach: a proxy or a client stack applying its
|
|
35
|
+
* own idle rule. Points 2 and 3 are each load-bearing on their own.
|
|
36
|
+
*
|
|
37
|
+
* A fourth thing is handled here that is easy to not even think of:
|
|
38
|
+
* **cancellation reaches the source.** When the consumer goes away, the async
|
|
39
|
+
* iterable is returned, so a departed subscriber does not leave live work
|
|
40
|
+
* running on the server.
|
|
41
|
+
*/
|
|
42
|
+
import type { HttpMethod } from '../contract/define';
|
|
43
|
+
import type { RawRoute, RawRouteContext } from './types';
|
|
44
|
+
/** How a value becomes bytes on the wire. The only thing the two formats differ in. */
|
|
45
|
+
export type StreamingFormat = 'ndjson' | 'sse';
|
|
46
|
+
/**
|
|
47
|
+
* Default heartbeat, deliberately well under Bun's ten-second idle threshold.
|
|
48
|
+
*
|
|
49
|
+
* A default at or near the threshold does not protect anything: the first
|
|
50
|
+
* pulse would arrive at about the moment the connection was already being
|
|
51
|
+
* dropped, so the option would look configured and do nothing.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_STREAM_HEARTBEAT_MS = 5000;
|
|
54
|
+
export interface StreamingRouteOptions<TServer = unknown> {
|
|
55
|
+
path: string;
|
|
56
|
+
/** Default `GET` — a subscription is a read. */
|
|
57
|
+
method?: HttpMethod | 'ALL';
|
|
58
|
+
/** Wire framing. Default `ndjson`. */
|
|
59
|
+
format?: StreamingFormat;
|
|
60
|
+
/**
|
|
61
|
+
* Interval between keep-alive frames while the source is silent. Default
|
|
62
|
+
* `DEFAULT_STREAM_HEARTBEAT_MS`. Must be finite and positive.
|
|
63
|
+
*/
|
|
64
|
+
heartbeatMs?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Per-request idle timeout in **seconds**, applied through the runtime's own
|
|
67
|
+
* per-request control where it has one (Bun). Default `0` — no timeout.
|
|
68
|
+
*
|
|
69
|
+
* Zero by default and not by accident. The generic timeout exists to reap
|
|
70
|
+
* connections whose peer has gone quiet, and a stream whose normal state is
|
|
71
|
+
* silence is the one case where that inference is wrong — which is the reason
|
|
72
|
+
* this primitive is being reached for at all. It is still a field, because
|
|
73
|
+
* removing a general limit is a decision worth being able to see and to
|
|
74
|
+
* override.
|
|
75
|
+
*/
|
|
76
|
+
idleTimeoutSeconds?: number;
|
|
77
|
+
/**
|
|
78
|
+
* The frames. Returned as an async iterable so a generator is the natural
|
|
79
|
+
* way to write one.
|
|
80
|
+
*
|
|
81
|
+
* **A source that waits must honour `context.signal`.** See
|
|
82
|
+
* `StreamingSourceContext` — this is the one part of cancellation the
|
|
83
|
+
* primitive cannot do on the source's behalf.
|
|
84
|
+
*/
|
|
85
|
+
source: (request: Request, context: StreamingSourceContext<TServer>) => AsyncIterable<unknown> | Promise<AsyncIterable<unknown>>;
|
|
86
|
+
/** Extra response headers. The framing headers below cannot be overridden. */
|
|
87
|
+
headers?: Record<string, string>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* What a source is given, and the reason the signal is not optional.
|
|
91
|
+
*
|
|
92
|
+
* Closing an async iterator is not enough to stop a source, and the mechanism
|
|
93
|
+
* is worth stating because the failure is silent. An async generator serialises
|
|
94
|
+
* its requests: `return()` issued while a `next()` is still in flight is
|
|
95
|
+
* QUEUED behind it. A subscription source's `next()` is in flight almost all
|
|
96
|
+
* the time — that is what a subscription is — so the return is queued behind a
|
|
97
|
+
* promise that will only settle when the next event arrives, which for a quiet
|
|
98
|
+
* plane may be never. `iterator.return()` is still called, because it does
|
|
99
|
+
* close a source suspended at a `yield`; it simply cannot interrupt one that is
|
|
100
|
+
* waiting.
|
|
101
|
+
*
|
|
102
|
+
* The signal is what can. It is aborted the moment the consumer goes away —
|
|
103
|
+
* through either route, a request abort or a stream cancel, which are not the
|
|
104
|
+
* same event — and a source that awaits on it stops immediately:
|
|
105
|
+
*
|
|
106
|
+
* ```ts
|
|
107
|
+
* ndjsonRoute({
|
|
108
|
+
* path: '/events/subscribe',
|
|
109
|
+
* source: async function* (request, { signal }) {
|
|
110
|
+
* for await (const event of subscribe({ signal })) yield event
|
|
111
|
+
* },
|
|
112
|
+
* })
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export interface StreamingSourceContext<TServer = unknown> extends RawRouteContext<TServer> {
|
|
116
|
+
/** Aborted when the consumer goes away. A waiting source must honour it. */
|
|
117
|
+
signal: AbortSignal;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A `RawRoute` serving a continuing body.
|
|
121
|
+
*
|
|
122
|
+
* @see ndjsonRoute
|
|
123
|
+
* @see sseRoute
|
|
124
|
+
*/
|
|
125
|
+
export declare function streamingRoute<TServer = unknown>(options: StreamingRouteOptions<TServer>): RawRoute<TServer>;
|
|
126
|
+
/** A `streamingRoute` framed as newline-delimited JSON. Keep-alive is a blank line. */
|
|
127
|
+
export declare function ndjsonRoute<TServer = unknown>(options: Omit<StreamingRouteOptions<TServer>, 'format'>): RawRoute<TServer>;
|
|
128
|
+
/** A `streamingRoute` framed as Server-Sent Events — readable by `parseSSE`. */
|
|
129
|
+
export declare function sseRoute<TServer = unknown>(options: Omit<StreamingRouteOptions<TServer>, 'format'>): RawRoute<TServer>;
|
|
130
|
+
//# sourceMappingURL=streaming-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-route.d.ts","sourceRoot":"","sources":["../../src/server/streaming-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEzD,uFAAuF;AACvF,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD,MAAM,WAAW,qBAAqB,CAAC,OAAO,GAAG,OAAO;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;IAC5B,sCAAsC;IACtC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,MAAM,EAAE,CACN,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,sBAAsB,CAAC,OAAO,CAAC,KACrC,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,sBAAsB,CAAC,OAAO,GAAG,OAAO,CAAE,SAAQ,eAAe,CAAC,OAAO,CAAC;IACzF,4EAA4E;IAC5E,MAAM,EAAE,WAAW,CAAC;CACrB;AAiGD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAG,OAAO,EAC9C,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACtC,QAAQ,CAAC,OAAO,CAAC,CAgNnB;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,OAAO,GAAG,OAAO,EAC3C,OAAO,EAAE,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,GACtD,QAAQ,CAAC,OAAO,CAAC,CAEnB;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,OAAO,GAAG,OAAO,EACxC,OAAO,EAAE,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,GACtD,QAAQ,CAAC,OAAO,CAAC,CAEnB"}
|
package/dist/testing.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./index-vtjgx3vv.js";
|
|
5
5
|
import {
|
|
6
6
|
createApplication
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-eabpd4tb.js";
|
|
8
8
|
import"./index-8eywc9zv.js";
|
|
9
9
|
import {
|
|
10
10
|
RealtimeRequestDisconnectedError,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
isRecord
|
|
34
34
|
} from "./index-smpbdg6k.js";
|
|
35
|
+
import"./index-xxye8j3k.js";
|
|
35
36
|
|
|
36
37
|
// src/agent-runtime/testing.ts
|
|
37
38
|
function createAgentRaceBarrier(timeoutMs = 5000) {
|