@statewalker/webrun-http-browser 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index-sw-umd.js +413 -270
- package/dist/index-sw-umd.min.js +2 -2
- package/dist/index-sw.js +409 -265
- package/dist/index-sw.min.js +2 -2
- package/dist/index-umd.js +286 -417
- package/dist/index-umd.min.js +2 -2
- package/dist/index.js +277 -412
- package/dist/index.min.js +2 -2
- package/package.json +1 -1
- package/public/index.html +61 -93
- package/public-relay/heartbeat.js +1 -1
- package/public-relay/relay-sw.js +6 -343
- package/public-relay/relay.html +5 -26
- package/src/{data-channels.js → core/data-channels.js} +26 -10
- package/src/core/index.js +4 -0
- package/src/http/HttpError.js +59 -0
- package/src/{http-send-recieve.js → http/http-send-recieve.js} +1 -1
- package/src/http/index.js +3 -0
- package/src/index.js +4 -9
- package/src/relay/index-sw.js +216 -0
- package/{public-relay/relay-lib.js → src/relay/index.js} +80 -6
- package/src/relay/splitServiceUrl.js +24 -0
- package/src/{http-sw-dispatcher.js → sw/http-sw-dispatcher.js} +1 -1
- package/src/{sw-dispatcher.js → sw/sw-dispatcher.js} +1 -1
- package/public/abc.txt +0 -1
- package/public/index-service-worker.js +0 -1
- /package/src/{data-calls.js → core/data-calls.js} +0 -0
- /package/src/{data-send-recieve.js → core/data-send-recieve.js} +0 -0
- /package/src/{errors.js → core/errors.js} +0 -0
- /package/src/{http-stubs.js → http/http-stubs.js} +0 -0
- /package/src/{readable-streams.js → http/readable-streams.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @statewalker/webrun-http-browser v0.
|
|
1
|
+
// @statewalker/webrun-http-browser v0.2.0 https://github.com/statewalker/statewalker-webrun-http-browser Copyright 2023 Mikhail Kotelnikov
|
|
2
2
|
function serializeError(error) {
|
|
3
3
|
return Object.assign({
|
|
4
4
|
message: error,
|
|
@@ -199,7 +199,10 @@ function newChannel(port) {
|
|
|
199
199
|
await listener(data);
|
|
200
200
|
}
|
|
201
201
|
};
|
|
202
|
-
const channel = newInvokationChannel(
|
|
202
|
+
const channel = newInvokationChannel({
|
|
203
|
+
port,
|
|
204
|
+
handler: notifyAll,
|
|
205
|
+
});
|
|
203
206
|
|
|
204
207
|
const start = () => channel.start();
|
|
205
208
|
|
|
@@ -237,15 +240,20 @@ function newChannel(port) {
|
|
|
237
240
|
};
|
|
238
241
|
}
|
|
239
242
|
|
|
240
|
-
function newInvokationChannel(
|
|
241
|
-
|
|
243
|
+
function newInvokationChannel({
|
|
244
|
+
port,
|
|
245
|
+
handler = () => {
|
|
246
|
+
throw new Error("Handler not implemented");
|
|
247
|
+
},
|
|
248
|
+
onError = console.error,
|
|
249
|
+
newCallId = () =>
|
|
250
|
+
newInvokationChannel.__counter = (newInvokationChannel.__counter || 0) + 1,
|
|
242
251
|
}) {
|
|
243
252
|
const MESSAGE_TYPE_REQUEST = "REQUEST";
|
|
244
253
|
const MESSAGE_TYPE_RESPONSE = "RESPONSE";
|
|
245
254
|
const EVENT_MESSAGE = "message";
|
|
246
255
|
|
|
247
256
|
const requests = {};
|
|
248
|
-
let requestCounter = 0;
|
|
249
257
|
const listener = async (event) => {
|
|
250
258
|
const data = event.data || {};
|
|
251
259
|
const { type, callId } = data;
|
|
@@ -282,17 +290,25 @@ function newInvokationChannel(port, handler = () => {
|
|
|
282
290
|
};
|
|
283
291
|
|
|
284
292
|
const start = async () => {
|
|
285
|
-
|
|
286
|
-
|
|
293
|
+
try {
|
|
294
|
+
port.addEventListener(EVENT_MESSAGE, listener);
|
|
295
|
+
port.start && await port.start();
|
|
296
|
+
} catch (e) {
|
|
297
|
+
onError(e);
|
|
298
|
+
}
|
|
287
299
|
};
|
|
288
300
|
|
|
289
301
|
const close = async () => {
|
|
290
|
-
|
|
291
|
-
|
|
302
|
+
try {
|
|
303
|
+
port.removeEventListener(EVENT_MESSAGE, listener);
|
|
304
|
+
port.close && await port.close();
|
|
305
|
+
} catch (e) {
|
|
306
|
+
onError(e);
|
|
307
|
+
}
|
|
292
308
|
};
|
|
293
309
|
|
|
294
310
|
const invoke = async function (request = {}, ...transfers) {
|
|
295
|
-
const callId =
|
|
311
|
+
const callId = newCallId();
|
|
296
312
|
return new Promise((resolve, reject) => {
|
|
297
313
|
try {
|
|
298
314
|
requests[callId] = { resolve, reject };
|
|
@@ -511,435 +527,284 @@ async function sendHttpRequest(communicationPort, request) {
|
|
|
511
527
|
return await clientStub(request);
|
|
512
528
|
}
|
|
513
529
|
|
|
514
|
-
function
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!defaultGetStoreFunc) {
|
|
531
|
-
defaultGetStoreFunc = createStore('keyval-store', 'keyval');
|
|
532
|
-
}
|
|
533
|
-
return defaultGetStoreFunc;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Get a value by its key.
|
|
537
|
-
*
|
|
538
|
-
* @param key
|
|
539
|
-
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
|
540
|
-
*/
|
|
541
|
-
function get(key, customStore = defaultGetStore()) {
|
|
542
|
-
return customStore('readonly', (store) => promisifyRequest(store.get(key)));
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Set a value with a key.
|
|
546
|
-
*
|
|
547
|
-
* @param key
|
|
548
|
-
* @param value
|
|
549
|
-
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
|
550
|
-
*/
|
|
551
|
-
function set(key, value, customStore = defaultGetStore()) {
|
|
552
|
-
return customStore('readwrite', (store) => {
|
|
553
|
-
store.put(value, key);
|
|
554
|
-
return promisifyRequest(store.transaction);
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
class SwPortHandler {
|
|
559
|
-
constructor(options) {
|
|
560
|
-
this.options = options;
|
|
561
|
-
if (!this.key) throw new Error("Key is not defined.");
|
|
562
|
-
if (!this.scope) throw new Error("Scope is not defined");
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
get key() {
|
|
566
|
-
return this.options.key;
|
|
530
|
+
function splitServiceUrl(url, separator = "~") {
|
|
531
|
+
let key = "";
|
|
532
|
+
let path = "";
|
|
533
|
+
let str = url + "";
|
|
534
|
+
const idx = str.indexOf(separator);
|
|
535
|
+
let baseUrl = "";
|
|
536
|
+
if (idx >= 0) {
|
|
537
|
+
baseUrl = str.substring(0, idx + separator.length);
|
|
538
|
+
str.substring(idx + separator.length)
|
|
539
|
+
.replace(/^([^\/]+)/, (match, $1) => {
|
|
540
|
+
baseUrl += match;
|
|
541
|
+
if (baseUrl.length < str.length) baseUrl += "/";
|
|
542
|
+
key = $1;
|
|
543
|
+
path = str.substring(baseUrl.length);
|
|
544
|
+
return "";
|
|
545
|
+
});
|
|
567
546
|
}
|
|
547
|
+
return {
|
|
548
|
+
url,
|
|
549
|
+
key,
|
|
550
|
+
baseUrl,
|
|
551
|
+
path,
|
|
552
|
+
};
|
|
553
|
+
}
|
|
568
554
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
555
|
+
function newServiceWorkerPort() {
|
|
556
|
+
// Bind the service worker to
|
|
557
|
+
const channel = new MessageChannel();
|
|
558
|
+
channel.port1.onmessage = (event) => {
|
|
559
|
+
navigator.serviceWorker.controller.postMessage(event.data, event.ports);
|
|
560
|
+
};
|
|
561
|
+
navigator.serviceWorker.addEventListener("message", (event) => {
|
|
562
|
+
channel.port1.postMessage(event.data, event.ports);
|
|
563
|
+
});
|
|
564
|
+
return channel.port2;
|
|
565
|
+
}
|
|
572
566
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
567
|
+
async function initServiceWorker1({ swUrl, scopeUrl, type }) {
|
|
568
|
+
const {
|
|
569
|
+
installing,
|
|
570
|
+
waiting,
|
|
571
|
+
active,
|
|
572
|
+
} = await navigator.serviceWorker.register(swUrl, {
|
|
573
|
+
// type: "module",
|
|
574
|
+
scope: scopeUrl,
|
|
575
|
+
});
|
|
576
|
+
(installing || waiting || active).addEventListener("statechange", (e) => {
|
|
577
|
+
console.log("state", e.target.state);
|
|
578
|
+
});
|
|
576
579
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
580
|
+
const serviceWorker = navigator.serviceWorker;
|
|
581
|
+
await new Promise((resolve) => {
|
|
582
|
+
// Resolve right away if this page is already controlled.
|
|
583
|
+
if (serviceWorker.controller) {
|
|
584
|
+
resolve();
|
|
585
|
+
} else {
|
|
586
|
+
const onChange = () => {
|
|
587
|
+
resolve();
|
|
588
|
+
serviceWorker.removeEventListener("controllerchange", onChange);
|
|
589
|
+
serviceWorker.oncontrollerchange = null;
|
|
590
|
+
};
|
|
591
|
+
serviceWorker.addEventListener("controllerchange", onChange);
|
|
592
|
+
serviceWorker.oncontrollerchange = onChange;
|
|
583
593
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
async
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
async _updateCommunicationChannel() {
|
|
597
|
-
// console.log("[_updateCommunicationChannel]", this._serviceWorker);
|
|
598
|
-
if (!this._serviceWorker) return;
|
|
599
|
-
const [port1, port2] = await this._newCommunicationChannel();
|
|
600
|
-
await this._setCommunicationPort(port1);
|
|
601
|
-
await callChannel(
|
|
602
|
-
this._serviceWorker,
|
|
603
|
-
"UPDATE_COMMUNICATION_PORT",
|
|
604
|
-
this._getRegistrationInfo(),
|
|
605
|
-
port2,
|
|
606
|
-
);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
_getRegistrationInfo() {
|
|
610
|
-
return { key: this.key };
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* Starts the server.
|
|
615
|
-
*/
|
|
616
|
-
async start() {
|
|
617
|
-
return this._registrationPromise = this._registrationPromise ||
|
|
618
|
-
(async () => {
|
|
619
|
-
const [register, cleanup] = newRegistry();
|
|
620
|
-
this._cleanupRegistrations = cleanup;
|
|
621
|
-
register(() => this._cleanupRegistrations = null);
|
|
622
|
-
const registration = await navigator.serviceWorker.register(
|
|
623
|
-
this.serviceWorkerUrl,
|
|
624
|
-
{
|
|
625
|
-
// type: "module",
|
|
626
|
-
scope: this.scope,
|
|
627
|
-
},
|
|
628
|
-
);
|
|
629
|
-
register(() => registration.unregister());
|
|
630
|
-
|
|
631
|
-
// (example: when the service worker is the same but it is waked up/activated after an idle period)
|
|
632
|
-
register(
|
|
633
|
-
handleChannelCalls(
|
|
634
|
-
navigator.serviceWorker,
|
|
635
|
-
"UPDATE_COMMUNICATION_PORT",
|
|
636
|
-
async (event, params, port) => {
|
|
637
|
-
console.log("[UPDATE_COMMUNICATION_PORT]", port);
|
|
638
|
-
this._setCommunicationPort(port);
|
|
639
|
-
return this._getRegistrationInfo();
|
|
640
|
-
},
|
|
641
|
-
),
|
|
642
|
-
);
|
|
643
|
-
|
|
644
|
-
this._serviceWorker = await getServiceWorkerController();
|
|
645
|
-
await awaitServiceWorkerActivation(this._serviceWorker);
|
|
646
|
-
await this._updateCommunicationChannel();
|
|
647
|
-
|
|
648
|
-
async function getServiceWorkerController() {
|
|
649
|
-
return await new Promise((resolve) => {
|
|
650
|
-
// Resolve right away if this page is already controlled.
|
|
651
|
-
const serviceWorker = navigator.serviceWorker;
|
|
652
|
-
if (serviceWorker.controller) {
|
|
653
|
-
resolve(serviceWorker.controller);
|
|
654
|
-
} else {
|
|
655
|
-
const onChange = () => {
|
|
656
|
-
resolve(serviceWorker.controller);
|
|
657
|
-
serviceWorker.removeEventListener("controllerchange", onChange);
|
|
658
|
-
serviceWorker.oncontrollerchange = null;
|
|
659
|
-
};
|
|
660
|
-
serviceWorker.addEventListener("controllerchange", onChange);
|
|
661
|
-
serviceWorker.oncontrollerchange = onChange;
|
|
662
|
-
}
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// ------------------------------
|
|
667
|
-
// Await until the service is ready
|
|
668
|
-
async function awaitServiceWorkerActivation(worker) {
|
|
669
|
-
const isActivated = () => worker.state === "activated";
|
|
670
|
-
await new Promise(async (resolve) => {
|
|
671
|
-
if (isActivated()) resolve();
|
|
672
|
-
else {
|
|
673
|
-
worker.onstatechange = () => {
|
|
674
|
-
if (!isActivated()) return;
|
|
675
|
-
worker.onstatechange = null;
|
|
676
|
-
resolve();
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
})();
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* Stops the server and removes associated handlers.
|
|
686
|
-
*/
|
|
687
|
-
async stop() {
|
|
688
|
-
if (this._cleanupRegistrations) this._cleanupRegistrations();
|
|
689
|
-
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
690
|
-
for (let registration of registrations) {
|
|
691
|
-
try {
|
|
692
|
-
await registration.unregister();
|
|
693
|
-
} catch (error) {
|
|
694
|
-
console.log("Service Worker registration failed: ", error);
|
|
695
|
-
}
|
|
594
|
+
});
|
|
595
|
+
const worker = serviceWorker.controller;
|
|
596
|
+
const isActivated = () => worker.state === "activated";
|
|
597
|
+
return await new Promise(async (resolve) => {
|
|
598
|
+
if (isActivated()) resolve(worker);
|
|
599
|
+
else {
|
|
600
|
+
worker.onstatechange = () => {
|
|
601
|
+
if (!isActivated()) return;
|
|
602
|
+
worker.onstatechange = null;
|
|
603
|
+
resolve(worker);
|
|
604
|
+
};
|
|
696
605
|
}
|
|
697
|
-
}
|
|
606
|
+
});
|
|
698
607
|
}
|
|
699
608
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
status: 410,
|
|
724
|
-
});
|
|
609
|
+
async function initServiceWorker({ swUrl, scopeUrl, type }) {
|
|
610
|
+
await navigator.serviceWorker.register(swUrl, {
|
|
611
|
+
type,
|
|
612
|
+
scope: scopeUrl,
|
|
613
|
+
});
|
|
614
|
+
const worker = await getServiceWorkerController();
|
|
615
|
+
await awaitServiceWorkerActivation(worker);
|
|
616
|
+
return worker;
|
|
617
|
+
|
|
618
|
+
async function getServiceWorkerController() {
|
|
619
|
+
return await new Promise((resolve) => {
|
|
620
|
+
// Resolve right away if this page is already controlled.
|
|
621
|
+
const serviceWorker = navigator.serviceWorker;
|
|
622
|
+
if (serviceWorker.controller) {
|
|
623
|
+
resolve(serviceWorker.controller);
|
|
624
|
+
} else {
|
|
625
|
+
const onChange = () => {
|
|
626
|
+
resolve(serviceWorker.controller);
|
|
627
|
+
serviceWorker.removeEventListener("controllerchange", onChange);
|
|
628
|
+
serviceWorker.oncontrollerchange = null;
|
|
629
|
+
};
|
|
630
|
+
serviceWorker.addEventListener("controllerchange", onChange);
|
|
631
|
+
serviceWorker.oncontrollerchange = onChange;
|
|
725
632
|
}
|
|
726
|
-
result = channelInfo;
|
|
727
|
-
break;
|
|
728
|
-
}
|
|
729
|
-
return result;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
start() {
|
|
733
|
-
this._cleanup = handleChannelCalls(
|
|
734
|
-
this.self,
|
|
735
|
-
"UPDATE_COMMUNICATION_PORT",
|
|
736
|
-
async (event, channelInfo, port) => {
|
|
737
|
-
const clientId = event.source.id;
|
|
738
|
-
this.log("[UPDATE_COMMUNICATION_PORT]", clientId, channelInfo);
|
|
739
|
-
await this._updateChannelInfo({ ...channelInfo, port, clientId });
|
|
740
|
-
return { ...channelInfo };
|
|
741
|
-
},
|
|
742
|
-
);
|
|
743
|
-
this.self.onmessage = () => {};
|
|
744
|
-
|
|
745
|
-
this.self.addEventListener("install", (event) => {
|
|
746
|
-
this.log("Skip waiting on install.", event);
|
|
747
|
-
this.self.skipWaiting();
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
this.self.addEventListener("activate", async (event) => {
|
|
751
|
-
this.log(
|
|
752
|
-
"Claim control over all clients.",
|
|
753
|
-
event,
|
|
754
|
-
clients,
|
|
755
|
-
this.self.clients,
|
|
756
|
-
);
|
|
757
|
-
event.waitUntil((async () => {
|
|
758
|
-
await this.self.clients.claim();
|
|
759
|
-
await this._checkActivation();
|
|
760
|
-
})());
|
|
761
633
|
});
|
|
762
634
|
}
|
|
763
635
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
636
|
+
// ------------------------------
|
|
637
|
+
// Await until the service is ready
|
|
638
|
+
async function awaitServiceWorkerActivation(worker) {
|
|
639
|
+
const isActivated = () => worker.state === "activated";
|
|
640
|
+
await new Promise(async (resolve) => {
|
|
641
|
+
if (isActivated()) resolve();
|
|
642
|
+
else {
|
|
643
|
+
worker.onstatechange = () => {
|
|
644
|
+
if (!isActivated()) return;
|
|
645
|
+
worker.onstatechange = null;
|
|
646
|
+
resolve();
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
});
|
|
774
650
|
}
|
|
651
|
+
}
|
|
775
652
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
}
|
|
790
|
-
}
|
|
653
|
+
async function initHttpService(handler, {
|
|
654
|
+
key,
|
|
655
|
+
port,
|
|
656
|
+
}) {
|
|
657
|
+
return await registerConnectionsHandler({
|
|
658
|
+
key,
|
|
659
|
+
communicationPort: port,
|
|
660
|
+
handler: async (event, data, callPort) => {
|
|
661
|
+
handleHttpRequests(callPort, handler);
|
|
662
|
+
return true;
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
}
|
|
791
666
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
667
|
+
async function callHttpService(request, {
|
|
668
|
+
key,
|
|
669
|
+
port,
|
|
670
|
+
}) {
|
|
671
|
+
const callPort = await initializeConnection({
|
|
672
|
+
key,
|
|
673
|
+
communicationPort: port,
|
|
674
|
+
});
|
|
675
|
+
const result = await sendHttpRequest(callPort, request);
|
|
676
|
+
return result;
|
|
677
|
+
}
|
|
797
678
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
679
|
+
function getRelayWindowMessageHandler({
|
|
680
|
+
swUrl = new URL("./index-sw.js", import.meta.url) + "",
|
|
681
|
+
scopeUrl = new URL("../", import.meta.url) + "",
|
|
682
|
+
} = {}) {
|
|
683
|
+
let externalPort;
|
|
684
|
+
return async (ev) => {
|
|
685
|
+
if (ev.data.type === "CONNECT") {
|
|
686
|
+
const newExternalPort = (ev.ports || [])[0];
|
|
687
|
+
if (externalPort) {
|
|
688
|
+
newExternalPort.close();
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
externalPort = newExternalPort;
|
|
692
|
+
await initServiceWorker({
|
|
693
|
+
swUrl,
|
|
694
|
+
scopeUrl,
|
|
695
|
+
});
|
|
696
|
+
const serviceWorkerPort = newServiceWorkerPort();
|
|
697
|
+
serviceWorkerPort.onmessage = (event) => {
|
|
698
|
+
externalPort.postMessage(event.data, event.ports);
|
|
699
|
+
};
|
|
802
700
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
clientIds.add(clientId);
|
|
807
|
-
}
|
|
808
|
-
const index = new Map();
|
|
809
|
-
for (let clientId of clientIds) {
|
|
810
|
-
const client = await this.self.clients.get(clientId);
|
|
811
|
-
if (client) index.set(clientId, client);
|
|
812
|
-
else this.handlersIndex.delete(clientId);
|
|
701
|
+
externalPort.onmessage = (event) => {
|
|
702
|
+
serviceWorkerPort.postMessage(event.data, event.ports);
|
|
703
|
+
};
|
|
813
704
|
}
|
|
814
|
-
|
|
815
|
-
return index;
|
|
816
|
-
}
|
|
705
|
+
};
|
|
817
706
|
}
|
|
818
707
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
708
|
+
async function newRemoteRelayChannel({
|
|
709
|
+
baseUrl = new URL("./", import.meta.url),
|
|
710
|
+
url = new URL("./relay.html", baseUrl),
|
|
711
|
+
container = document.body,
|
|
712
|
+
} = {}) {
|
|
713
|
+
const messageChannel = new MessageChannel();
|
|
714
|
+
const { iframe, promise } = await newIFrame(url);
|
|
715
|
+
Object.assign(iframe.style, {
|
|
716
|
+
// height: "100px"
|
|
717
|
+
position: "fixed",
|
|
718
|
+
width: "1px",
|
|
719
|
+
height: "1px",
|
|
720
|
+
top: "-1000",
|
|
721
|
+
left: "-1000",
|
|
722
|
+
display: "block",
|
|
723
|
+
opacity: "0",
|
|
724
|
+
border: "none",
|
|
725
|
+
outline: "none",
|
|
726
|
+
});
|
|
727
|
+
container.appendChild(iframe);
|
|
728
|
+
promise.then(() => {
|
|
729
|
+
iframe.contentWindow.postMessage(
|
|
730
|
+
{
|
|
731
|
+
type: "CONNECT",
|
|
732
|
+
},
|
|
733
|
+
"*",
|
|
734
|
+
[messageChannel.port1],
|
|
832
735
|
);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
break;
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
return !handler
|
|
846
|
-
? new Response(null, {
|
|
847
|
-
status: 404,
|
|
848
|
-
statusMessage: "Error 404: Not found",
|
|
849
|
-
})
|
|
850
|
-
: handler(request);
|
|
851
|
-
}
|
|
736
|
+
});
|
|
737
|
+
return {
|
|
738
|
+
port: messageChannel.port2,
|
|
739
|
+
close: () => {
|
|
740
|
+
container.parentElement && container.parentElement.removeChild(container);
|
|
741
|
+
messageChannel.port1.close();
|
|
742
|
+
messageChannel.port2.close();
|
|
743
|
+
},
|
|
744
|
+
};
|
|
852
745
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
746
|
+
async function newIFrame(url) {
|
|
747
|
+
const iframe = document.createElement("iframe");
|
|
748
|
+
iframe.src = url;
|
|
749
|
+
Object.assign(iframe.style, {
|
|
750
|
+
padding: 0,
|
|
751
|
+
margin: 0,
|
|
752
|
+
border: "none",
|
|
753
|
+
outline: "none",
|
|
754
|
+
width: "100%",
|
|
755
|
+
height: "100%",
|
|
756
|
+
});
|
|
864
757
|
return {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
758
|
+
iframe,
|
|
759
|
+
promise: new Promise((resolve, reject) => {
|
|
760
|
+
try {
|
|
761
|
+
iframe.onerror = reject;
|
|
762
|
+
iframe.onload = () => resolve(iframe);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
reject(error);
|
|
765
|
+
}
|
|
766
|
+
}),
|
|
870
767
|
};
|
|
871
768
|
}
|
|
872
769
|
}
|
|
770
|
+
// -------------------------------------------------------
|
|
873
771
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
const key = requestUrl
|
|
893
|
-
.substring(rootUrl.length)
|
|
894
|
-
.replace(/^\/?([^\/]+).*$/, "$1");
|
|
895
|
-
// console.log(`* rootUrl="${rootUrl}" requestUrl="${requestUrl}" key="${key}"`);
|
|
896
|
-
channelInfo = await this.loadChannelInfo(key);
|
|
897
|
-
}
|
|
898
|
-
if (channelInfo && channelInfo.port) {
|
|
899
|
-
return await sendHttpRequest(channelInfo.port, request);
|
|
900
|
-
} else {
|
|
901
|
-
const newRequest = new Request(requestUrl, {
|
|
902
|
-
method: request.method,
|
|
903
|
-
headers: request.headers,
|
|
904
|
-
body: request.body,
|
|
905
|
-
referrer: request.referrer,
|
|
906
|
-
referrerPolicy: request.referrerPolicy,
|
|
907
|
-
// mode: request.mode,
|
|
908
|
-
credentials: request.credentials,
|
|
909
|
-
cache: request.cache,
|
|
910
|
-
redirect: request.redirect,
|
|
911
|
-
integrity: request.integrity,
|
|
912
|
-
});
|
|
913
|
-
return await fetch(newRequest);
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
// const requestUrl = request.url;
|
|
917
|
-
// let url = requestUrl.replace(
|
|
918
|
-
// /^.*\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}(.*)$/,
|
|
919
|
-
// "$1",
|
|
920
|
-
// );
|
|
921
|
-
// if (url !== requestUrl) {
|
|
922
|
-
// url = new URL(
|
|
923
|
-
// "/packages/webrun-http-browser/src" + url,
|
|
924
|
-
// self.location.href,
|
|
925
|
-
// );
|
|
926
|
-
// }
|
|
927
|
-
} catch (error) {
|
|
928
|
-
console.error(error);
|
|
929
|
-
return new Response(null, {
|
|
930
|
-
status: 500,
|
|
931
|
-
statusText: "Error 500: Internal error",
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
|
-
})());
|
|
935
|
-
}
|
|
772
|
+
async function initializeConnection({
|
|
773
|
+
key,
|
|
774
|
+
communicationPort,
|
|
775
|
+
...options
|
|
776
|
+
}) {
|
|
777
|
+
const channel = new MessageChannel();
|
|
778
|
+
const accepted = await callChannel(
|
|
779
|
+
communicationPort,
|
|
780
|
+
"CONNECT",
|
|
781
|
+
{ key, ...options },
|
|
782
|
+
channel.port2,
|
|
783
|
+
);
|
|
784
|
+
if (!accepted) {
|
|
785
|
+
channel.port1.close();
|
|
786
|
+
channel.port2.close();
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
return channel.port1;
|
|
936
790
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
791
|
+
|
|
792
|
+
async function registerConnectionsHandler({
|
|
793
|
+
key,
|
|
794
|
+
handler,
|
|
795
|
+
communicationPort,
|
|
796
|
+
}) {
|
|
797
|
+
const [register, cleanup] = newRegistry();
|
|
798
|
+
await callChannel(communicationPort, "REGISTER", { key });
|
|
799
|
+
register(() => callChannel(communicationPort, "UNREGISTER", { key }));
|
|
800
|
+
register(
|
|
801
|
+
handleChannelCalls(
|
|
802
|
+
communicationPort,
|
|
803
|
+
"CONNECT",
|
|
804
|
+
handler,
|
|
805
|
+
),
|
|
806
|
+
);
|
|
807
|
+
return cleanup;
|
|
943
808
|
}
|
|
944
809
|
|
|
945
|
-
export {
|
|
810
|
+
export { callChannel, callHttpService, deserializeError, fromReadableStream, getRelayWindowMessageHandler, handleChannelCalls, handleHttpRequests, handleStreams, initHttpService, initServiceWorker, initServiceWorker1, initializeConnection, newHttpClientStub, newHttpServerStub, newInvokationChannel, newRegistry, newRemoteRelayChannel, newServiceWorkerPort, recieveData, registerConnectionsHandler, sendData, sendHttpRequest, sendStream, serializeError, splitServiceUrl, toReadableStream };
|