@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/dist/index-umd.js DELETED
@@ -1,853 +0,0 @@
1
- // @statewalker/webrun-http-browser v0.3.3 https://github.com/statewalker/statewalker-webrun-http-browser Copyright 2023 Mikhail Kotelnikov
2
- (function (global, factory) {
3
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
5
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.statewalker = global.statewalker || {}, global.statewalker["webrun-http-browser"] = global.statewalker["webrun-http-browser"] || {})));
6
- })(this, (function (exports) { 'use strict';
7
-
8
- function serializeError(error) {
9
- return Object.assign({
10
- message: error,
11
- stack: error.stack,
12
- }, error);
13
- }
14
-
15
- function deserializeError(error) {
16
- if (typeof error === "string") {
17
- error = { message: error };
18
- }
19
- return Object.assign(new Error(error.message), error);
20
- }
21
-
22
- async function callChannel(mainChannel, callType, params, ...transfers) {
23
- return new Promise((resolve, reject) => {
24
- const channel = new MessageChannel();
25
- channel.port1.onmessage = (ev) => {
26
- const { result, error } = ev.data;
27
- if (error) reject(deserializeError(error));
28
- else resolve(result);
29
- };
30
- mainChannel.postMessage({ type: callType, params }, [
31
- channel.port2,
32
- ...transfers,
33
- ]);
34
- });
35
- }
36
-
37
- function handleChannelCalls(mainChannel, callType, handler) {
38
- const messageListener = async (event) => {
39
- if (!event.data || event.data.type !== callType) return;
40
- const [port, ...transfers] = event.ports;
41
- let response = {};
42
- try {
43
- const params = event.data.params;
44
- response.result = await handler(event, params, ...transfers);
45
- } catch (error) {
46
- response.error = serializeError(error);
47
- }
48
- port.postMessage(response);
49
- };
50
- mainChannel.addEventListener("message", messageListener);
51
- try {
52
- mainChannel.start && mainChannel.start();
53
- } catch (e) {}
54
- return () => mainChannel.removeEventListener("message", messageListener);
55
- }
56
-
57
- // See https://github.com/agenjs/agen-utils/blob/main/src/iterator.js
58
- async function* iterate(init, queue = []) {
59
- let promise, notify, push = async (error, value, done) => {
60
- const slot = { error, value, done };
61
- slot.promise = new Promise(n => slot.notify = n);
62
- await queue.push(slot);
63
- notify && notify();
64
- notify = null;
65
- return slot.promise;
66
- };
67
- const next = (value) => push(undefined, value, false);
68
- const complete = () => push(undefined, undefined, true);
69
- const error = err => push(err, undefined, true);
70
- const unsubscribe = init(Object.assign([next, complete, error], { next, complete, error }));
71
- let slot;
72
- try {
73
- while (true) {
74
- slot = await queue.shift();
75
- if (slot) {
76
- try {
77
- if (slot.error) { throw slot.error; }
78
- else if (slot.done) { break; }
79
- else { yield slot.value; }
80
- } finally {
81
- slot.notify(true);
82
- }
83
- } else {
84
- await (promise = notify ? promise : new Promise(n => notify = n));
85
- }
86
- }
87
- } finally {
88
- notify && notify();
89
- push = () => false; // Stop pushing in the queue...
90
- ((typeof unsubscribe === 'function') && (await unsubscribe()));
91
- while (slot = await queue.shift()) { slot.notify(false); }
92
- }
93
- }
94
-
95
- function newRegistry(onError = console.error) {
96
- let counter = 0;
97
- const registrations = {};
98
- const register = (action) => {
99
- const id = counter++;
100
- return (registrations[id] = Object.assign(
101
- function (skip) {
102
- try {
103
- delete registrations[id];
104
- return !skip && action && action();
105
- } catch (error) {
106
- onError(error);
107
- }
108
- },
109
- { action }
110
- ));
111
- };
112
- const unregister = (action) =>
113
- Object.values(registrations).forEach((r) => r.action === action && r(true));
114
- const clear = () => Object.values(registrations).forEach((r) => r());
115
- return Object.assign([register, clear, unregister], {
116
- register,
117
- clear,
118
- unregister
119
- });
120
- }
121
-
122
- async function* recieveData(onMessage) {
123
- yield* iterate((iterator) => {
124
- return onMessage(async ({ done = true, value, error } = {}) => {
125
- if (error) {
126
- await iterator.error(error);
127
- } else if (done) {
128
- await iterator.complete();
129
- } else {
130
- await iterator.next(value);
131
- }
132
- });
133
- });
134
- }
135
-
136
- async function sendData(send, it) {
137
- let error;
138
- try {
139
- for await (let value of it) {
140
- await send({ done: false, value });
141
- }
142
- } catch (err) {
143
- error = err;
144
- } finally {
145
- await send({ done: true, error });
146
- }
147
- }
148
-
149
- async function* sendStream(communicationPort, input, params = {}) {
150
- const messageChannel = new MessageChannel();
151
- communicationPort.postMessage({ type: "START_CALL", params }, [
152
- messageChannel.port2,
153
- ]);
154
-
155
- const channel = newChannel(messageChannel.port1);
156
- try {
157
- await channel.start();
158
- channel.sendAll(input);
159
- yield* channel.recieveAll();
160
- } finally {
161
- await channel.close();
162
- }
163
- }
164
-
165
- function handleStreams(communicationPort, handler) {
166
- const listener = async (event) => {
167
- const { type, params } = event.data || {};
168
- if (type !== "START_CALL") return;
169
- const port = event.ports[0];
170
- const channel = newChannel(port);
171
- try {
172
- await channel.start();
173
- const input = channel.recieveAll();
174
- const response = await handler(input, params);
175
- await channel.sendAll(response);
176
- } finally {
177
- await channel.close();
178
- }
179
- };
180
- communicationPort.addEventListener("message", listener);
181
- try {
182
- communicationPort.start && communicationPort.start();
183
- } catch (e) {}
184
- return () => communicationPort.removeEventListener("message", listener);
185
- }
186
-
187
- /**
188
- * This method creates and returns methods allowing to send and recieve data over the specified port.
189
- * The main characteristics of the returned methods is that they properly manage backpressure - sender
190
- * iterators are waiting to send the next value until the previous one is consumed on the other side.
191
- * @param {*} port
192
- * @returns an object with the following methods:
193
- * * `start` - starts the connection over the specified port
194
- * * `close`- stops all iterators and closes the port
195
- * * `recieveAll() : AsyncIterator` - returns an AsyncIterator over all values send by the peer
196
- * * `sendAll(it : AsyncIterator) : Promise<any>` - sends all values defined by the given
197
- * AsyncIterator to the peer
198
- */
199
- function newChannel(port) {
200
- let listeners = [];
201
- let iterators = [];
202
-
203
- const notifyAll = async (data) => {
204
- for (let listener of listeners) {
205
- await listener(data);
206
- }
207
- };
208
- const channel = newInvokationChannel({
209
- port,
210
- handler: notifyAll,
211
- });
212
-
213
- const start = () => channel.start();
214
-
215
- const close = async () => {
216
- await notifyAll({ done: true });
217
- [...iterators].forEach((it) => it.return && it.return());
218
- await channel.close();
219
- };
220
-
221
- async function* recieveAll() {
222
- yield* recieveData((listener) => {
223
- listeners.push(listener);
224
- return () => listeners = listeners.filter((l) => l !== listener);
225
- });
226
- }
227
-
228
- async function sendAll(it) {
229
- await sendData(
230
- channel.invoke,
231
- (async function* () {
232
- try {
233
- iterators.push(it);
234
- yield* it;
235
- } finally {
236
- iterators = iterators.filter((i) => i !== it);
237
- }
238
- })(),
239
- );
240
- }
241
- return {
242
- start,
243
- close,
244
- recieveAll,
245
- sendAll,
246
- };
247
- }
248
-
249
- function newInvokationChannel({
250
- port,
251
- handler = () => {
252
- throw new Error("Handler not implemented");
253
- },
254
- onError = console.error,
255
- newCallId = () =>
256
- newInvokationChannel.__counter = (newInvokationChannel.__counter || 0) + 1,
257
- }) {
258
- const MESSAGE_TYPE_REQUEST = "REQUEST";
259
- const MESSAGE_TYPE_RESPONSE = "RESPONSE";
260
- const EVENT_MESSAGE = "message";
261
-
262
- const requests = {};
263
- const listener = async (event) => {
264
- const data = event.data || {};
265
- const { type, callId } = data;
266
- if (type === MESSAGE_TYPE_REQUEST) {
267
- try {
268
- const { request } = data;
269
- let result = await handler(request, ...(event.ports || []));
270
- const [response, ...transfers] = Array.isArray(result)
271
- ? result
272
- : result !== undefined
273
- ? [result]
274
- : [];
275
- port.postMessage(
276
- { type: MESSAGE_TYPE_RESPONSE, callId, response },
277
- transfers,
278
- );
279
- } catch (error) {
280
- port.postMessage({
281
- type: MESSAGE_TYPE_RESPONSE,
282
- callId,
283
- error: serializeError(error),
284
- });
285
- }
286
- } else if (type === MESSAGE_TYPE_RESPONSE) {
287
- const { callId, response, error } = data;
288
- const request = requests[callId];
289
- delete requests[callId];
290
- if (request) {
291
- error
292
- ? request.reject(deserializeError(error))
293
- : request.resolve(response);
294
- }
295
- }
296
- };
297
-
298
- const start = async () => {
299
- try {
300
- port.addEventListener(EVENT_MESSAGE, listener);
301
- port.start && await port.start();
302
- } catch (e) {
303
- onError(e);
304
- }
305
- };
306
-
307
- const close = async () => {
308
- try {
309
- port.removeEventListener(EVENT_MESSAGE, listener);
310
- port.close && await port.close();
311
- } catch (e) {
312
- onError(e);
313
- }
314
- };
315
-
316
- const invoke = async function (request = {}, ...transfers) {
317
- const callId = newCallId();
318
- return new Promise((resolve, reject) => {
319
- try {
320
- requests[callId] = { resolve, reject };
321
- port.postMessage(
322
- { type: MESSAGE_TYPE_REQUEST, callId, request },
323
- transfers,
324
- );
325
- } catch (error) {
326
- reject(error);
327
- delete request[callId];
328
- }
329
- });
330
- };
331
-
332
- return {
333
- start,
334
- close,
335
- invoke,
336
- };
337
- }
338
-
339
- function toReadableStream(it) {
340
- return new ReadableStream({
341
- type: "bytes",
342
- async pull(controller) {
343
- let handled = false;
344
- try {
345
- while (true) {
346
- const slot = await it.next();
347
- if (!slot || slot.done) {
348
- break;
349
- }
350
- controller.enqueue(await slot.value);
351
- }
352
- } catch (error) {
353
- handled = true;
354
- controller.error(error);
355
- } finally {
356
- !handled && controller.close();
357
- }
358
- },
359
- });
360
- }
361
-
362
- async function* fromReadableStream(stream) {
363
- const reader = await stream.getReader();
364
- let done, value;
365
- while (({ done, value } = await reader.read())) {
366
- if (done) {
367
- break;
368
- }
369
- yield await value;
370
- }
371
- }
372
-
373
- /**
374
- * This method returns an HTTP handlers transforming
375
- * HTTP Request instances to binary representations and
376
- * sending them to a transport layer.
377
- * Results of these transport ivokations are deserialized
378
- * as meaningful Response instances and returned back to the caller.
379
- *
380
- * The specified `send` method is used to dispatch serialized
381
- * requests to return the serialized remote results.
382
- * This transport method accepts and returns objects with
383
- * the same structure:
384
- * * `options` - contains serialized request or response parameters
385
- * * `content` - an async iterator over binary blocks for
386
- * the request or response
387
- *
388
- * @param {*} send transport function accepting serialized requests
389
- * and returning back serialized responses
390
- * @returns an async handler accepting standard
391
- * HTTP `Request` instances and returning `Response` instances
392
- */
393
- function newHttpClientStub(send) {
394
- return async (request) => {
395
- request = await request;
396
- const fields = [
397
- "url",
398
- "method",
399
- "mode",
400
- "credentials",
401
- "cache",
402
- "redirect",
403
- "referrer",
404
- "referrerPolicy",
405
- "integrity",
406
- "keepalive"
407
- ];
408
- const headers = [...request.headers].map(([key, value]) => {
409
- return [key, value]
410
- });
411
- const requestOptions = fields.reduce((options, key) => {
412
- const val = request[key];
413
- if (val !== undefined) options[key] = val;
414
- return options;
415
- }, {
416
- headers
417
- });
418
- const requestContent = (request.body)
419
- ? fromReadableStream(request.body)
420
- : [];
421
- const result = await send({
422
- options: requestOptions,
423
- content: requestContent,
424
- });
425
- let responseBody = null;
426
- let responseOptions = {};
427
- if (!result) {
428
- responseOptions = {
429
- status: 404,
430
- statusText: "Error 404: Not Found",
431
- };
432
- } else {
433
- responseOptions = result.options;
434
- const responseContent = result.content;
435
- if (
436
- requestOptions.method !== "HEAD" &&
437
- requestOptions.method !== "OPTIONS"
438
- ) {
439
- responseBody = toReadableStream(responseContent);
440
- } else if (responseContent && responseContent.return) {
441
- responseContent.return();
442
- }
443
- }
444
- return new Response(responseBody, responseOptions);
445
- };
446
- }
447
-
448
- /**
449
- * This method returns the server-side call handler transforming
450
- * serialized requests to HTTP Request instances, delegating
451
- * their handing to the given `handler` method. This handler
452
- * should handle the HTTP request and return a valid Response instance.
453
- * The resulting instance is serialized as an object with the same
454
- * structure as the initial serialized request:
455
- * - `options` - contains serialized request or response parameters
456
- * - `content` - an async iterator over binary blocks for
457
- * the request or response
458
- * @param {*} handler this handler method accepts standard HTTP Request
459
- * and returns back an HTTP Response instance
460
- * @returns a method deserializing HTTP requests and returning back
461
- * serialized HTTP responses
462
- */
463
- function newHttpServerStub(handler) {
464
- return async (params) => {
465
- const {
466
- options: requestOptions,
467
- content: requestContent,
468
- } = await params;
469
- let requestBody = undefined;
470
- const { url, mode, headers = [] } = requestOptions;
471
- const requestHeaders = new Headers();
472
- for (let [key, value] of headers) {
473
- requestHeaders.append(key, value);
474
- }
475
- delete requestOptions.mode;
476
- delete requestOptions.url;
477
- if (
478
- requestOptions.method !== "GET" &&
479
- requestOptions.method !== "HEAD" &&
480
- requestOptions.method !== "OPTIONS"
481
- ) {
482
- requestBody = toReadableStream(requestContent);
483
- requestOptions.duplex = "half";
484
- } else if (requestContent && requestContent.return) {
485
- requestContent.return();
486
- }
487
- const request = new Request(url, {
488
- ...requestOptions,
489
- headers: requestHeaders,
490
- // duplex: 'full',
491
- body: requestBody,
492
- });
493
- const response = await handler(request);
494
- const responseOptions = {
495
- status: response.status,
496
- statusText: response.statusText,
497
- headers: Object.fromEntries([...response.headers]),
498
- };
499
- const responseContent = await fromReadableStream(await response.body);
500
- return {
501
- options: responseOptions,
502
- content: responseContent,
503
- };
504
- };
505
- }
506
-
507
- async function* httpToIterator(params) {
508
- const { options, content } = await params;
509
- const encoder = new TextEncoder();
510
- yield encoder.encode(JSON.stringify(options));
511
- yield* content;
512
- }
513
-
514
- async function httpFromIterator(it) {
515
- it = await it;
516
- const { done, value } = await it.next();
517
- let options = {};
518
- if (!done && value) {
519
- const decoder = new TextDecoder();
520
- const str = decoder.decode(value);
521
- options = JSON.parse(str);
522
- }
523
- return {
524
- options,
525
- content: it,
526
- };
527
- }
528
-
529
- function handleHttpRequests(communicationPort, handler) {
530
- const serverStub = newHttpServerStub(handler);
531
- return handleStreams(communicationPort, (it) => {
532
- return httpToIterator(serverStub(httpFromIterator(it)));
533
- });
534
- }
535
-
536
- async function sendHttpRequest(communicationPort, request) {
537
- const clientStub = newHttpClientStub(async (req) => {
538
- return await httpFromIterator(
539
- sendStream(communicationPort, httpToIterator(req)),
540
- );
541
- });
542
- return await clientStub(request);
543
- }
544
-
545
- function splitServiceUrl(url, separator = "~") {
546
- let key = "";
547
- let path = "";
548
- let str = url + "";
549
- const idx = str.indexOf(separator);
550
- let baseUrl = "";
551
- if (idx >= 0) {
552
- baseUrl = str.substring(0, idx + separator.length);
553
- str.substring(idx + separator.length)
554
- .replace(/^([^\/]+)/, (match, $1) => {
555
- baseUrl += match;
556
- if (baseUrl.length < str.length) baseUrl += "/";
557
- key = $1;
558
- path = str.substring(baseUrl.length);
559
- return "";
560
- });
561
- }
562
- return {
563
- url,
564
- key,
565
- baseUrl,
566
- path,
567
- };
568
- }
569
-
570
- function newServiceWorkerPort() {
571
- // Bind the service worker to
572
- const channel = new MessageChannel();
573
- channel.port1.onmessage = (event) => {
574
- navigator.serviceWorker.controller.postMessage(event.data, event.ports);
575
- };
576
- navigator.serviceWorker.addEventListener("message", (event) => {
577
- channel.port1.postMessage(event.data, event.ports);
578
- });
579
- return channel.port2;
580
- }
581
-
582
- async function initServiceWorker1({ swUrl, scopeUrl, type }) {
583
- const {
584
- installing,
585
- waiting,
586
- active,
587
- } = await navigator.serviceWorker.register(swUrl, {
588
- // type: "module",
589
- scope: scopeUrl,
590
- });
591
- (installing || waiting || active).addEventListener("statechange", (e) => {
592
- console.log("state", e.target.state);
593
- });
594
-
595
- const serviceWorker = navigator.serviceWorker;
596
- await new Promise((resolve) => {
597
- // Resolve right away if this page is already controlled.
598
- if (serviceWorker.controller) {
599
- resolve();
600
- } else {
601
- const onChange = () => {
602
- resolve();
603
- serviceWorker.removeEventListener("controllerchange", onChange);
604
- serviceWorker.oncontrollerchange = null;
605
- };
606
- serviceWorker.addEventListener("controllerchange", onChange);
607
- serviceWorker.oncontrollerchange = onChange;
608
- }
609
- });
610
- const worker = serviceWorker.controller;
611
- const isActivated = () => worker.state === "activated";
612
- return await new Promise(async (resolve) => {
613
- if (isActivated()) resolve(worker);
614
- else {
615
- worker.onstatechange = () => {
616
- if (!isActivated()) return;
617
- worker.onstatechange = null;
618
- resolve(worker);
619
- };
620
- }
621
- });
622
- }
623
-
624
- async function initServiceWorker({ swUrl, scopeUrl, type }) {
625
- await navigator.serviceWorker.register(swUrl, {
626
- type,
627
- scope: scopeUrl,
628
- });
629
- const worker = await getServiceWorkerController();
630
- await awaitServiceWorkerActivation(worker);
631
- return worker;
632
-
633
- async function getServiceWorkerController() {
634
- return await new Promise((resolve) => {
635
- // Resolve right away if this page is already controlled.
636
- const serviceWorker = navigator.serviceWorker;
637
- if (serviceWorker.controller) {
638
- resolve(serviceWorker.controller);
639
- } else {
640
- const onChange = () => {
641
- resolve(serviceWorker.controller);
642
- serviceWorker.removeEventListener("controllerchange", onChange);
643
- serviceWorker.oncontrollerchange = null;
644
- };
645
- serviceWorker.addEventListener("controllerchange", onChange);
646
- serviceWorker.oncontrollerchange = onChange;
647
- }
648
- });
649
- }
650
-
651
- // ------------------------------
652
- // Await until the service is ready
653
- async function awaitServiceWorkerActivation(worker) {
654
- const isActivated = () => worker.state === "activated";
655
- await new Promise(async (resolve) => {
656
- if (isActivated()) resolve();
657
- else {
658
- worker.onstatechange = () => {
659
- if (!isActivated()) return;
660
- worker.onstatechange = null;
661
- resolve();
662
- };
663
- }
664
- });
665
- }
666
- }
667
-
668
- async function initHttpService(handler, {
669
- key,
670
- port,
671
- }) {
672
- return await registerConnectionsHandler({
673
- key,
674
- communicationPort: port,
675
- handler: async (event, data, callPort) => {
676
- handleHttpRequests(callPort, handler);
677
- return true;
678
- },
679
- });
680
- }
681
-
682
- async function callHttpService(request, {
683
- key,
684
- port,
685
- }) {
686
- const callPort = await initializeConnection({
687
- key,
688
- communicationPort: port,
689
- });
690
- const result = await sendHttpRequest(callPort, request);
691
- return result;
692
- }
693
-
694
- function getRelayWindowMessageHandler({
695
- swUrl = new URL("./index-sw.js", (typeof document === 'undefined' && typeof location === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : typeof document === 'undefined' ? location.href : (document.currentScript && document.currentScript.src || new URL('index-umd.js', document.baseURI).href))) + "",
696
- scopeUrl = new URL("../", (typeof document === 'undefined' && typeof location === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : typeof document === 'undefined' ? location.href : (document.currentScript && document.currentScript.src || new URL('index-umd.js', document.baseURI).href))) + "",
697
- } = {}) {
698
- let externalPort;
699
- return async (ev) => {
700
- if (ev.data.type === "CONNECT") {
701
- const newExternalPort = (ev.ports || [])[0];
702
- if (externalPort) {
703
- newExternalPort.close();
704
- return;
705
- }
706
- externalPort = newExternalPort;
707
- await initServiceWorker({
708
- swUrl,
709
- scopeUrl,
710
- });
711
- const serviceWorkerPort = newServiceWorkerPort();
712
- serviceWorkerPort.onmessage = (event) => {
713
- externalPort.postMessage(event.data, event.ports);
714
- };
715
-
716
- externalPort.onmessage = (event) => {
717
- serviceWorkerPort.postMessage(event.data, event.ports);
718
- };
719
- }
720
- };
721
- }
722
-
723
- async function newRemoteRelayChannel({
724
- baseUrl = new URL("../public-relay/", (typeof document === 'undefined' && typeof location === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : typeof document === 'undefined' ? location.href : (document.currentScript && document.currentScript.src || new URL('index-umd.js', document.baseURI).href))),
725
- url = new URL("relay.html", baseUrl),
726
- container = document.body,
727
- } = {}) {
728
- const messageChannel = new MessageChannel();
729
- const { iframe, promise } = await newIFrame(url);
730
- Object.assign(iframe.style, {
731
- // height: "100px"
732
- position: "fixed",
733
- width: "1px",
734
- height: "1px",
735
- top: "-1000",
736
- left: "-1000",
737
- display: "block",
738
- opacity: "0",
739
- border: "none",
740
- outline: "none",
741
- });
742
- container.appendChild(iframe);
743
- promise.then(() => {
744
- iframe.contentWindow.postMessage(
745
- {
746
- type: "CONNECT",
747
- },
748
- "*",
749
- [messageChannel.port1],
750
- );
751
- });
752
- return {
753
- baseUrl,
754
- port: messageChannel.port2,
755
- close: () => {
756
- iframe.parentElement && iframe.parentElement.removeChild(iframe);
757
- messageChannel.port1.close();
758
- messageChannel.port2.close();
759
- },
760
- };
761
-
762
- async function newIFrame(url) {
763
- const iframe = document.createElement("iframe");
764
- iframe.src = url;
765
- Object.assign(iframe.style, {
766
- padding: 0,
767
- margin: 0,
768
- border: "none",
769
- outline: "none",
770
- width: "100%",
771
- height: "100%",
772
- });
773
- return {
774
- iframe,
775
- promise: new Promise((resolve, reject) => {
776
- try {
777
- iframe.onerror = reject;
778
- iframe.onload = () => resolve(iframe);
779
- } catch (error) {
780
- reject(error);
781
- }
782
- }),
783
- };
784
- }
785
- }
786
- // -------------------------------------------------------
787
-
788
- async function initializeConnection({
789
- key,
790
- communicationPort,
791
- ...options
792
- }) {
793
- const channel = new MessageChannel();
794
- const accepted = await callChannel(
795
- communicationPort,
796
- "CONNECT",
797
- { key, ...options },
798
- channel.port2,
799
- );
800
- if (!accepted) {
801
- channel.port1.close();
802
- channel.port2.close();
803
- return null;
804
- }
805
- return channel.port1;
806
- }
807
-
808
- async function registerConnectionsHandler({
809
- key,
810
- handler,
811
- communicationPort,
812
- }) {
813
- const [register, cleanup] = newRegistry();
814
- await callChannel(communicationPort, "REGISTER", { key });
815
- register(() => callChannel(communicationPort, "UNREGISTER", { key }));
816
- register(
817
- handleChannelCalls(
818
- communicationPort,
819
- "CONNECT",
820
- handler,
821
- ),
822
- );
823
- return cleanup;
824
- }
825
-
826
- exports.callChannel = callChannel;
827
- exports.callHttpService = callHttpService;
828
- exports.deserializeError = deserializeError;
829
- exports.fromReadableStream = fromReadableStream;
830
- exports.getRelayWindowMessageHandler = getRelayWindowMessageHandler;
831
- exports.handleChannelCalls = handleChannelCalls;
832
- exports.handleHttpRequests = handleHttpRequests;
833
- exports.handleStreams = handleStreams;
834
- exports.initHttpService = initHttpService;
835
- exports.initServiceWorker = initServiceWorker;
836
- exports.initServiceWorker1 = initServiceWorker1;
837
- exports.initializeConnection = initializeConnection;
838
- exports.newHttpClientStub = newHttpClientStub;
839
- exports.newHttpServerStub = newHttpServerStub;
840
- exports.newInvokationChannel = newInvokationChannel;
841
- exports.newRegistry = newRegistry;
842
- exports.newRemoteRelayChannel = newRemoteRelayChannel;
843
- exports.newServiceWorkerPort = newServiceWorkerPort;
844
- exports.recieveData = recieveData;
845
- exports.registerConnectionsHandler = registerConnectionsHandler;
846
- exports.sendData = sendData;
847
- exports.sendHttpRequest = sendHttpRequest;
848
- exports.sendStream = sendStream;
849
- exports.serializeError = serializeError;
850
- exports.splitServiceUrl = splitServiceUrl;
851
- exports.toReadableStream = toReadableStream;
852
-
853
- }));