@statewalker/webrun-http-browser 0.3.3 → 0.3.4

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.
Files changed (93) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +321 -51
  3. package/demo/demo-1.html +109 -194
  4. package/demo/demo-2.html +118 -299
  5. package/dist/core/data-calls.d.ts +5 -0
  6. package/dist/core/data-calls.d.ts.map +1 -0
  7. package/dist/core/data-channels.d.ts +17 -0
  8. package/dist/core/data-channels.d.ts.map +1 -0
  9. package/dist/core/index.d.ts +6 -0
  10. package/dist/core/index.d.ts.map +1 -0
  11. package/dist/core/message-target.d.ts +16 -0
  12. package/dist/core/message-target.d.ts.map +1 -0
  13. package/dist/core/registry.d.ts +18 -0
  14. package/dist/core/registry.d.ts.map +1 -0
  15. package/dist/http/http-send-recieve.d.ts +23 -0
  16. package/dist/http/http-send-recieve.d.ts.map +1 -0
  17. package/dist/http/index.d.ts +4 -0
  18. package/dist/http/index.d.ts.map +1 -0
  19. package/dist/index.d.ts +4 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +2541 -807
  22. package/dist/relay/index-sw.d.ts +7 -0
  23. package/dist/relay/index-sw.d.ts.map +1 -0
  24. package/dist/relay/index.d.ts +69 -0
  25. package/dist/relay/index.d.ts.map +1 -0
  26. package/dist/relay/split-service-url.d.ts +13 -0
  27. package/dist/relay/split-service-url.d.ts.map +1 -0
  28. package/dist/relay-sw.d.ts +2 -0
  29. package/dist/relay-sw.d.ts.map +1 -0
  30. package/dist/relay-sw.js +878 -0
  31. package/dist/sw/http-sw-dispatcher.d.ts +28 -0
  32. package/dist/sw/http-sw-dispatcher.d.ts.map +1 -0
  33. package/dist/sw/index.d.ts +3 -0
  34. package/dist/sw/index.d.ts.map +1 -0
  35. package/dist/sw/sw-dispatcher.d.ts +74 -0
  36. package/dist/sw/sw-dispatcher.d.ts.map +1 -0
  37. package/dist/sw-worker.d.ts +2 -0
  38. package/dist/sw-worker.d.ts.map +1 -0
  39. package/dist/sw-worker.js +813 -0
  40. package/dist/sw.d.ts +2 -0
  41. package/dist/sw.d.ts.map +1 -0
  42. package/dist/sw.js +1076 -0
  43. package/package.json +50 -37
  44. package/public/index.html +61 -97
  45. package/public/index.js +7 -4
  46. package/public/sw-worker.js +4 -0
  47. package/public-relay/heartbeat.js +4 -3
  48. package/public-relay/relay-sw.js +4 -6
  49. package/public-relay/relay.html +16 -11
  50. package/src/core/data-calls.ts +46 -0
  51. package/src/core/data-channels.ts +224 -0
  52. package/src/core/index.ts +9 -0
  53. package/src/core/message-target.ts +18 -0
  54. package/src/core/registry.ts +54 -0
  55. package/src/http/http-send-recieve.ts +81 -0
  56. package/src/http/index.ts +7 -0
  57. package/src/index.ts +3 -0
  58. package/src/relay/index-sw.ts +145 -0
  59. package/src/relay/index.ts +261 -0
  60. package/src/relay/split-service-url.ts +30 -0
  61. package/src/relay-sw.ts +7 -0
  62. package/src/sw/http-sw-dispatcher.ts +122 -0
  63. package/src/sw/index.ts +2 -0
  64. package/src/sw/sw-dispatcher.ts +307 -0
  65. package/src/sw-worker.ts +7 -0
  66. package/src/sw.ts +1 -0
  67. package/CHANGELOG.md +0 -1
  68. package/demo/demo-2 copy.html +0 -598
  69. package/demo/demo-3.html +0 -167
  70. package/dist/index-sw-umd.js +0 -798
  71. package/dist/index-sw-umd.min.js +0 -2
  72. package/dist/index-sw.js +0 -791
  73. package/dist/index-sw.min.js +0 -2
  74. package/dist/index-umd.js +0 -853
  75. package/dist/index-umd.min.js +0 -2
  76. package/dist/index.min.js +0 -2
  77. package/index.js +0 -1
  78. package/src/core/data-calls.js +0 -36
  79. package/src/core/data-channels.js +0 -192
  80. package/src/core/data-send-recieve.js +0 -28
  81. package/src/core/errors.js +0 -13
  82. package/src/core/index.js +0 -4
  83. package/src/http/HttpError.js +0 -59
  84. package/src/http/http-send-recieve.js +0 -40
  85. package/src/http/http-stubs.js +0 -135
  86. package/src/http/index.js +0 -3
  87. package/src/http/readable-streams.js +0 -33
  88. package/src/index.js +0 -7
  89. package/src/relay/index-sw.js +0 -216
  90. package/src/relay/index.js +0 -263
  91. package/src/relay/splitServiceUrl.js +0 -24
  92. package/src/sw/http-sw-dispatcher.js +0 -128
  93. package/src/sw/sw-dispatcher.js +0 -264
