@pellux/goodvibes-daemon-sdk 1.9.0 → 1.10.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/dist/gateway-rest-routes.d.ts.map +1 -1
- package/dist/gateway-rest-routes.js +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/relay-registration.d.ts +39 -0
- package/dist/relay-registration.d.ts.map +1 -1
- package/dist/relay-registration.js +144 -10
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-rest-routes.d.ts","sourceRoot":"","sources":["../src/gateway-rest-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAYD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,
|
|
1
|
+
{"version":3,"file":"gateway-rest-routes.d.ts","sourceRoot":"","sources":["../src/gateway-rest-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAYD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,gBAAgB,EA0E1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,8BAA8B,CAAC,GAChD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAe1B"}
|
|
@@ -80,6 +80,12 @@ export const GATEWAY_REST_ROUTES = [
|
|
|
80
80
|
// power.* — sleep ownership: the chip state + the owner keep-awake toggle.
|
|
81
81
|
route('GET', '/api/power/status', 'power.status.get'),
|
|
82
82
|
route('POST', '/api/power/keep-awake', 'power.keepAwake.set'),
|
|
83
|
+
// ops.memory.get — the MemoryGovernor snapshot (tier, budget, RSS/heap,
|
|
84
|
+
// per-cache footprints, paused jobs, tripwire state).
|
|
85
|
+
route('GET', '/api/ops/memory', 'ops.memory.get'),
|
|
86
|
+
// voice.local.* — managed local-voice runtime status + one-act install.
|
|
87
|
+
route('GET', '/api/voice/local/status', 'voice.local.status'),
|
|
88
|
+
route('POST', '/api/voice/local/install', 'voice.local.install'),
|
|
83
89
|
];
|
|
84
90
|
/**
|
|
85
91
|
* Dispatch a request against the gateway REST route table.
|
package/dist/index.d.ts
CHANGED
|
@@ -43,5 +43,5 @@ export type { RelayServerSocket, RelayServerLogger, RelayServerLimits, } from '.
|
|
|
43
43
|
export { createBunRelayServer } from './relay-server-entry.js';
|
|
44
44
|
export type { BunRelayServerOptions } from './relay-server-entry.js';
|
|
45
45
|
export { createRelayDaemonRegistration, RELAY_VIA_HEADER, isRelayTunneledRequest } from './relay-registration.js';
|
|
46
|
-
export type { RelayDaemonRegistration, RelayDaemonRegistrationOptions, RelayRegistrationStatus, RelayRegistrationLogger, RelayClientWebSocket, } from './relay-registration.js';
|
|
46
|
+
export type { RelayDaemonRegistration, RelayDaemonRegistrationOptions, RelayRegistrationStats, RelayRegistrationStatus, RelayRegistrationLogger, RelayClientWebSocket, } from './relay-registration.js';
|
|
47
47
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,iCAAiC,EACjC,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,EAC9B,yBAAyB,EACzB,mCAAmC,EACnC,4BAA4B,EAC5B,sCAAsC,EACtC,wBAAwB,EACxB,iCAAiC,EACjC,oCAAoC,EACpC,0BAA0B,EAC1B,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACnL,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,QAAQ,EACR,UAAU,EACV,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,8BAA8B,EAC9B,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,cAAc,EACd,4BAA4B,EAC5B,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,6BAA6B,EAC7B,uBAAuB,EACvB,kCAAkC,EAClC,kBAAkB,IAAI,wBAAwB,EAC9C,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,IAAI,6BAA6B,EAClD,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EACxB,qCAAqC,EACrC,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,EAC3B,qBAAqB,EACrB,6BAA6B,EAC7B,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,kCAAkC,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,4CAA4C,EAAE,MAAM,kCAAkC,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AACnE,YAAY,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACvG,OAAO,EAAE,0CAA0C,EAAE,MAAM,gCAAgC,CAAC;AAC5F,OAAO,EAAE,uCAAuC,EAAE,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACzG,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EACL,QAAQ,EACR,eAAe,EACf,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAClH,YAAY,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,9 +43,46 @@ export interface RelayDaemonRegistrationOptions {
|
|
|
43
43
|
readonly maxStreamsPerPipe?: number;
|
|
44
44
|
/** Bounded per-stream send buffer, in chunks; overflow drops-with-notice (default 256). */
|
|
45
45
|
readonly streamBufferChunks?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Max simultaneously-open secure-channel pipes retained in memory (default
|
|
48
|
+
* 512). Each pipe holds a live secure channel derived from the connecting
|
|
49
|
+
* surface's session; a relay that drops pipes WITHOUT sending a pipe-close
|
|
50
|
+
* control frame (crash, network partition) would otherwise leave the channel
|
|
51
|
+
* context — and the operator-token-authenticated requests riding it — pinned
|
|
52
|
+
* forever. When the cap is hit the least-recently-used pipe is evicted (its
|
|
53
|
+
* streams closed) so retained-context count stays bounded.
|
|
54
|
+
*/
|
|
55
|
+
readonly maxPipes?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Max concurrently in-flight tunneled REQUESTS across all pipes (default
|
|
58
|
+
* 1024). Each in-flight request retains its reconstructed Request — headers
|
|
59
|
+
* (including the operator-token Authorization header) and any buffered body —
|
|
60
|
+
* for the FULL lifetime: dispatch AND response buffering (the max-memory
|
|
61
|
+
* phase). When the cap is hit a new request is refused with
|
|
62
|
+
* an honest 503 `relay-overloaded` response instead of being retained, so a
|
|
63
|
+
* dispatch stall (or a hot job-transition loop fanning requests) can never
|
|
64
|
+
* accumulate request contexts without limit.
|
|
65
|
+
*/
|
|
66
|
+
readonly maxInFlightRequests?: number;
|
|
46
67
|
readonly logger?: RelayRegistrationLogger;
|
|
47
68
|
readonly onStatusChange?: (status: RelayRegistrationStatus) => void;
|
|
48
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Point-in-time footprint of the retained relay contexts. Exposed so ops
|
|
72
|
+
* surfaces and regression tests can assert the caps hold under load.
|
|
73
|
+
*/
|
|
74
|
+
export interface RelayRegistrationStats {
|
|
75
|
+
/** Open secure-channel pipes currently retained. */
|
|
76
|
+
readonly pipes: number;
|
|
77
|
+
/** Tunneled requests currently mid-dispatch (contexts still retained). */
|
|
78
|
+
readonly inFlightRequests: number;
|
|
79
|
+
/** Live event-subscription streams currently retained across all pipes. */
|
|
80
|
+
readonly streams: number;
|
|
81
|
+
/** Pipes evicted because the maxPipes cap was exceeded (cumulative). */
|
|
82
|
+
readonly droppedPipes: number;
|
|
83
|
+
/** Requests refused because the maxInFlightRequests cap was exceeded (cumulative). */
|
|
84
|
+
readonly droppedRequests: number;
|
|
85
|
+
}
|
|
49
86
|
/** A running daemon-side relay registration. */
|
|
50
87
|
export interface RelayDaemonRegistration {
|
|
51
88
|
start(): void;
|
|
@@ -53,6 +90,8 @@ export interface RelayDaemonRegistration {
|
|
|
53
90
|
readonly status: RelayRegistrationStatus;
|
|
54
91
|
/** Mint a pairing payload a surface can scan to reach this daemon. */
|
|
55
92
|
mintPairing(label?: string): Promise<RelayPairingPayload>;
|
|
93
|
+
/** Retained-context footprint, for ops visibility and cap regression tests. */
|
|
94
|
+
stats(): RelayRegistrationStats;
|
|
56
95
|
}
|
|
57
96
|
export declare function createRelayDaemonRegistration(options: RelayDaemonRegistrationOptions): RelayDaemonRegistration;
|
|
58
97
|
//# sourceMappingURL=relay-registration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-registration.d.ts","sourceRoot":"","sources":["../src/relay-registration.ts"],"names":[],"mappings":"AAaA,OAAO,EAeL,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACzB,MAAM,wCAAwC,CAAC;AAEhD,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;CAC1G;AAED,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED,2DAA2D;AAC3D,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;AAExG,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChE;AAED,yDAAyD;AACzD,MAAM,WAAW,8BAA8B;IAC7C,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9D,yEAAyE;IACzE,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,oBAAoB,CAAC;IAC/D,wDAAwD;IACxD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,mDAAmD;IACnD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,sEAAsE;IACtE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,2FAA2F;IAC3F,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACrE;AAED,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,sEAAsE;IACtE,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-registration.d.ts","sourceRoot":"","sources":["../src/relay-registration.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,6 +37,39 @@ function toBytes(data) {
|
|
|
37
37
|
}
|
|
38
38
|
const DEFAULT_MAX_STREAMS_PER_PIPE = 8;
|
|
39
39
|
const DEFAULT_STREAM_BUFFER_CHUNKS = 256;
|
|
40
|
+
const DEFAULT_MAX_PIPES = 512;
|
|
41
|
+
const DEFAULT_MAX_IN_FLIGHT_REQUESTS = 1024;
|
|
42
|
+
/** Ceiling on one tunneled response body; larger (or endless) bodies are refused with 502. */
|
|
43
|
+
const MAX_TUNNEL_RESPONSE_BYTES = 32 * 1024 * 1024;
|
|
44
|
+
/** Read a response body with a hard byte ceiling; over-ceiling reads are cancelled and refused. */
|
|
45
|
+
async function readTunnelBodyBounded(response, maxBytes) {
|
|
46
|
+
const body = response.body;
|
|
47
|
+
if (!body)
|
|
48
|
+
return { ok: true, bytes: new Uint8Array(0) };
|
|
49
|
+
const reader = body.getReader();
|
|
50
|
+
const chunks = [];
|
|
51
|
+
let total = 0;
|
|
52
|
+
for (;;) {
|
|
53
|
+
const { done, value } = await reader.read();
|
|
54
|
+
if (done)
|
|
55
|
+
break;
|
|
56
|
+
if (value) {
|
|
57
|
+
total += value.byteLength;
|
|
58
|
+
if (total > maxBytes) {
|
|
59
|
+
await reader.cancel().catch(() => { });
|
|
60
|
+
return { ok: false };
|
|
61
|
+
}
|
|
62
|
+
chunks.push(value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const merged = new Uint8Array(total);
|
|
66
|
+
let offset = 0;
|
|
67
|
+
for (const chunk of chunks) {
|
|
68
|
+
merged.set(chunk, offset);
|
|
69
|
+
offset += chunk.byteLength;
|
|
70
|
+
}
|
|
71
|
+
return { ok: true, bytes: merged };
|
|
72
|
+
}
|
|
40
73
|
/**
|
|
41
74
|
* The daemon-side pump for one event subscription: it seals event-source chunks
|
|
42
75
|
* into `stream-data` frames and writes them to the relay socket, applying a
|
|
@@ -122,14 +155,57 @@ export function createRelayDaemonRegistration(options) {
|
|
|
122
155
|
const maxDelay = options.reconnectMaxDelayMs ?? 30_000;
|
|
123
156
|
const maxStreamsPerPipe = options.maxStreamsPerPipe ?? DEFAULT_MAX_STREAMS_PER_PIPE;
|
|
124
157
|
const streamBufferChunks = options.streamBufferChunks ?? DEFAULT_STREAM_BUFFER_CHUNKS;
|
|
158
|
+
const maxPipes = Math.max(1, Math.trunc(options.maxPipes ?? DEFAULT_MAX_PIPES));
|
|
159
|
+
const maxInFlightRequests = Math.max(1, Math.trunc(options.maxInFlightRequests ?? DEFAULT_MAX_IN_FLIGHT_REQUESTS));
|
|
125
160
|
let status = 'idle';
|
|
126
161
|
let socket = null;
|
|
127
162
|
let stopped = false;
|
|
128
163
|
let attempt = 0;
|
|
129
164
|
let reconnectTimer = null;
|
|
165
|
+
let inFlightRequests = 0;
|
|
166
|
+
let droppedPipes = 0;
|
|
167
|
+
let droppedRequests = 0;
|
|
168
|
+
// Secure channels keyed by pipe. Map insertion order is the LRU order used
|
|
169
|
+
// to evict the coldest pipe when the maxPipes cap is exceeded; a served frame
|
|
170
|
+
// re-inserts its pipe so active pipes stay warm (see touchPipe).
|
|
130
171
|
const channels = new Map();
|
|
131
172
|
// Per-pipe live event subscriptions: pipeKey -> (streamId -> record).
|
|
132
173
|
const pipeStreams = new Map();
|
|
174
|
+
function countStreams() {
|
|
175
|
+
let total = 0;
|
|
176
|
+
for (const streams of pipeStreams.values())
|
|
177
|
+
total += streams.size;
|
|
178
|
+
return total;
|
|
179
|
+
}
|
|
180
|
+
/** Move a pipe to the warm (most-recent) end of the LRU order. */
|
|
181
|
+
function touchPipe(pipeKey) {
|
|
182
|
+
const channel = channels.get(pipeKey);
|
|
183
|
+
if (!channel)
|
|
184
|
+
return;
|
|
185
|
+
channels.delete(pipeKey);
|
|
186
|
+
channels.set(pipeKey, channel);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Enforce the maxPipes cap by evicting the least-recently-used pipe(s). Each
|
|
190
|
+
* eviction closes the pipe's streams and drops its channel, releasing the
|
|
191
|
+
* retained request/session context with a structured, counted log line —
|
|
192
|
+
* never a silent leak.
|
|
193
|
+
*/
|
|
194
|
+
function enforcePipeCap() {
|
|
195
|
+
while (channels.size > maxPipes) {
|
|
196
|
+
const oldest = channels.keys().next().value;
|
|
197
|
+
if (oldest === undefined)
|
|
198
|
+
break;
|
|
199
|
+
channels.delete(oldest);
|
|
200
|
+
closePipeStreams(oldest);
|
|
201
|
+
droppedPipes += 1;
|
|
202
|
+
logger.warn('relay pipe cap exceeded — evicted coldest pipe', {
|
|
203
|
+
maxPipes,
|
|
204
|
+
droppedPipes,
|
|
205
|
+
pipe: oldest,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
133
209
|
function closePipeStreams(pipeKey) {
|
|
134
210
|
const streams = pipeStreams.get(pipeKey);
|
|
135
211
|
if (!streams)
|
|
@@ -159,9 +235,11 @@ export function createRelayDaemonRegistration(options) {
|
|
|
159
235
|
// First frame on a new pipe is the client's handshake initiation.
|
|
160
236
|
const { keys, message2 } = await respondToHandshake(options.identity, ridBytes, payload);
|
|
161
237
|
channels.set(pipeKey, new RelaySecureChannel(keys, 'daemon'));
|
|
238
|
+
enforcePipeCap();
|
|
162
239
|
ws.send(framePipePayload(pipeIdBytes, message2));
|
|
163
240
|
return;
|
|
164
241
|
}
|
|
242
|
+
touchPipe(pipeKey);
|
|
165
243
|
await serveTunneledFrame(pipeKey, existing, pipeIdBytes, payload, ws);
|
|
166
244
|
}
|
|
167
245
|
async function serveTunneledFrame(pipeKey, channel, pipeIdBytes, sealed, ws) {
|
|
@@ -185,24 +263,71 @@ export function createRelayDaemonRegistration(options) {
|
|
|
185
263
|
// only; a surface should never send them. Ignore rather than trust.
|
|
186
264
|
}
|
|
187
265
|
async function serveTunneledRequest(header, body, channel, pipeIdBytes, ws) {
|
|
266
|
+
// In-flight request cap: refuse (don't retain) when saturated. Each in-flight
|
|
267
|
+
// request pins its reconstructed Request — headers carry the operator-token
|
|
268
|
+
// Authorization header — until dispatch resolves, so an unbounded backlog is
|
|
269
|
+
// exactly the retained-context leak this guard prevents. The refusal is an
|
|
270
|
+
// honest structured 503 the surface can surface and retry.
|
|
271
|
+
if (inFlightRequests >= maxInFlightRequests) {
|
|
272
|
+
droppedRequests += 1;
|
|
273
|
+
logger.warn('relay in-flight request cap exceeded — refused', {
|
|
274
|
+
maxInFlightRequests,
|
|
275
|
+
droppedRequests,
|
|
276
|
+
});
|
|
277
|
+
const busy = encodeTunnelFrame({ id: header.id, kind: 'response', status: 503, headers: [['content-type', 'application/json'], ['retry-after', '1']] }, encodeUtf8(JSON.stringify({ error: 'relay-overloaded', message: 'Daemon relay is at its in-flight request cap; retry shortly.' })));
|
|
278
|
+
ws.send(framePipePayload(pipeIdBytes, await channel.seal(busy)));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// Abortable request: a streaming endpoint reached as a plain tunneled
|
|
282
|
+
// request tears down on request.signal abort; without a signal its
|
|
283
|
+
// producer would run (and buffer) forever.
|
|
284
|
+
const abort = new AbortController();
|
|
188
285
|
const request = new Request(new URL(header.path, options.localBaseUrl), {
|
|
189
286
|
method: header.method,
|
|
190
287
|
headers: [...header.headers.map(([k, v]) => [k, v]), [RELAY_VIA_HEADER, '1']],
|
|
191
288
|
...(body.length > 0 ? { body } : {}),
|
|
289
|
+
signal: abort.signal,
|
|
192
290
|
});
|
|
193
|
-
|
|
291
|
+
// The in-flight count covers the FULL request lifetime — dispatch AND
|
|
292
|
+
// response buffering. Buffering is the max-memory phase; releasing the slot
|
|
293
|
+
// at dispatch-resolve would let N buffering requests bypass the cap.
|
|
294
|
+
inFlightRequests += 1;
|
|
194
295
|
try {
|
|
195
|
-
response
|
|
296
|
+
let response;
|
|
297
|
+
try {
|
|
298
|
+
response = (await options.dispatch(request)) ?? new Response('Not found', { status: 404 });
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
logger.error('relay dispatch failed', { error: String(err) });
|
|
302
|
+
response = new Response('Internal error', { status: 500 });
|
|
303
|
+
}
|
|
304
|
+
// A plain tunneled request must never buffer an event stream: refuse
|
|
305
|
+
// honestly and tear the producer down (the stream-open frame kind is the
|
|
306
|
+
// supported path for subscriptions).
|
|
307
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
308
|
+
if (contentType.includes('text/event-stream')) {
|
|
309
|
+
abort.abort();
|
|
310
|
+
await response.body?.cancel().catch(() => { });
|
|
311
|
+
const refused = encodeTunnelFrame({ id: header.id, kind: 'response', status: 501, headers: [['content-type', 'application/json']] }, encodeUtf8(JSON.stringify({ error: 'streaming-not-supported', message: 'This path serves an event stream; open it with a stream-open frame instead of a plain request.' })));
|
|
312
|
+
ws.send(framePipePayload(pipeIdBytes, await channel.seal(refused)));
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const bounded = await readTunnelBodyBounded(response, MAX_TUNNEL_RESPONSE_BYTES);
|
|
316
|
+
if (!bounded.ok) {
|
|
317
|
+
abort.abort();
|
|
318
|
+
const refused = encodeTunnelFrame({ id: header.id, kind: 'response', status: 502, headers: [['content-type', 'application/json']] }, encodeUtf8(JSON.stringify({ error: 'response-too-large', message: `Response exceeded the ${MAX_TUNNEL_RESPONSE_BYTES}-byte tunneled-request ceiling.` })));
|
|
319
|
+
ws.send(framePipePayload(pipeIdBytes, await channel.seal(refused)));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const bodyBytes = bounded.bytes;
|
|
323
|
+
const respHeaders = [];
|
|
324
|
+
response.headers.forEach((value, key) => respHeaders.push([key, value]));
|
|
325
|
+
const out = encodeTunnelFrame({ id: header.id, kind: 'response', status: response.status, headers: respHeaders }, bodyBytes);
|
|
326
|
+
ws.send(framePipePayload(pipeIdBytes, await channel.seal(out)));
|
|
196
327
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
response = new Response('Internal error', { status: 500 });
|
|
328
|
+
finally {
|
|
329
|
+
inFlightRequests -= 1;
|
|
200
330
|
}
|
|
201
|
-
const bodyBytes = new Uint8Array(await response.arrayBuffer());
|
|
202
|
-
const respHeaders = [];
|
|
203
|
-
response.headers.forEach((value, key) => respHeaders.push([key, value]));
|
|
204
|
-
const out = encodeTunnelFrame({ id: header.id, kind: 'response', status: response.status, headers: respHeaders }, new Uint8Array(bodyBytes.buffer.slice(bodyBytes.byteOffset, bodyBytes.byteOffset + bodyBytes.byteLength)));
|
|
205
|
-
ws.send(framePipePayload(pipeIdBytes, await channel.seal(out)));
|
|
206
331
|
}
|
|
207
332
|
async function openTunneledStream(pipeKey, header, channel, pipeIdBytes, ws) {
|
|
208
333
|
const streams = pipeStreams.get(pipeKey) ?? new Map();
|
|
@@ -372,5 +497,14 @@ export function createRelayDaemonRegistration(options) {
|
|
|
372
497
|
...(label !== undefined ? { label } : {}),
|
|
373
498
|
});
|
|
374
499
|
},
|
|
500
|
+
stats() {
|
|
501
|
+
return {
|
|
502
|
+
pipes: channels.size,
|
|
503
|
+
inFlightRequests,
|
|
504
|
+
streams: countStreams(),
|
|
505
|
+
droppedPipes,
|
|
506
|
+
droppedRequests,
|
|
507
|
+
};
|
|
508
|
+
},
|
|
375
509
|
};
|
|
376
510
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pellux/goodvibes-daemon-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"bun": "1.3.10",
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -172,9 +172,9 @@
|
|
|
172
172
|
"control-plane"
|
|
173
173
|
],
|
|
174
174
|
"dependencies": {
|
|
175
|
-
"@pellux/goodvibes-contracts": "1.
|
|
176
|
-
"@pellux/goodvibes-errors": "1.
|
|
177
|
-
"@pellux/goodvibes-transport-core": "1.
|
|
175
|
+
"@pellux/goodvibes-contracts": "1.10.1",
|
|
176
|
+
"@pellux/goodvibes-errors": "1.10.1",
|
|
177
|
+
"@pellux/goodvibes-transport-core": "1.10.1"
|
|
178
178
|
},
|
|
179
179
|
"publishConfig": {
|
|
180
180
|
"access": "public"
|