@mcp-b/do-runtime 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 55bae81: Export the shared in-memory hibernation mirror and browser WebSocket-upgrade adapter so embedders can reuse the reference host behavior instead of copying example shims.
8
+
3
9
  ## 0.6.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -241,6 +241,12 @@ registry is populated before the constructor, so SDKs can lazily rebuild their
241
241
  connection wrappers without another upgrade or connect hook. Closed sockets are
242
242
  removed before `webSocketClose` runs.
243
243
 
244
+ `HibernationMirror` is the package's in-memory reference implementation. Seed a
245
+ replacement mirror with the prior socket snapshot and auto-response pair, then
246
+ pass that mirror to `ports.hibernation` and its `snapshot()` to `webSockets`.
247
+ Browser hosts can install the remaining Request/Response upgrade accommodation
248
+ from `@mcp-b/do-runtime/browser`; the runtime itself supplies `WebSocketPair`.
249
+
244
250
  `container.quiescence()` reports armed timers, pending `waitUntil` work, input
245
251
  lock state, and output-gate breakage without waiting. `drainWaitUntil()` is for
246
252
  shutdown and intentionally never settles while a live interval remains armed.
@@ -0,0 +1,55 @@
1
+ import { o as markWebSocketUsed } from "./chunks/web-socket-W63BdFn5.js";
2
+ //#region src/browser.ts
3
+ var upgradeRequests = /* @__PURE__ */ new WeakSet();
4
+ var installed = false;
5
+ /** Install the Request/Response half of browser-hosted WebSocket upgrades. */
6
+ function installWebSocketUpgradeGlobals() {
7
+ if (installed) return;
8
+ installed = true;
9
+ const NativeRequest = globalThis.Request;
10
+ class WorkersRequest extends NativeRequest {
11
+ constructor(input, init) {
12
+ const upgrade = input instanceof NativeRequest && isWebSocketUpgrade(input);
13
+ super(input, init);
14
+ if (upgrade) withWebSocketUpgrade(this);
15
+ }
16
+ }
17
+ globalThis.Request = WorkersRequest;
18
+ const NativeResponse = globalThis.Response;
19
+ class WorkersResponse extends NativeResponse {
20
+ constructor(body, init = {}) {
21
+ const upgrade = init.status === 101;
22
+ const { webSocket, ...nativeInit } = init;
23
+ super(body, upgrade ? {
24
+ ...nativeInit,
25
+ status: 200
26
+ } : nativeInit);
27
+ if (upgrade) Object.defineProperty(this, "status", { value: 101 });
28
+ if (webSocket !== void 0) {
29
+ markWebSocketUsed(webSocket);
30
+ Object.defineProperty(this, "webSocket", { value: webSocket });
31
+ }
32
+ }
33
+ }
34
+ globalThis.Response = WorkersResponse;
35
+ }
36
+ function upgradeWebSocket(response) {
37
+ return response.webSocket;
38
+ }
39
+ /** Preserve the upgrade signal across browser `Request.clone()` calls. */
40
+ function withWebSocketUpgrade(request) {
41
+ if (upgradeRequests.has(request)) return request;
42
+ upgradeRequests.add(request);
43
+ const get = request.headers.get.bind(request.headers);
44
+ Object.defineProperty(request.headers, "get", { value: (name) => name.toLowerCase() === "upgrade" ? "websocket" : get(name) });
45
+ const clone = request.clone.bind(request);
46
+ Object.defineProperty(request, "clone", { value: () => withWebSocketUpgrade(clone()) });
47
+ return request;
48
+ }
49
+ function isWebSocketUpgrade(request) {
50
+ return upgradeRequests.has(request) || request.headers.get("Upgrade")?.toLowerCase() === "websocket";
51
+ }
52
+ //#endregion
53
+ export { installWebSocketUpgradeGlobals, upgradeWebSocket, withWebSocketUpgrade };
54
+
55
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import { markWebSocketUsed, type RawWebSocket } from \"./api/web-socket\";\n\nexport type UpgradeWebSocket = EventTarget &\n RawWebSocket & {\n accept(): void;\n readonly readyState: number;\n };\n\ntype UpgradeResponseInit = Omit<ResponseInit, \"webSocket\"> & {\n webSocket?: UpgradeWebSocket;\n};\ntype UpgradeResponse = Response & { readonly webSocket?: UpgradeWebSocket };\ntype CloneableRequest = { readonly headers: Headers; clone(): CloneableRequest };\n\nconst upgradeRequests = new WeakSet<CloneableRequest>();\nlet installed = false;\n\n/** Install the Request/Response half of browser-hosted WebSocket upgrades. */\nexport function installWebSocketUpgradeGlobals(): void {\n if (installed) return;\n installed = true;\n\n const NativeRequest = globalThis.Request;\n class WorkersRequest extends NativeRequest {\n constructor(input: RequestInfo | URL, init?: RequestInit) {\n const upgrade = input instanceof NativeRequest && isWebSocketUpgrade(input);\n super(input, init);\n if (upgrade) withWebSocketUpgrade(this);\n }\n }\n globalThis.Request = WorkersRequest as typeof Request;\n\n const NativeResponse = globalThis.Response;\n class WorkersResponse extends NativeResponse {\n constructor(body?: BodyInit | null, init: UpgradeResponseInit = {}) {\n const upgrade = init.status === 101;\n const { webSocket, ...nativeInit } = init;\n super(body, upgrade ? { ...nativeInit, status: 200 } : nativeInit);\n if (upgrade) Object.defineProperty(this, \"status\", { value: 101 });\n if (webSocket !== undefined) {\n markWebSocketUsed(webSocket);\n Object.defineProperty(this, \"webSocket\", { value: webSocket });\n }\n }\n }\n globalThis.Response = WorkersResponse as typeof Response;\n}\n\nexport function upgradeWebSocket(response: Response): UpgradeWebSocket | undefined {\n return (response as UpgradeResponse).webSocket;\n}\n\n/** Preserve the upgrade signal across browser `Request.clone()` calls. */\nexport function withWebSocketUpgrade<T extends CloneableRequest>(request: T): T {\n if (upgradeRequests.has(request)) return request;\n upgradeRequests.add(request);\n const get = request.headers.get.bind(request.headers);\n Object.defineProperty(request.headers, \"get\", {\n value: (name: string): string | null =>\n name.toLowerCase() === \"upgrade\" ? \"websocket\" : get(name),\n });\n const clone = request.clone.bind(request);\n Object.defineProperty(request, \"clone\", {\n value: (): CloneableRequest => withWebSocketUpgrade(clone()),\n });\n return request;\n}\n\nfunction isWebSocketUpgrade(request: Request): boolean {\n return (\n upgradeRequests.has(request) || request.headers.get(\"Upgrade\")?.toLowerCase() === \"websocket\"\n );\n}\n"],"mappings":";;AAcA,IAAM,kCAAkB,IAAI,QAA0B;AACtD,IAAI,YAAY;;AAGhB,SAAgB,iCAAuC;CACrD,IAAI,WAAW;CACf,YAAY;CAEZ,MAAM,gBAAgB,WAAW;CACjC,MAAM,uBAAuB,cAAc;EACzC,YAAY,OAA0B,MAAoB;GACxD,MAAM,UAAU,iBAAiB,iBAAiB,mBAAmB,KAAK;GAC1E,MAAM,OAAO,IAAI;GACjB,IAAI,SAAS,qBAAqB,IAAI;EACxC;CACF;CACA,WAAW,UAAU;CAErB,MAAM,iBAAiB,WAAW;CAClC,MAAM,wBAAwB,eAAe;EAC3C,YAAY,MAAwB,OAA4B,CAAC,GAAG;GAClE,MAAM,UAAU,KAAK,WAAW;GAChC,MAAM,EAAE,WAAW,GAAG,eAAe;GACrC,MAAM,MAAM,UAAU;IAAE,GAAG;IAAY,QAAQ;GAAI,IAAI,UAAU;GACjE,IAAI,SAAS,OAAO,eAAe,MAAM,UAAU,EAAE,OAAO,IAAI,CAAC;GACjE,IAAI,cAAc,KAAA,GAAW;IAC3B,kBAAkB,SAAS;IAC3B,OAAO,eAAe,MAAM,aAAa,EAAE,OAAO,UAAU,CAAC;GAC/D;EACF;CACF;CACA,WAAW,WAAW;AACxB;AAEA,SAAgB,iBAAiB,UAAkD;CACjF,OAAQ,SAA6B;AACvC;;AAGA,SAAgB,qBAAiD,SAAe;CAC9E,IAAI,gBAAgB,IAAI,OAAO,GAAG,OAAO;CACzC,gBAAgB,IAAI,OAAO;CAC3B,MAAM,MAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ,OAAO;CACpD,OAAO,eAAe,QAAQ,SAAS,OAAO,EAC5C,QAAQ,SACN,KAAK,YAAY,MAAM,YAAY,cAAc,IAAI,IAAI,EAC7D,CAAC;CACD,MAAM,QAAQ,QAAQ,MAAM,KAAK,OAAO;CACxC,OAAO,eAAe,SAAS,SAAS,EACtC,aAA+B,qBAAqB,MAAM,CAAC,EAC7D,CAAC;CACD,OAAO;AACT;AAEA,SAAS,mBAAmB,SAA2B;CACrD,OACE,gBAAgB,IAAI,OAAO,KAAK,QAAQ,QAAQ,IAAI,SAAS,CAAC,EAAE,YAAY,MAAM;AAEtF"}