package/demo/demo-2.html CHANGED
@@ -1,318 +1,137 @@
1
- <!DOCTYPE HTML>
2
- <html>
3
-
4
- <head>
5
- <meta charset="utf-8" />
6
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1" />
8
- <style>
9
- /* CSS styles for files tree. */
10
- .tree {
11
- --tree-line-width: 1px;
12
- --tree-line-color: silver;
13
- --tree-connector-radius: 0.1em;
14
- --tree-connector-length: 0.5em;
15
- --tree-connector-height: 0.6em;
16
- --tree-content-padding: 0.5em;
17
- position: relative;
18
- }
19
- .tree .tree-node {
20
- position: relative;
21
- padding-inline-start: var(--tree-connector-length);
22
- border-inline-start: var(--tree-line-width) solid var(--tree-line-color);
23
- }
24
- .tree .tree-node:before {
25
- content: "";
26
- position: absolute;
27
- top: 0;
28
- left: 0;
29
- right: 0;
30
- width: var(--tree-connector-length);
31
- height: var(--tree-connector-height);
32
- max-height: 100%;
33
- margin-inline-start: calc(0em - var(--tree-line-width));
34
- border-bottom: var(--tree-line-width) solid var(--tree-line-color);
35
- border-inline-start: var(--tree-line-width) solid var(--tree-line-color);
36
- border-end-start-radius: var(--tree-connector-radius);
37
- }
38
- .tree .tree-node:last-child {
39
- border-inline-start: var(--tree-line-width) solid transparent;
40
- }
41
- .tree .tree-node > .tree-node-content {
42
- position: relative;
43
- padding-inline-start: var(--tree-content-padding);
44
- }
45
- .tree .tree-node > .tree-node-content:before {
46
- content: "";
47
- position: absolute;
48
- top: var(--tree-connector-height);
49
- left: 0;
50
- right: 0;
51
- width: var(--tree-line-width);
52
- height: calc(100% - var(--tree-connector-height));
53
- border-inline-start: var(--tree-line-width) solid var(--tree-line-color);
54
- }
55
- .tree .tree-node > .tree-node-content:last-child:before {
56
- border-inline-start: var(--tree-line-width) solid transparent;
57
- }
58
-
59
- .tree {
60
- --tree-content-padding: 0.1em;
61
- padding: 1em 1em 1em 2em;
62
- }
63
- .tree .tree-node > .tree-node-content {
64
- display: flex;
65
- gap: 0.2em;
66
- }
67
- .tree .tree-node > .tree-node-content > .icon-dir,
68
- .tree .tree-node > .tree-node-content > .icon-file {
69
- display: block;
70
- width: 1.5em;
71
- color: gray;
72
- }
73
-
74
- /* */
75
- .files-panel {
76
- display: flex;
77
- align-items: stretch;
78
- align-content: stretch;
79
- justify-content: stretch;
80
- min-height: 25em;
81
- gap: 1em;
82
- width: 100%;
83
- }
84
- .files-panel .files-explorer {
85
- min-width: 15em;
86
- border: 1px solid #eee;
87
- flex: none;
88
- }
89
- .files-panel .files-preview {
90
- flex: auto;
91
- border: 1px solid red;
92
- }
93
- .files-panel .files-preview iframe {
94
- width: 100%;
95
- height: calc(100% - 1em);
96
- border: none;
97
- outline: none;
98
- }
99
- </style>
100
- </head>
101
-
102
- <body>
103
- <h3>Local File System</h3>
104
- <p>
105
- This page allows you to get read/write access to your local file system and develop the whole site directly in the browser without an HTTP server.
106
- </p>
107
- <div>
108
- <button id="fs-open">Open Workspace</button>
109
- <button id="fs-redraw-tree" style="display: none;">Redraw Files Tree</button>
110
- </div>
111
- <div class="files-panel">
112
- <div class="files-explorer">
113
- Files Tree:
114
- <div id="fs-view"></div>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>webrun-http-browser — local file server demo (relay)</title>
7
+ <style>
8
+ body { font-family: system-ui, sans-serif; margin: 2rem; max-width: 60rem; }
9
+ .panel { display: flex; gap: 1rem; min-height: 22rem; }
10
+ .files { width: 16rem; border: 1px solid #e5e5e5; padding: 0.5rem; overflow: auto; }
11
+ .preview { flex: 1; border: 1px solid #e5e5e5; }
12
+ iframe { width: 100%; height: 100%; border: none; }
13
+ .tree-node { padding-left: 1rem; }
14
+ .entry { display: flex; gap: 0.25rem; cursor: pointer; font-family: monospace; }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <h1>Local disk → in-browser file server</h1>
19
+ <p>
20
+ Click <strong>Open folder</strong> and pick a directory. A relay
21
+ ServiceWorker will serve the folder's contents from an in-browser URL
22
+ rooted at <code>~FS/</code>.
23
+ </p>
24
+ <button type="button" id="open">Open folder</button>
25
+ <button type="button" id="reload" style="display: none;">Reload tree</button>
26
+ <div class="panel">
27
+ <div class="files" id="files"></div>
28
+ <div class="preview">
29
+ <iframe title="File preview" id="preview" name="preview" src=""></iframe>
30
+ </div>
115
31
  </div>
116
- <div class="files-preview">
117
- Files Preview:
118
- <iframe id="fs-preview" name="fs-preview" width="100%" height="100%" src=""></iframe>
119
- </div>
120
- </div>
121
32
 
122
- <script type="module">
123
- import * as WebRunHttp from "https://unpkg.com/@statewalker/webrun-http-browser@0.3/dist/index.js";
124
- import { Hono } from "https://unpkg.com/hono@3.5/dist/index.js";
125
- import mime from "https://esm.sh/mime-types";
126
- import {
127
- BrowserFilesApi,
128
- verifyPermission,
129
- } from "https://unpkg.com/@statewalker/webrun-files@0.2.0/dist/index.js";
33
+ <script type="module">
34
+ import * as WebRunHttp from "../dist/index.js";
130
35
 
131
- Promise.resolve().then(main).catch(console.error);
132
- async function main() {
36
+ const openBtn = document.querySelector("#open");
37
+ const reloadBtn = document.querySelector("#reload");
38
+ const filesView = document.querySelector("#files");
133
39
 
134
- const openBtn = document.querySelector("#fs-open");
135
- const refreshBtn = document.querySelector("#fs-redraw-tree");
136
- let close;
137
40
  openBtn.addEventListener("click", async () => {
138
- if (close) close();
139
- // Open a local folder:
140
- const fs = await openRepository();
141
- // Create a dispatcher between files.
142
- // This dispatcher get the requested path, read the
143
- // file content and return it to the caller with
144
- // a correct mime type:
145
- const router = await newFilesRouter(fs);
146
-
147
- // Create an HTTP Server with the specified name.
148
- // It uses the given Hono router to dispatch requests
149
- // between endpoints.
150
- const SERVICE_KEY = "FS"
151
- const serviceBaseUrl = await startHttpService({
152
- serviceKey : SERVICE_KEY,
153
- router
154
- })
155
-
156
- openBtn.style.display = "none";
157
- refreshBtn.style.display = "block";
158
- const target = "fs-preview";
159
- const filesRenderOptions = {
160
- fs,
161
- baseUrl : serviceBaseUrl,
162
- target
163
- };
164
- renderFilesExplorer(filesRenderOptions);
165
- refreshBtn.addEventListener("click", (event) => {
166
- renderFilesExplorer(filesRenderOptions);
167
- });
168
- })
169
- }
170
-
171
- function newFilesRouter(fs) {
172
- const router = new Hono();
173
- router.get("/*", async (context) => {
174
- let { url, path } = context.req;
175
- path = path.replace(/#.*$/, "");
176
- if (path.match(/\/$/)) {
177
- path = path + "index.html";
178
- }
179
- const fileInfo = await fs.stats(path);
180
- if (!fileInfo || (fileInfo.kind !== "file")) {
181
- return context.notFound();
41
+ const rootHandle = await window.showDirectoryPicker();
42
+ const permission = await rootHandle.requestPermission?.({ mode: "read" });
43
+ if (permission && permission !== "granted") {
44
+ throw new Error("Permission denied");
182
45
  }
183
- const content = await fs.read(fileInfo);
184
- const responseBody = await WebRunHttp.toReadableStream(content);
185
- return new Response(responseBody, {
186
- status: 200,
187
- headers: {
188
- "Content-Type": fileInfo.type,
189
- },
190
- });
191
- });
192
- return router;
193
- }
194
46
 
195
- async function openRepository(readwrite = true) {
196
- const handler = await window.showDirectoryPicker();
197
- if (!(await verifyPermission(handler, readwrite))) {
198
- throw new Error("Access was not granted");
199
- }
200
- const fs = new BrowserFilesApi({ rootHandler : handler });
201
- return fs;
202
- }
203
-
204
- async function startHttpService({
205
- serviceKey,
206
- router
207
- }) {
208
- // Step 1: Start a ServiceWorker and open a MessageChannel used to recieve HTTP requests and send responses:
209
- const connection = await WebRunHttp.newRemoteRelayChannel();
210
-
211
- // Step 2: Define an HTTP handler
212
- const serviceBaseUrl = `${connection.baseUrl}~${serviceKey}`;
213
- const app = new Hono({
214
- getPath: (req) => req.url.substring(serviceBaseUrl.length)
215
- });
216
- // Add the router
217
- app.route("/", router);
218
- const httpHandler = (request) => app.fetch(request);
47
+ const SERVICE_KEY = "FS";
48
+ const connection = await WebRunHttp.newRemoteRelayChannel();
49
+ const serviceBaseUrl = `${connection.baseUrl}~${SERVICE_KEY}`;
50
+
51
+ await WebRunHttp.initHttpService(
52
+ async (request) => {
53
+ const url = new URL(request.url);
54
+ const rel = url.pathname.substring(
55
+ new URL(serviceBaseUrl).pathname.length,
56
+ );
57
+ const path = rel.replace(/^\/+/, "").replace(/\/$/, "");
58
+ try {
59
+ const file = await resolveFile(rootHandle, path);
60
+ if (!file) return new Response(null, { status: 404 });
61
+ const body = await file.stream();
62
+ return new Response(body, {
63
+ headers: { "Content-Type": file.type || guessMime(file.name) },
64
+ });
65
+ } catch (_err) {
66
+ return new Response(null, { status: 404 });
67
+ }
68
+ },
69
+ { key: SERVICE_KEY, port: connection.port },
70
+ );
219
71
 
220
- // Step 3: Instantiate a "server" using the communcation channel with the ServiceWorker:
221
- const close = await WebRunHttp.initHttpService(httpHandler, {
222
- key: serviceKey, // Service prefix
223
- port: connection.port
72
+ openBtn.style.display = "none";
73
+ reloadBtn.style.display = "";
74
+ reloadBtn.addEventListener("click", () => renderTree(rootHandle, serviceBaseUrl));
75
+ renderTree(rootHandle, serviceBaseUrl);
224
76
  });
225
77
 
226
- return serviceBaseUrl;
227
- }
228
-
229
- // Files tree visualization
230
-
231
- async function renderFilesExplorer({ fs, baseUrl, target = "_blank" }) {
232
- const container = document.querySelector("#fs-view");
233
- container.innerHTML = "";
234
- container.classList.add("tree");
235
- for await (let file of fs.list("/", { recursive: false })) {
236
- renderFile({
237
- fs,
238
- file,
239
- baseUrl,
240
- container,
241
- target
242
- })
243
- }
244
- }
245
-
246
- function renderFile({
247
- fs,
248
- file,
249
- container,
250
- baseUrl,
251
- target
252
- }) {
253
- let path = file.path;
254
- const isDirectory = file.kind === "directory";
255
- if (isDirectory) {
256
- if (path[path.length - 1] !== '/') {
257
- path += '/';
78
+ async function resolveFile(root, path) {
79
+ const parts = path.split("/").filter(Boolean);
80
+ let dir = root;
81
+ for (let i = 0; i < parts.length - 1; i++) {
82
+ dir = await dir.getDirectoryHandle(parts[i]);
258
83
  }
84
+ const handle = await dir.getFileHandle(parts[parts.length - 1]);
85
+ return handle.getFile();
259
86
  }
260
87
 
261
- const treeNodeElm = newElement("tree-node", container);
262
- const treeNodeContentElm = newElement("tree-node-content", treeNodeElm);
263
- const iconElm = newElement("tree-node-icon", treeNodeContentElm);
264
- const iconCls = isDirectory ? "icon-dir" : "icon-file";
265
- iconElm.classList.add(iconCls);
266
- iconElm.innerText = isDirectory ? 'dir' : 'file';
267
-
268
- const linkElm = newElement("file-name", treeNodeContentElm, "a");
269
- const fileUrl = baseUrl + path;
270
- linkElm.setAttribute("href", fileUrl);
271
- linkElm.setAttribute("target", target);
272
- linkElm.innerText = file.name;
88
+ async function renderTree(rootHandle, baseUrl) {
89
+ filesView.innerHTML = "";
90
+ await renderDir(rootHandle, "", baseUrl, filesView);
91
+ }
273
92
 
274
- if (isDirectory) {
275
- let opened = false;
276
- linkElm.addEventListener("click", async (ev) => {
277
- ev.preventDefault();
278
- ev.stopPropagation();
279
- opened = !opened;
280
- if (opened) {
281
- for await (let child of fs.list(file, { recursive: false })) {
282
- renderFile({
283
- fs,
284
- file : child,
285
- baseUrl,
286
- container : treeNodeElm,
287
- target
288
- })
289
- }
93
+ async function renderDir(handle, prefix, baseUrl, parent) {
94
+ for await (const [name, entry] of handle.entries()) {
95
+ const node = document.createElement("div");
96
+ node.className = "tree-node";
97
+ const row = document.createElement("div");
98
+ row.className = "entry";
99
+ const path = `${prefix}${name}`;
100
+ if (entry.kind === "directory") {
101
+ row.textContent = `📁 ${name}`;
102
+ let expanded = false;
103
+ row.addEventListener("click", async () => {
104
+ expanded = !expanded;
105
+ if (expanded) await renderDir(entry, `${path}/`, baseUrl, node);
106
+ else for (const c of [...node.children].slice(1)) node.removeChild(c);
107
+ });
290
108
  } else {
291
- let elm = treeNodeElm.querySelector(".tree-node-content");
292
- elm = elm?.nextElementSibling;
293
- while (elm) {
294
- const next = elm.nextElementSibling;
295
- treeNodeElm.removeChild(elm);
296
- elm = next;
297
- }
109
+ const link = document.createElement("a");
110
+ link.href = `${baseUrl}/${path}`;
111
+ link.target = "preview";
112
+ link.textContent = `📄 ${name}`;
113
+ row.appendChild(link);
298
114
  }
299
- })
300
- }
301
-
302
- function newElement(className, parent, name = "div") {
303
- const div = document.createElement(name);
304
- className
305
- .split(/\\s+/)
306
- .map(s => s.trim())
307
- .forEach(cls => div.classList.add(cls));
308
- if (parent) {
309
- parent.appendChild(div);
115
+ node.appendChild(row);
116
+ parent.appendChild(node);
310
117
  }
311
- return div;
312
118
  }
313
- }
314
-
315
- </script>
316
- </body>
317
119
 
318
- </html>
120
+ function guessMime(name) {
121
+ const ext = name.toLowerCase().split(".").pop();
122
+ return ({
123
+ html: "text/html",
124
+ css: "text/css",
125
+ js: "text/javascript",
126
+ json: "application/json",
127
+ png: "image/png",
128
+ jpg: "image/jpeg",
129
+ jpeg: "image/jpeg",
130
+ svg: "image/svg+xml",
131
+ txt: "text/plain",
132
+ md: "text/markdown",
133
+ }[ext] ?? "application/octet-stream");
134
+ }
135
+ </script>
136
+ </body>
137
+ </html>
@@ -0,0 +1,5 @@
1
+ import type { MessageSink, MessageSource } from "./message-target.js";
2
+ export type ChannelCallHandler = (event: MessageEvent, params: unknown, ...transfers: MessagePort[]) => unknown;
3
+ export declare function callChannel<T = unknown>(target: MessageSink, callType: string, params: unknown, ...transfers: Transferable[]): Promise<T>;
4
+ export declare function handleChannelCalls(target: MessageSource, callType: string, handler: ChannelCallHandler): () => void;
5
+ //# sourceMappingURL=data-calls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-calls.d.ts","sourceRoot":"","sources":["../../src/core/data-calls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,OAAO,EACf,GAAG,SAAS,EAAE,WAAW,EAAE,KACxB,OAAO,CAAC;AAEb,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EACrC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,EACf,GAAG,SAAS,EAAE,YAAY,EAAE,GAC3B,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,GAC1B,MAAM,IAAI,CAeZ"}
@@ -0,0 +1,17 @@
1
+ import type { MessageTarget } from "./message-target.js";
2
+ export interface InvocationChannel {
3
+ start(): Promise<void>;
4
+ close(): Promise<void>;
5
+ invoke<T = unknown>(request?: unknown, ...transfers: Transferable[]): Promise<T>;
6
+ }
7
+ export interface NewInvocationChannelOptions {
8
+ port: MessageTarget;
9
+ handler?: (request: unknown, ...ports: MessagePort[]) => unknown;
10
+ onError?: (error: unknown) => void;
11
+ newCallId?: () => number;
12
+ }
13
+ export declare function newInvokationChannel({ port, handler, onError, newCallId, }: NewInvocationChannelOptions): InvocationChannel;
14
+ export declare function sendStream<T>(communicationPort: MessageTarget, input: AsyncIterable<T>, params?: Record<string, unknown>): AsyncGenerator<T, void, unknown>;
15
+ export type StreamHandler<T> = (input: AsyncIterable<T>, params: Record<string, unknown>) => AsyncIterable<T> | Promise<AsyncIterable<T>>;
16
+ export declare function handleStreams<T>(communicationPort: MessageTarget, handler: StreamHandler<T>): () => void;
17
+ //# sourceMappingURL=data-channels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-channels.d.ts","sourceRoot":"","sources":["../../src/core/data-channels.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAqBzD,MAAM,WAAW,iBAAiB;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,OAEC,EACD,OAAuB,EACvB,SAAuC,GACxC,EAAE,2BAA2B,GAAG,iBAAiB,CAoEjD;AAED,wBAAuB,UAAU,CAAC,CAAC,EACjC,iBAAiB,EAAE,aAAa,EAChC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAYlC;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAC7B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAElD,wBAAgB,aAAa,CAAC,CAAC,EAC7B,iBAAiB,EAAE,aAAa,EAChC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,MAAM,IAAI,CAqBZ"}
@@ -0,0 +1,6 @@
1
+ export * from "@statewalker/webrun-streams";
2
+ export * from "./data-calls.js";
3
+ export * from "./data-channels.js";
4
+ export * from "./message-target.js";
5
+ export * from "./registry.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAGA,cAAc,6BAA6B,CAAC;AAE5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type MessageListener = (event: MessageEvent) => void | Promise<void>;
2
+ /** An object we can listen for `"message"` events on. */
3
+ export interface MessageSource {
4
+ addEventListener(type: "message", listener: MessageListener): void;
5
+ removeEventListener(type: "message", listener: MessageListener): void;
6
+ start?(): void | Promise<void>;
7
+ }
8
+ /** An object we can post messages to (with optional transferable list). */
9
+ export interface MessageSink {
10
+ postMessage(message: unknown, transfer?: Transferable[]): void;
11
+ }
12
+ /** Full-duplex message target: both sends and receives. */
13
+ export interface MessageTarget extends MessageSource, MessageSink {
14
+ close?(): void | Promise<void>;
15
+ }
16
+ //# sourceMappingURL=message-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-target.d.ts","sourceRoot":"","sources":["../../src/core/message-target.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5E,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACnE,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACtE,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;CAChE;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAc,SAAQ,aAAa,EAAE,WAAW;IAC/D,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC"}
@@ -0,0 +1,18 @@
1
+ export type CleanupAction = () => unknown;
2
+ interface CleanupFn {
3
+ (skip?: boolean): unknown;
4
+ action: CleanupAction;
5
+ }
6
+ export interface Registry {
7
+ register(action: CleanupAction): CleanupFn;
8
+ unregister(action: CleanupAction): void;
9
+ clear(): void;
10
+ }
11
+ export type NewRegistryResult = [
12
+ register: Registry["register"],
13
+ clear: Registry["clear"],
14
+ unregister: Registry["unregister"]
15
+ ] & Registry;
16
+ export declare function newRegistry(onError?: (error: unknown) => void): NewRegistryResult;
17
+ export {};
18
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC;AAE1C,UAAU,SAAS;IACjB,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IACxC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC;IAC9B,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC;IACxB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC;CACnC,GACC,QAAQ,CAAC;AAEX,wBAAgB,WAAW,CAAC,OAAO,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAoB,GAAG,iBAAiB,CAiChG"}
@@ -0,0 +1,23 @@
1
+ import { type HttpHandler } from "@statewalker/webrun-http-streams";
2
+ import type { MessageTarget } from "../core/message-target.js";
3
+ /**
4
+ * @deprecated For new code, prefer the `MessagePort`-based stack from
5
+ * `@statewalker/webrun-http-port`. Once a `MessagePort` is established between
6
+ * page and worker, `httpServe(port, handler)` provides equivalent semantics
7
+ * with `callBidi` multiplexing, full-duplex streaming, and `AbortSignal`.
8
+ * This helper remains for existing ServiceWorker setups that still consume the
9
+ * `MessageTarget` surface; it will be reimplemented on top of
10
+ * `webrun-http-port` in a follow-up release.
11
+ */
12
+ export declare function handleHttpRequests(communicationPort: MessageTarget, handler: HttpHandler): () => void;
13
+ /**
14
+ * @deprecated For new code, prefer the `MessagePort`-based stack from
15
+ * `@statewalker/webrun-http-port/fetch`. Once the page and SW share a
16
+ * `MessagePort`, `fetchOverPort(port, request)` provides the same
17
+ * `Request → Response` semantics with multiplexing via `callBidi`, JSONL
18
+ * envelope framing, and native `AbortSignal` support. This helper remains for
19
+ * existing ServiceWorker setups; it will be reimplemented on top of
20
+ * `webrun-http-port` in a follow-up release.
21
+ */
22
+ export declare function sendHttpRequest(communicationPort: MessageTarget, request: Request): Promise<Response>;
23
+ //# sourceMappingURL=http-send-recieve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-send-recieve.d.ts","sourceRoot":"","sources":["../../src/http/http-send-recieve.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAMjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA+B/D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,aAAa,EAChC,OAAO,EAAE,WAAW,GACnB,MAAM,IAAI,CAOZ;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,iBAAiB,EAAE,aAAa,EAChC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC,CAOnB"}
@@ -0,0 +1,4 @@
1
+ export * from "@statewalker/webrun-http-streams";
2
+ export * from "@statewalker/webrun-streams";
3
+ export * from "./http-send-recieve.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAIA,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./core/index.js";
2
+ export * from "./http/index.js";
3
+ export * from "./relay/index.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}