reflected 0.0.1 → 0.0.2

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 (51) hide show
  1. package/README.md +26 -9
  2. package/dist/async-DF1WaSCr.js +1 -0
  3. package/dist/async.js +1 -1
  4. package/dist/{broadcast-BPNfR9nK.js → broadcast-D0xibjmN.js} +1 -1
  5. package/dist/{broadcast-CwqVSk2p.js → broadcast-Dc7wAEE6.js} +1 -1
  6. package/dist/broadcast.js +1 -1
  7. package/dist/channel-CdS9bLt4.js +1 -0
  8. package/dist/index.js +1 -1
  9. package/dist/{message-CgNarJIa.js → message-D7s0I-EX.js} +1 -1
  10. package/dist/{message-YPvgpfHS.js → message-DLH7cJo6.js} +1 -1
  11. package/dist/message.js +1 -1
  12. package/dist/{sender-23_Enxlo.js → sender-BMLGKAss.js} +1 -1
  13. package/dist/shared-C_kd5Il-.js +1 -0
  14. package/dist/shared-MkVjuKUg.js +1 -0
  15. package/dist/sw.js +1 -1
  16. package/dist/{xhr-CYct95wr.js → xhr-D5y-AocB.js} +1 -1
  17. package/dist/xhr-DAG_4oRo.js +1 -0
  18. package/dist/xhr.js +1 -1
  19. package/package.json +7 -3
  20. package/rollup.js +2 -2
  21. package/src/channel.js +1 -1
  22. package/src/index.js +3 -0
  23. package/src/main/async.js +2 -2
  24. package/src/main/shared.js +3 -3
  25. package/src/main/xhr.js +4 -7
  26. package/src/service/listeners.js +2 -2
  27. package/src/worker/async.js +7 -7
  28. package/src/worker/shared.js +6 -6
  29. package/src/worker/xhr.js +3 -3
  30. package/test/README/index.html +11 -0
  31. package/test/{readme.html → README/index.js} +3 -15
  32. package/test/README/mini-coi.js +28 -0
  33. package/test/{readme.js → README/worker.js} +2 -2
  34. package/test/index.js +1 -1
  35. package/test/sw.js +1 -1
  36. package/test/worker.js +1 -1
  37. package/types/broadcast.d.ts +1 -1
  38. package/types/channel.d.ts +1 -1
  39. package/types/index.d.ts +4 -0
  40. package/types/main/shared.d.ts +2 -2
  41. package/types/message.d.ts +1 -1
  42. package/types/reflected/src/main/shared.d.ts +1 -1
  43. package/types/reflected/src/worker/shared.d.ts +1 -1
  44. package/types/worker/broadcast.d.ts +1 -1
  45. package/types/worker/message.d.ts +1 -1
  46. package/types/worker/shared.d.ts +4 -4
  47. package/dist/async-Cn7CWifh.js +0 -1
  48. package/dist/channel-BwDpH9fR.js +0 -1
  49. package/dist/shared-D9sRqO2H.js +0 -1
  50. package/dist/shared-DdAq4SGF.js +0 -1
  51. package/dist/xhr-C97Ssg1V.js +0 -1
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # reflected
2
2
 
3
- A primitive to allow workers to call synchronously any functionality exposed on the main thread.
3
+ A primitive to allow workers to call **synchronously** any functionality exposed on the main thread.
4
+
5
+ ## Strategies
4
6
 
5
7
  This module uses 3 synchronous strategies + 1 asynchronous fallback:
6
8
 
@@ -9,14 +11,23 @@ This module uses 3 synchronous strategies + 1 asynchronous fallback:
9
11
  * **xhr** based on synchronous *XMLHttpRequest* and a dedicated *ServiceWorker* able to intercept such *POST* requests, broadcast to all listening channels the request and resolve as response for the worker.
10
12
  * **async** which will always return a *Promise* and will not need special headers or *ServiceWorker*. This is also a fallback for the *xhr* case if the `serviceWorker` option field has not been provided.
11
13
 
12
- All strategies are automatically detected through the default/main `import` but all dedicated strategies can be retrieved directly, example:
14
+ All strategies are automatically detected through the default/main `import` but all dedicated strategies can be retrieved directly, for example:
13
15
 
14
16
  * `import reflect from 'reflected'` will decide automatically which strategy should be used.
15
17
  * `import reflect from 'reflected/message'` will return the right *message* based module on the main thread and the worker mode within the worker.
16
18
  * `import reflect from 'reflected/main/message'` will return the *message* strategy for the main thread only. This requires the least amount of bandwidth when you are sure that *message* strategy will work on main.
17
19
  * `import reflect from 'reflected/worker/message'` will return the *message* strategy for the worker thread only. This requires the least amount of bandwidth when you are sure that *message* strategy will work within the worker.
18
20
 
19
- Swap `message` with `broadcast`, `xhr` or `async`, and all exports will work equally well accordingly to the chosen "*channel strategy*".
21
+ Swap `message` with `broadcast`, `xhr` or `async`, and all exports will work equally well according to the chosen "*channel strategy*".
22
+
23
+ | Import | Use case |
24
+ |--------|----------|
25
+ | `reflected` | Auto-pick strategy (main + worker) |
26
+ | `reflected/message` \| `broadcast` \| `xhr` \| `async` | Specific strategy, context-aware |
27
+ | `reflected/main/<strategy>` | Main thread only (smaller bundle) |
28
+ | `reflected/worker/<strategy>` | Worker only (smaller bundle) |
29
+
30
+ **Requirements:** Synchronous strategies except for `xhr` need [Cross-Origin Isolation](https://developer.mozilla.org/en-US/docs/Web/API/Window/crossOriginIsolated) (e.g. `Cross-Origin-Opener-Policy: same-origin` and `Cross-Origin-Embedder-Policy: require-corp`). The `async` strategy works without those headers and always returns a Promise.
20
31
 
21
32
  ### Worker Thread API
22
33
 
@@ -30,7 +41,7 @@ const reflected = await reflect({
30
41
  // use this helper to transform such data into something
31
42
  // that the worker can use/understand after invoke
32
43
  // ⚠️ must be synchronous and it's invoked synchronously
33
- ondata(response:Int32Array) {
44
+ onsync(response:Int32Array) {
34
45
  return response.length ? response[0] : undefined;
35
46
  },
36
47
 
@@ -45,7 +56,7 @@ const reflected = await reflect({
45
56
  },
46
57
  });
47
58
 
48
- // retrive the result of `test_sum(1, 2, 3)`
59
+ // retrieve the result of `test_sum(1, 2, 3)`
49
60
  // directly from the main thread.
50
61
  // only the async channel variant would need to await
51
62
  const value = reflected({
@@ -74,16 +85,16 @@ const worker = await reflect(
74
85
  // Worker scriptURL
75
86
  './worker.js',
76
87
  // Worker options + required utilities / helpers
77
- // ℹ️ type is enforced to be 'module' due top-level await
88
+ // ℹ️ type is enforced to be 'module' due to top-level await
78
89
  {
79
90
  // invoked when the worker asks to synchronize a call
80
- // and it mmust return an Int32Array reference to populate
91
+ // and it must return an Int32Array reference to populate
81
92
  // the SharedArrayBuffer and notify/unlock the worker
82
93
  // ℹ️ works even if synchronous but it's resolved asynchronously
83
94
  // ⚠️ the worker is not responsive until this returns so
84
95
  // be sure you handle errors gracefully to still provide
85
96
  // a result the worker can consume out of the shared buffer!
86
- async ondata(payload:unknown) {
97
+ async onsync(payload:unknown) {
87
98
  const { invoke, args } = payload;
88
99
 
89
100
  if (invoke === 'test_sum') {
@@ -124,4 +135,10 @@ const worker = await reflect(
124
135
  const value = await worker.send({ any: 'payload' });
125
136
  ```
126
137
 
127
- Test [live](https://webreflection.github.io/reflected/test/readme.html) or read the [main thread](./test/readme.html) and [worker thread](./test/readme.js) code.
138
+ ### Extras
139
+
140
+ - **Named export `channel`:** After initialization, `import reflect, { channel } from 'reflected'` gives the active strategy name (`'message'`, `'broadcast'`, `'xhr'`, or `'async'`).
141
+ - **Errors:** From main-thread `onsync`, return `new Int32Array(0)` (or a convention of your choice) so the worker always gets a result; handle that in the worker’s `onsync` to avoid hanging.
142
+ - **Types:** you can import `MainOptions` and `WorkerOptions` from the root of the porject because *main* `reflect(string, MainOptions)` and *worker* `reflect(WorkerOptions)` are different in a subtle way you probably don't want to mess around with (in particular, the `onsync` which must be sync on the *worker* side of affairs or it cannnot work)
143
+
144
+ Test [live](https://webreflection.github.io/reflected/test/README/) or read the [main thread](./test/README/index.js) and [worker thread](./test/README/worker.js) code.
@@ -0,0 +1 @@
1
+ import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as s}from"./i32-C78nBJH2.js";import{s as t}from"./sender-BMLGKAss.js";import"./channel-CdS9bLt4.js";const{promise:r,resolve:a}=e();addEventListener("message",({data:[e,s,t]})=>a([e,s,t]),{once:!0});const n="async";var o=a=>r.then(([r,n,o])=>(postMessage(1),((t,r,a)=>{const n=new BroadcastChannel(t),o=s(),d=new Map;return n.addEventListener("message",({data:[e,s]})=>{r.set(s,0),d.get(e)(a.onsync(r.subarray(2,2+r[1]))),d.delete(e)}),(s,...t)=>{const{promise:r,resolve:a}=e(),i=o();return d.set(i,a),n.postMessage([i,s],...t),r}})(o,new Int32Array(r),t({...n,...a}))));export{n as channel,o as default};
package/dist/async.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s=e=>{const t=new Int32Array(1);return()=>t[0]++},n="eac8422c-ea74-4190-9b8c-7966827497f0";const{isArray:r}=Array,a=e=>e;class o extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=s(),this.#t=new Map,t.onsend||(t.onsend=a),super.addEventListener("message",async e=>{const{data:s}=e;if(r(s)&&s[0]===n){e.stopImmediatePropagation(),e.preventDefault();const[n,r]=s[1],a=this.#t.get(n);this.#t.delete(n),a(await t.onsend(r))}})}send(e,...s){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([n,[r,e]],...s),a}}let{SharedArrayBuffer:c}=globalThis;try{new c(4,{maxByteLength:8})}catch(e){c=class extends ArrayBuffer{get growable(){return super.resizable}grow(e){super.resize(e)}}}const i=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0};let u=!0;try{crypto.randomUUID()}catch(e){u=!1}const p=u?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),g="async";var y=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends o{constructor(e,t,s){const n=p(),r=new BroadcastChannel(n),a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new c(i+e,{maxByteLength:i+t}))(t),o=new Int32Array(a),u=((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.ondata(n),a=r.length,o=i+r.buffer.byteLength;e.byteLength<o&&e.grow(o),s.set(r,2),s[1]=a,s[0]=1}})(a,t);r.addEventListener("message",async({data:[e,t]})=>{await u({data:t}),r.postMessage([e,o.slice(0,2+o[1])])}),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,g,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t).concat(n))}get channel(){return g}});const{isArray:l}=Array;const{promise:h,resolve:m}=t();addEventListener("message",({data:[e,t,s]})=>m([e,t,s]),{once:!0});const w="async";var f="importScripts"in globalThis?e=>h.then(([r,a,o])=>(postMessage(1),((e,n,r)=>{const a=new BroadcastChannel(e),o=s(),c=new Map;return a.addEventListener("message",({data:[e,t]})=>{const[s,a]=c.get(e);n.set(t,0),s(r.ondata(n.subarray(2,2+n[1])))}),(e,...s)=>{const{promise:n,resolve:r}=t(),i=o();return c.set(i,[r,s]),a.postMessage([i,e],...s),n}})(o,new Int32Array(r),(e=>(addEventListener("message",async t=>{const{data:s}=t;if(l(s)&&s[0]===n){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=s[1];postMessage([n,[r,await e.onsend(a)]])}}),e))({...a,...e})))):y;export{w as channel,f as default};
1
+ const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s=e=>{const t=new Int32Array(1);return()=>t[0]++},n="fc260aad-4404-43b8-ae9d-2c06554bb294";const{isArray:r}=Array,a=e=>e;class o extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=s(),this.#t=new Map,t.onsend||(t.onsend=a),super.addEventListener("message",async e=>{const{data:s}=e;if(r(s)&&s[0]===n){e.stopImmediatePropagation(),e.preventDefault();const[n,r]=s[1],a=this.#t.get(n);this.#t.delete(n),a(await t.onsend(r))}})}send(e,...s){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([n,[r,e]],...s),a}}let{SharedArrayBuffer:c}=globalThis;try{new c(4,{maxByteLength:8})}catch(e){c=class extends ArrayBuffer{get growable(){return super.resizable}grow(e){super.resize(e)}}}const i=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0};let u=!0;try{crypto.randomUUID()}catch(e){u=!1}const p=u?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),y="async";var g=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends o{constructor(e,t,s){const n=p(),r=new BroadcastChannel(n),a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new c(i+e,{maxByteLength:i+t}))(t),o=new Int32Array(a),u=((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.onsync(n),a=r.length,o=i+r.buffer.byteLength;e.byteLength<o&&e.grow(o),s.set(r,2),s[1]=a,s[0]=1}})(a,t);r.addEventListener("message",async({data:[e,t]})=>{await u({data:t}),r.postMessage([e,o.slice(0,2+o[1])])}),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,y,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t).concat(n))}get channel(){return y}});const{isArray:l}=Array;const{promise:h,resolve:m}=t();addEventListener("message",({data:[e,t,s]})=>m([e,t,s]),{once:!0});const w="async";var f="importScripts"in globalThis?e=>h.then(([r,a,o])=>(postMessage(1),((e,n,r)=>{const a=new BroadcastChannel(e),o=s(),c=new Map;return a.addEventListener("message",({data:[e,t]})=>{n.set(t,0),c.get(e)(r.onsync(n.subarray(2,2+n[1]))),c.delete(e)}),(e,...s)=>{const{promise:n,resolve:r}=t(),i=o();return c.set(i,r),a.postMessage([i,e],...s),n}})(o,new Int32Array(r),(e=>(addEventListener("message",async t=>{const{data:s}=t;if(l(s)&&s[0]===n){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=s[1];postMessage([n,[r,await e.onsend(a)]])}}),e))({...a,...e})))):g;export{w as channel,f as default};
@@ -1 +1 @@
1
- import{b as s,S as e,a,h as r,u as t,p as n}from"./shared-D9sRqO2H.js";import{r as o}from"./shared-RFmxa5x4.js";import"./with-resolvers-CHEvl4oe.js";import"./i32-C78nBJH2.js";import"./channel-BwDpH9fR.js";const c="broadcast";var d=s(class extends e{constructor(s,e,d){const p=o(),i=new BroadcastChannel(p),m=a(e);i.addEventListener("message",r(m,e,!0)),super(...t(s,c,e)),super.addEventListener("message",()=>d(this),{once:!0}),super.postMessage(n(m,e).concat(p))}get channel(){return c}});export{d as default};
1
+ import{b as s,S as e,a,h as r,u as t,p as n}from"./shared-MkVjuKUg.js";import{r as o}from"./shared-RFmxa5x4.js";import"./with-resolvers-CHEvl4oe.js";import"./i32-C78nBJH2.js";import"./channel-CdS9bLt4.js";const c="broadcast";var d=s(class extends e{constructor(s,e,d){const p=o(),i=new BroadcastChannel(p),m=a(e);i.addEventListener("message",r(m,e,!0)),super(...t(s,c,e)),super.addEventListener("message",()=>d(this),{once:!0}),super.postMessage(n(m,e).concat(p))}get channel(){return c}});export{d as default};
@@ -1 +1 @@
1
- import{w as r}from"./with-resolvers-CHEvl4oe.js";import{h as s}from"./shared-DdAq4SGF.js";import"./sender-23_Enxlo.js";import"./channel-BwDpH9fR.js";const{promise:a,resolve:e}=r(),o="broadcast";var t=s(a,({data:[r,s,a]})=>e([r,s,new BroadcastChannel(a)]));export{o as channel,t as default};
1
+ import{w as r}from"./with-resolvers-CHEvl4oe.js";import{h as s}from"./shared-C_kd5Il-.js";import"./sender-BMLGKAss.js";import"./channel-CdS9bLt4.js";const{promise:a,resolve:e}=r(),o="broadcast";var t=s(a,({data:[r,s,a]})=>e([r,s,new BroadcastChannel(a)]));export{o as channel,t as default};
package/dist/broadcast.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s="eac8422c-ea74-4190-9b8c-7966827497f0";const{isArray:n}=Array,r=e=>e;class a extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=(()=>{const e=new Int32Array(1);return()=>e[0]++})(),this.#t=new Map,t.onsend||(t.onsend=r),super.addEventListener("message",async e=>{const{data:r}=e;if(n(r)&&r[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,n]=r[1],a=this.#t.get(s);this.#t.delete(s),a(await t.onsend(n))}})}send(e,...n){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([s,[r,e]],...n),a}}const{notify:o,store:c}=Atomics,i=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0};let u=!0;try{crypto.randomUUID()}catch(e){u=!1}const p=u?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),h="broadcast";var m=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends a{constructor(e,t,s){const n=p(),r=new BroadcastChannel(n),a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(i+e,{maxByteLength:i+t}))(t);r.addEventListener("message",((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.ondata(n),a=r.length,d=i+r.buffer.byteLength;e.byteLength<d&&e.grow(d),s.set(r,2),c(s,1,a),c(s,0,1),o(s,0)}})(a,t)),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,h,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t).concat(n))}get channel(){return h}});const{isArray:y}=Array;const{load:g,store:l,wait:w}=Atomics,{promise:f,resolve:v}=t(),L="broadcast";var A=((e,t)=>(addEventListener("message",t,{once:!0}),t=>e.then(([e,n,r])=>(postMessage(1),((e,t,s)=>(n,...r)=>(e.postMessage(n,...r),w(t,0,0),l(t,0,0),s.ondata(t.subarray(2,2+g(t,1)))))(r,new Int32Array(e),(e=>(addEventListener("message",async t=>{const{data:n}=t;if(y(n)&&n[0]===s){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=n[1];postMessage([s,[r,await e.onsend(a)]])}}),e))({...n,...t}))))))(f,({data:[e,t,s]})=>v([e,t,new BroadcastChannel(s)])),b="importScripts"in globalThis?A:m;export{L as channel,b as default};
1
+ const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s="fc260aad-4404-43b8-ae9d-2c06554bb294";const{isArray:n}=Array,r=e=>e;class a extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=(()=>{const e=new Int32Array(1);return()=>e[0]++})(),this.#t=new Map,t.onsend||(t.onsend=r),super.addEventListener("message",async e=>{const{data:r}=e;if(n(r)&&r[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,n]=r[1],a=this.#t.get(s);this.#t.delete(s),a(await t.onsend(n))}})}send(e,...n){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([s,[r,e]],...n),a}}const{notify:o,store:c}=Atomics,i=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0};let u=!0;try{crypto.randomUUID()}catch(e){u=!1}const p=u?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),y="broadcast";var h=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends a{constructor(e,t,s){const n=p(),r=new BroadcastChannel(n),a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(i+e,{maxByteLength:i+t}))(t);r.addEventListener("message",((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.onsync(n),a=r.length,d=i+r.buffer.byteLength;e.byteLength<d&&e.grow(d),s.set(r,2),c(s,1,a),c(s,0,1),o(s,0)}})(a,t)),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,y,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t).concat(n))}get channel(){return y}});const{isArray:m}=Array;const{load:g,store:l,wait:w}=Atomics,{promise:f,resolve:v}=t(),b="broadcast";var L=((e,t)=>(addEventListener("message",t,{once:!0}),t=>e.then(([e,n,r])=>(postMessage(1),((e,t,s)=>(n,...r)=>(e.postMessage(n,...r),w(t,0,0),l(t,0,0),s.onsync(t.subarray(2,2+g(t,1)))))(r,new Int32Array(e),(e=>(addEventListener("message",async t=>{const{data:n}=t;if(m(n)&&n[0]===s){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=n[1];postMessage([s,[r,await e.onsend(a)]])}}),e))({...n,...t}))))))(f,({data:[e,t,s]})=>v([e,t,new BroadcastChannel(s)])),A="importScripts"in globalThis?L:h;export{b as channel,A as default};
@@ -0,0 +1 @@
1
+ var a="fc260aad-4404-43b8-ae9d-2c06554bb294";export{a as S};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{w as a}from"./with-resolvers-CHEvl4oe.js";import{n as s}from"./shared-array-buffer-cwdMr2mc.js";let e,t;if("importScripts"in globalThis){let s;const{promise:r,resolve:o}=a(),i=new URL(location).searchParams.get("reflected");e=i,s="message"===i?import("./message-CgNarJIa.js"):"broadcast"===i?import("./broadcast-CwqVSk2p.js"):"xhr"===i?import("./xhr-CYct95wr.js"):import("./async-Cn7CWifh.js"),t=async a=>{const{data:e,ports:t}=await r,{default:o}=await s,i=new Event("message");return i.data=e,i.ports=t,dispatchEvent(i),o(a)},addEventListener("message",o,{once:!0})}else s?"InstallTrigger"in globalThis?(e="broadcast",t=(await import("./broadcast-BPNfR9nK.js")).default):(e="message",t=(await import("./message-YPvgpfHS.js")).default):navigator.serviceWorker?(e="xhr",t=(await import("./xhr-C97Ssg1V.js")).default):(e="fallback",t=()=>{});var r=t;export{e as channel,r as default};
1
+ import{w as a}from"./with-resolvers-CHEvl4oe.js";import{n as s}from"./shared-array-buffer-cwdMr2mc.js";let e,t;if("importScripts"in globalThis){let s;const{promise:r,resolve:o}=a(),i=new URL(location).searchParams.get("reflected");e=i,s="message"===i?import("./message-D7s0I-EX.js"):"broadcast"===i?import("./broadcast-Dc7wAEE6.js"):"xhr"===i?import("./xhr-D5y-AocB.js"):import("./async-DF1WaSCr.js"),t=async a=>{const{data:e,ports:t}=await r,{default:o}=await s,i=new Event("message");return i.data=e,i.ports=t,dispatchEvent(i),o(a)},addEventListener("message",o,{once:!0})}else s?"InstallTrigger"in globalThis?(e="broadcast",t=(await import("./broadcast-D0xibjmN.js")).default):(e="message",t=(await import("./message-DLH7cJo6.js")).default):navigator.serviceWorker?(e="xhr",t=(await import("./xhr-DAG_4oRo.js")).default):(e="fallback",t=()=>{});var r=t;export{e as channel,r as default};
@@ -1 +1 @@
1
- import{w as s}from"./with-resolvers-CHEvl4oe.js";import{h as r}from"./shared-DdAq4SGF.js";import"./sender-23_Enxlo.js";import"./channel-BwDpH9fR.js";const{promise:e,resolve:o}=s(),a="message";var t=r(e,({data:[s,r],ports:[e]})=>o([s,r,e]));export{a as channel,t as default};
1
+ import{w as s}from"./with-resolvers-CHEvl4oe.js";import{h as r}from"./shared-C_kd5Il-.js";import"./sender-BMLGKAss.js";import"./channel-CdS9bLt4.js";const{promise:e,resolve:o}=s(),a="message";var t=r(e,({data:[s,r],ports:[e]})=>o([s,r,e]));export{a as channel,t as default};
@@ -1 +1 @@
1
- import{b as s,S as e,a as t,h as r,u as a,p as n}from"./shared-D9sRqO2H.js";import"./with-resolvers-CHEvl4oe.js";import"./i32-C78nBJH2.js";import"./channel-BwDpH9fR.js";const o="message";var p=s(class extends e{constructor(s,e,p){const{port1:c,port2:i}=new MessageChannel,d=t(e);c.addEventListener(o,r(d,e,!0)),c.start(),super(...a(s,o,e)),super.addEventListener(o,()=>p(this),{once:!0}),super.postMessage(n(d,e),[i])}get channel(){return o}});export{p as default};
1
+ import{b as s,S as e,a as t,h as r,u as a,p as n}from"./shared-MkVjuKUg.js";import"./with-resolvers-CHEvl4oe.js";import"./i32-C78nBJH2.js";import"./channel-CdS9bLt4.js";const o="message";var p=s(class extends e{constructor(s,e,p){const{port1:c,port2:i}=new MessageChannel,d=t(e);c.addEventListener(o,r(d,e,!0)),c.start(),super(...a(s,o,e)),super.addEventListener(o,()=>p(this),{once:!0}),super.postMessage(n(d,e),[i])}get channel(){return o}});export{p as default};
package/dist/message.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s="eac8422c-ea74-4190-9b8c-7966827497f0";const{isArray:n}=Array,r=e=>e;class a extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=(()=>{const e=new Int32Array(1);return()=>e[0]++})(),this.#t=new Map,t.onsend||(t.onsend=r),super.addEventListener("message",async e=>{const{data:r}=e;if(n(r)&&r[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,n]=r[1],a=this.#t.get(s);this.#t.delete(s),a(await t.onsend(n))}})}send(e,...n){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([s,[r,e]],...n),a}}const{notify:o,store:i}=Atomics,c=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},u="message";var p=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends a{constructor(e,t,s){const{port1:n,port2:r}=new MessageChannel,a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(c+e,{maxByteLength:c+t}))(t);n.addEventListener(u,((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.ondata(n),a=r.length,d=c+r.buffer.byteLength;e.byteLength<d&&e.grow(d),s.set(r,2),i(s,1,a),i(s,0,1),o(s,0)}})(a,t)),n.start(),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,u,t)),super.addEventListener(u,()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t),[r])}get channel(){return u}});const{isArray:g}=Array;const{load:h,store:m,wait:y}=Atomics,{promise:l,resolve:f}=t(),v="message";var w=((e,t)=>(addEventListener("message",t,{once:!0}),t=>e.then(([e,n,r])=>(postMessage(1),((e,t,s)=>(n,...r)=>(e.postMessage(n,...r),y(t,0,0),m(t,0,0),s.ondata(t.subarray(2,2+h(t,1)))))(r,new Int32Array(e),(e=>(addEventListener("message",async t=>{const{data:n}=t;if(g(n)&&n[0]===s){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=n[1];postMessage([s,[r,await e.onsend(a)]])}}),e))({...n,...t}))))))(l,({data:[e,t],ports:[s]})=>f([e,t,s])),L="importScripts"in globalThis?w:p;export{v as channel,L as default};
1
+ const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s="fc260aad-4404-43b8-ae9d-2c06554bb294";const{isArray:n}=Array,r=e=>e;class a extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=(()=>{const e=new Int32Array(1);return()=>e[0]++})(),this.#t=new Map,t.onsend||(t.onsend=r),super.addEventListener("message",async e=>{const{data:r}=e;if(n(r)&&r[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,n]=r[1],a=this.#t.get(s);this.#t.delete(s),a(await t.onsend(n))}})}send(e,...n){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([s,[r,e]],...n),a}}const{notify:o,store:c}=Atomics,i=2*Int32Array.BYTES_PER_ELEMENT,d=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},u="message";var p=(e=>(s,n)=>{const{promise:r,resolve:a}=t();return new e(s,n,a),r})(class extends a{constructor(e,t,s){const{port1:n,port2:r}=new MessageChannel,a=(({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(i+e,{maxByteLength:i+t}))(t);n.addEventListener(u,((e,t)=>{const s=new Int32Array(e);return async({data:n})=>{const r=await t.onsync(n),a=r.length,d=i+r.buffer.byteLength;e.byteLength<d&&e.grow(d),s.set(r,2),c(s,1,a),c(s,0,1),o(s,0)}})(a,t)),n.start(),super(...((e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]})(e,u,t)),super.addEventListener(u,()=>s(this),{once:!0}),super.postMessage(((e,t)=>{const s={};for(const e in t){const n=t[e];d(e)&&d(n)&&(s[e]=n)}return[e,s]})(a,t),[r])}get channel(){return u}});const{isArray:y}=Array;const{load:g,store:h,wait:m}=Atomics,{promise:l,resolve:f}=t(),v="message";var w=((e,t)=>(addEventListener("message",t,{once:!0}),t=>e.then(([e,n,r])=>(postMessage(1),((e,t,s)=>(n,...r)=>(e.postMessage(n,...r),m(t,0,0),h(t,0,0),s.onsync(t.subarray(2,2+g(t,1)))))(r,new Int32Array(e),(e=>(addEventListener("message",async t=>{const{data:n}=t;if(y(n)&&n[0]===s){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=n[1];postMessage([s,[r,await e.onsend(a)]])}}),e))({...n,...t}))))))(l,({data:[e,t],ports:[s]})=>f([e,t,s])),L="importScripts"in globalThis?w:p;export{v as channel,L as default};
@@ -1 +1 @@
1
- import{S as a}from"./channel-BwDpH9fR.js";const{isArray:s}=Array;var e=e=>(addEventListener("message",async t=>{const{data:n}=t;if(s(n)&&n[0]===a){t.stopImmediatePropagation(),t.preventDefault();const[s,o]=n[1];postMessage([a,[s,await e.onsend(o)]])}}),e);export{e as s};
1
+ import{S as a}from"./channel-CdS9bLt4.js";const{isArray:s}=Array;var e=e=>(addEventListener("message",async t=>{const{data:n}=t;if(s(n)&&n[0]===a){t.stopImmediatePropagation(),t.preventDefault();const[s,o]=n[1];postMessage([a,[s,await e.onsend(o)]])}}),e);export{e as s};
@@ -0,0 +1 @@
1
+ import{s}from"./sender-BMLGKAss.js";const{load:e,store:t,wait:a}=Atomics,o=(o,n)=>(addEventListener("message",n,{once:!0}),n=>o.then(([o,r,c])=>(postMessage(1),((s,o,n)=>(r,...c)=>(s.postMessage(r,...c),a(o,0,0),t(o,0,0),n.onsync(o.subarray(2,2+e(o,1)))))(c,new Int32Array(o),s({...r,...n})))));export{o as h};
@@ -0,0 +1 @@
1
+ import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as t}from"./i32-C78nBJH2.js";import{S as s}from"./channel-CdS9bLt4.js";const{isArray:r}=Array,n=e=>e;class o extends Worker{#e;#t;constructor(e,o){super(e,o),this.#e=t(),this.#t=new Map,o.onsend||(o.onsend=n),super.addEventListener("message",async e=>{const{data:t}=e;if(r(t)&&t[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,r]=t[1],n=this.#t.get(s);this.#t.delete(s),n(await o.onsend(r))}})}send(t,...r){const n=this.#e(),{promise:o,resolve:a}=e();return this.#t.set(n,a),super.postMessage([s,[n,t]],...r),o}}const{notify:a,store:i}=Atomics,c=2*Int32Array.BYTES_PER_ELEMENT,u=({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(c+e,{maxByteLength:c+t}),h=t=>(s,r)=>{const{promise:n,resolve:o}=e();return new t(s,r,o),n},m=(e,t,s)=>{const r=new Int32Array(e);return async({data:n})=>{const o=await t.onsync(n),u=o.length,h=c+o.buffer.byteLength;e.byteLength<h&&e.grow(h),r.set(o,2),s?(i(r,1,u),i(r,0,1),a(r,0)):(r[1]=u,r[0]=1)}},p=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},y=(e,t)=>{const s={};for(const e in t){const r=t[e];p(e)&&p(r)&&(s[e]=r)}return[e,s]},d=(e,t,s)=>{const r=new URL(e,location.href);return r.searchParams.set("reflected",t),[r,{...s,type:"module"}]};export{o as S,u as a,h as b,m as h,c as m,y as p,d as u};
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,n=new this((n,s)=>{e=n,t=s});return{resolve:e,reject:t,promise:n}};var t=e.bind(Promise);const[n,s]=((e=e=>e)=>{const n=new Map,s=(()=>{const e=new Int32Array(1);return()=>e[0]++})();return[()=>{let r;do{r=e(s())}while(n.has(r));const a=t();return n.set(r,a),[r,a.promise]},(e,t,s)=>{const r=n.get(e);n.delete(e),s?r?.reject(s):r?.resolve(t)}]})(),{protocol:r,host:a,pathname:o}=location,i=`${r}//${a}${o}`,c=new BroadcastChannel("eac8422c-ea74-4190-9b8c-7966827497f0");c.addEventListener("message",({data:[e,t]})=>{if("response"===e){const[e,n]=t;s(e,`[${n.join(",")}]`)}});const d=async e=>{const[t,s]=n();return c.postMessage(["request",[t,e]]),new Response(await s)};addEventListener("activate",e=>e.waitUntil(clients.claim())),addEventListener("fetch",async e=>{const{request:t}=e;"POST"===t.method&&t.url.startsWith(i)&&(e.stopImmediatePropagation(),e.respondWith(t.json().then(d)),e.preventDefault())}),addEventListener("install",()=>skipWaiting());
1
+ const e=Promise.withResolvers||function(){var e,t,n=new this((n,s)=>{e=n,t=s});return{resolve:e,reject:t,promise:n}};var t=e.bind(Promise);const[n,s]=((e=e=>e)=>{const n=new Map,s=(()=>{const e=new Int32Array(1);return()=>e[0]++})();return[()=>{let a;do{a=e(s())}while(n.has(a));const r=t();return n.set(a,r),[a,r.promise]},(e,t,s)=>{const a=n.get(e);n.delete(e),s?a?.reject(s):a?.resolve(t)}]})(),{protocol:a,host:r,pathname:o}=location,i=`${a}//${r}${o}`,c=new BroadcastChannel("fc260aad-4404-43b8-ae9d-2c06554bb294");c.addEventListener("message",({data:[e,t]})=>{if("response"===e){const[e,n]=t;s(e,`[${n.join(",")}]`)}});const d=async e=>{const[t,s]=n();return c.postMessage(["request",[t,e]]),new Response(await s)};addEventListener("activate",e=>e.waitUntil(clients.claim())),addEventListener("fetch",async e=>{const{request:t}=e;"POST"===t.method&&t.url.startsWith(i)&&(e.stopImmediatePropagation(),e.respondWith(t.json().then(d)),e.preventDefault())}),addEventListener("install",()=>skipWaiting());
@@ -1 +1 @@
1
- import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as s}from"./i32-C78nBJH2.js";import{s as t}from"./sender-23_Enxlo.js";import"./channel-BwDpH9fR.js";const{parse:r,stringify:n}=JSON,{promise:o,resolve:a}=e();addEventListener("message",({data:[e,s,t]})=>a([e,s,t]),{once:!0});const p="xhr";var i=e=>o.then(([o,a,p])=>(postMessage(1),((e,t,o)=>{const a=new BroadcastChannel(e),p=s(),{serviceWorker:i}=o;return(s,...c)=>{const d=p();a.postMessage([d,s],...c);const m=new XMLHttpRequest;return m.open("POST",i,!1),m.setRequestHeader("Content-Type","application/json"),m.send(n([d,e])),t.set(r(m.responseText),0),o.ondata(t.subarray(2,2+t[1]))}})(p,new Int32Array(o),t({...a,...e}))));export{p as channel,i as default};
1
+ import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as s}from"./i32-C78nBJH2.js";import{s as t}from"./sender-BMLGKAss.js";import"./channel-CdS9bLt4.js";const{parse:r,stringify:n}=JSON,{promise:o,resolve:a}=e();addEventListener("message",({data:[e,s,t]})=>a([e,s,t]),{once:!0});const p="xhr";var i=e=>o.then(([o,a,p])=>(postMessage(1),((e,t,o)=>{const a=new BroadcastChannel(e),p=s(),{serviceWorker:i}=o;return(s,...c)=>{const d=p();a.postMessage([d,s],...c);const m=new XMLHttpRequest;return m.open("POST",i,!1),m.setRequestHeader("Content-Type","application/json"),m.send(n([d,e])),t.set(r(m.responseText),0),o.onsync(t.subarray(2,2+t[1]))}})(p,new Int32Array(o),t({...a,...e}))));export{p as channel,i as default};
@@ -0,0 +1 @@
1
+ import{w as e}from"./with-resolvers-CHEvl4oe.js";import{m as t,S as s,u as n,p as a,h as r}from"./shared-MkVjuKUg.js";import{S as o}from"./shared-array-buffer-cwdMr2mc.js";import{r as i}from"./shared-RFmxa5x4.js";import{S as c}from"./channel-CdS9bLt4.js";import"./i32-C78nBJH2.js";var l=({initByteLength:e=1024,maxByteLength:s=8192})=>new o(t+e,{maxByteLength:t+s});const d="async";let h=class extends s{constructor(e,t,s){const o=i(),c=new BroadcastChannel(o),h=l(t),p=new Int32Array(h),g=r(h,t,!1);c.addEventListener("message",async({data:[e,t]})=>{await g({data:t}),c.postMessage([e,p.slice(0,2+p[1])])}),super(...n(e,d,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(a(h,t).concat(o))}get channel(){return d}};const p=new Map,g=new BroadcastChannel(c);g.addEventListener("message",async({data:[e,t]})=>{if("request"===e){const[e,[s,n]]=t,a=p.get(n);a&&(g.postMessage(["response",[e,await a.get(s)]]),a.delete(s))}});const{promise:u,resolve:m}=e();let f=!0;const v=(e,t)=>{let s,n=!0,{url:a}=t;e.getRegistration(a).then(s=>s??e.register(a,t)).then(function r(o){const{controller:i}=e;if(n=n&&!!i,s=o.installing||o.waiting||o.active,!s)return v(e,t);if("activated"===s.state){if(n){if(i.scriptURL===a)return m();o.unregister()}location.reload()}else s.addEventListener("statechange",()=>r(o),{once:!0})})};class w extends s{#e;constructor(t,s,o){if(f){f=!1;let{serviceWorker:e}=s;if(!e)return new h(t,s,o);"string"==typeof e&&(e={url:e}),e.url=new URL(e.url,location.href).href,v(navigator.serviceWorker,e)}const c=i(),d=new BroadcastChannel(c),g=l(s),u=new Map,m=new Int32Array(g),w=r(g,s,!1);p.set(c,u),d.addEventListener("message",async({data:[t,s]})=>{const{promise:n,resolve:a}=e();u.set(t,n),await w({data:s}),a(m.slice(0,2+m[1]))}),super(...n(t,"xhr",s)),super.addEventListener("message",()=>o(this),{once:!0}),super.postMessage(a(g,s).concat(c)),this.#e=c}terminate(){p.delete(this.#e),super.terminate()}get channel(){return"xhr"}}var y=(t,s)=>{const{promise:n,resolve:a}=e();return new w(t,s,a)instanceof h?n:u.then(()=>n)};export{y as default};
package/dist/xhr.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s=e=>{const t=new Int32Array(1);return()=>t[0]++},n="eac8422c-ea74-4190-9b8c-7966827497f0";const{isArray:r}=Array,a=e=>e;class o extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=s(),this.#t=new Map,t.onsend||(t.onsend=a),super.addEventListener("message",async e=>{const{data:s}=e;if(r(s)&&s[0]===n){e.stopImmediatePropagation(),e.preventDefault();const[n,r]=s[1],a=this.#t.get(n);this.#t.delete(n),a(await t.onsend(r))}})}send(e,...s){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([n,[r,e]],...s),a}}let{SharedArrayBuffer:c}=globalThis;try{new c(4,{maxByteLength:8})}catch(e){c=class extends ArrayBuffer{get growable(){return super.resizable}grow(e){super.resize(e)}}}const i=2*Int32Array.BYTES_PER_ELEMENT,d=(e,t,s)=>{const n=new Int32Array(e);return async({data:s})=>{const r=await t.ondata(s),a=r.length,o=i+r.buffer.byteLength;e.byteLength<o&&e.grow(o),n.set(r,2),n[1]=a,n[0]=1}},l=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},u=(e,t)=>{const s={};for(const e in t){const n=t[e];l(e)&&l(n)&&(s[e]=n)}return[e,s]},p=(e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]};var g=({initByteLength:e=1024,maxByteLength:t=8192})=>new c(i+e,{maxByteLength:i+t});let h=!0;try{crypto.randomUUID()}catch(e){h=!1}const y=h?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),w="async";let f=class extends o{constructor(e,t,s){const n=y(),r=new BroadcastChannel(n),a=g(t),o=new Int32Array(a),c=d(a,t);r.addEventListener("message",async({data:[e,t]})=>{await c({data:t}),r.postMessage([e,o.slice(0,2+o[1])])}),super(...p(e,w,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(u(a,t).concat(n))}get channel(){return w}};const m=new Map,v=new BroadcastChannel(n);v.addEventListener("message",async({data:[e,t]})=>{if("request"===e){const[e,[s,n]]=t,r=m.get(n);if(r){const t=r.get(s);t&&(r.delete(s),v.postMessage(["response",[e,await t]]))}}});const{promise:L,resolve:x}=t();let E=!0;const M=(e,t)=>{let s,n=!0,{url:r}=t;e.getRegistration(r).then(s=>s??e.register(r,t)).then(function a(o){const{controller:c}=e;if(n=n&&!!c,s=o.installing||o.waiting||o.active,!s)return M(e,t);if("activated"===s.state){if(n){if(c.scriptURL===r)return x();o.unregister()}location.reload()}else s.addEventListener("statechange",()=>a(o),{once:!0})})};let A=class extends o{#s;constructor(e,s,n){if(E){E=!1;let{serviceWorker:t}=s;if(!t)return new f(e,s,n);"string"==typeof t&&(t={url:t}),t.url=new URL(t.url,location.href).href,M(navigator.serviceWorker,t)}const r=y(),a=new BroadcastChannel(r),o=g(s),c=new Map,i=new Int32Array(o),l=d(o,s);m.set(r,c),a.addEventListener("message",async({data:[e,s]})=>{const{promise:n,resolve:r}=t();c.set(e,n),await l({data:s}),r(i.slice(0,2+i[1]))}),super(...p(e,"xhr",s)),super.addEventListener("message",()=>n(this),{once:!0}),super.postMessage(u(o,s).concat(r)),this.#s=r}terminate(){m.delete(this.#s),super.terminate()}get channel(){return"xhr"}};const{isArray:b}=Array;const{parse:B,stringify:I}=JSON,{promise:q,resolve:R}=t();addEventListener("message",({data:[e,t,s]})=>R([e,t,s]),{once:!0});const P="xhr";var T="importScripts"in globalThis?e=>q.then(([t,r,a])=>(postMessage(1),((e,t,n)=>{const r=new BroadcastChannel(e),a=s(),{serviceWorker:o}=n;return(s,...c)=>{const i=a();r.postMessage([i,s],...c);const d=new XMLHttpRequest;return d.open("POST",o,!1),d.setRequestHeader("Content-Type","application/json"),d.send(I([i,e])),t.set(B(d.responseText),0),n.ondata(t.subarray(2,2+t[1]))}})(a,new Int32Array(t),(e=>(addEventListener("message",async t=>{const{data:s}=t;if(b(s)&&s[0]===n){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=s[1];postMessage([n,[r,await e.onsend(a)]])}}),e))({...r,...e})))):(e,s)=>{const{promise:n,resolve:r}=t();return new A(e,s,r)instanceof f?n:L.then(()=>n)};export{P as channel,T as default};
1
+ const e=Promise.withResolvers||function(){var e,t,s=new this((s,n)=>{e=s,t=n});return{resolve:e,reject:t,promise:s}};var t=e.bind(Promise),s=e=>{const t=new Int32Array(1);return()=>t[0]++},n="fc260aad-4404-43b8-ae9d-2c06554bb294";const{isArray:r}=Array,a=e=>e;class o extends Worker{#e;#t;constructor(e,t){super(e,t),this.#e=s(),this.#t=new Map,t.onsend||(t.onsend=a),super.addEventListener("message",async e=>{const{data:s}=e;if(r(s)&&s[0]===n){e.stopImmediatePropagation(),e.preventDefault();const[n,r]=s[1],a=this.#t.get(n);this.#t.delete(n),a(await t.onsend(r))}})}send(e,...s){const r=this.#e(),{promise:a,resolve:o}=t();return this.#t.set(r,o),super.postMessage([n,[r,e]],...s),a}}let{SharedArrayBuffer:c}=globalThis;try{new c(4,{maxByteLength:8})}catch(e){c=class extends ArrayBuffer{get growable(){return super.resizable}grow(e){super.resize(e)}}}const i=2*Int32Array.BYTES_PER_ELEMENT,d=(e,t,s)=>{const n=new Int32Array(e);return async({data:s})=>{const r=await t.onsync(s),a=r.length,o=i+r.buffer.byteLength;e.byteLength<o&&e.grow(o),n.set(r,2),n[1]=a,n[0]=1}},l=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},u=(e,t)=>{const s={};for(const e in t){const n=t[e];l(e)&&l(n)&&(s[e]=n)}return[e,s]},p=(e,t,s)=>{const n=new URL(e,location.href);return n.searchParams.set("reflected",t),[n,{...s,type:"module"}]};var g=({initByteLength:e=1024,maxByteLength:t=8192})=>new c(i+e,{maxByteLength:i+t});let h=!0;try{crypto.randomUUID()}catch(e){h=!1}const y=h?()=>crypto.randomUUID():()=>(Date.now()+Math.random()).toString(36),w="async";let m=class extends o{constructor(e,t,s){const n=y(),r=new BroadcastChannel(n),a=g(t),o=new Int32Array(a),c=d(a,t);r.addEventListener("message",async({data:[e,t]})=>{await c({data:t}),r.postMessage([e,o.slice(0,2+o[1])])}),super(...p(e,w,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(u(a,t).concat(n))}get channel(){return w}};const f=new Map,v=new BroadcastChannel(n);v.addEventListener("message",async({data:[e,t]})=>{if("request"===e){const[e,[s,n]]=t,r=f.get(n);r&&(v.postMessage(["response",[e,await r.get(s)]]),r.delete(s))}});const{promise:L,resolve:x}=t();let E=!0;const M=(e,t)=>{let s,n=!0,{url:r}=t;e.getRegistration(r).then(s=>s??e.register(r,t)).then(function a(o){const{controller:c}=e;if(n=n&&!!c,s=o.installing||o.waiting||o.active,!s)return M(e,t);if("activated"===s.state){if(n){if(c.scriptURL===r)return x();o.unregister()}location.reload()}else s.addEventListener("statechange",()=>a(o),{once:!0})})};let b=class extends o{#s;constructor(e,s,n){if(E){E=!1;let{serviceWorker:t}=s;if(!t)return new m(e,s,n);"string"==typeof t&&(t={url:t}),t.url=new URL(t.url,location.href).href,M(navigator.serviceWorker,t)}const r=y(),a=new BroadcastChannel(r),o=g(s),c=new Map,i=new Int32Array(o),l=d(o,s);f.set(r,c),a.addEventListener("message",async({data:[e,s]})=>{const{promise:n,resolve:r}=t();c.set(e,n),await l({data:s}),r(i.slice(0,2+i[1]))}),super(...p(e,"xhr",s)),super.addEventListener("message",()=>n(this),{once:!0}),super.postMessage(u(o,s).concat(r)),this.#s=r}terminate(){f.delete(this.#s),super.terminate()}get channel(){return"xhr"}};const{isArray:A}=Array;const{parse:B,stringify:I}=JSON,{promise:q,resolve:R}=t();addEventListener("message",({data:[e,t,s]})=>R([e,t,s]),{once:!0});const P="xhr";var T="importScripts"in globalThis?e=>q.then(([t,r,a])=>(postMessage(1),((e,t,n)=>{const r=new BroadcastChannel(e),a=s(),{serviceWorker:o}=n;return(s,...c)=>{const i=a();r.postMessage([i,s],...c);const d=new XMLHttpRequest;return d.open("POST",o,!1),d.setRequestHeader("Content-Type","application/json"),d.send(I([i,e])),t.set(B(d.responseText),0),n.onsync(t.subarray(2,2+t[1]))}})(a,new Int32Array(t),(e=>(addEventListener("message",async t=>{const{data:s}=t;if(A(s)&&s[0]===n){t.stopImmediatePropagation(),t.preventDefault();const[r,a]=s[1];postMessage([n,[r,await e.onsend(a)]])}}),e))({...r,...e})))):(e,s)=>{const{promise:n,resolve:r}=t();return new b(e,s,r)instanceof m?n:L.then(()=>n)};export{P as channel,T as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reflected",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "A primitive to allow workers to call synchronously any functionality exposed on the main thread.",
5
5
  "exports": {
6
6
  ".": {
@@ -61,8 +61,12 @@
61
61
  "build": "rm -rf dist && rollup -c rollup.js && cp dist/sw.js test/sw.js && npm run types",
62
62
  "types": "tsc --allowJs --checkJs --lib dom,esnext --module nodeNext --target esnext -d --emitDeclarationOnly --outDir ./types ./src/*.js ./src/*/*.js"
63
63
  },
64
- "keywords": [],
65
- "author": "Andrea Giammarchi",
64
+ "keywords": [
65
+ "worker",
66
+ "SharedArrayBuffer",
67
+ "synchronous"
68
+ ],
69
+ "author": "Andrea Giammarchi (webreflection)",
66
70
  "license": "MIT",
67
71
  "type": "module",
68
72
  "types": "./types/index.d.ts",
package/rollup.js CHANGED
@@ -2,8 +2,8 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
2
2
  import terser from '@rollup/plugin-terser';
3
3
 
4
4
  import { writeFileSync } from 'fs';
5
-
6
- writeFileSync(`./src/channel.js`, `export default '${crypto.randomUUID()}';`);
5
+ if (process.env.NEW_CHANNEL)
6
+ writeFileSync(`./src/channel.js`, `export default '${crypto.randomUUID()}';`);
7
7
 
8
8
  const plugins = [nodeResolve()].concat(process.env.NO_MIN ? [] : [terser()]);
9
9
 
package/src/channel.js CHANGED
@@ -1 +1 @@
1
- export default 'eac8422c-ea74-4190-9b8c-7966827497f0';
1
+ export default 'fc260aad-4404-43b8-ae9d-2c06554bb294';
package/src/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import withResolvers from '@webreflection/utils/with-resolvers';
2
2
  import { native } from '@webreflection/utils/shared-array-buffer';
3
3
 
4
+ /** @typedef {import('./main/shared.js').Options} MainOptions */
5
+ /** @typedef {import('./worker/shared.js').Options} WorkerOptions */
6
+
4
7
  /** @type {string} */
5
8
  let channel;
6
9
 
package/src/main/async.js CHANGED
@@ -12,8 +12,8 @@ export class Worker extends Sender {
12
12
  const sab = SAB(options);
13
13
  const i32a = new Int32Array(sab);
14
14
  const handle = handler(sab, options, false);
15
- bc.addEventListener('message', async ({ data: [id, data] }) => {
16
- await handle({ data });
15
+ bc.addEventListener('message', async ({ data: [id, payload] }) => {
16
+ await handle({ data: payload });
17
17
  bc.postMessage([id, i32a.slice(0, 2 + i32a[1])]);
18
18
  });
19
19
  super(...url(scriptURL, CHANNEL, options));
@@ -22,8 +22,8 @@ export const SAB = ({
22
22
 
23
23
  /**
24
24
  * @typedef {Object} Options
25
- * @property {(data: unknown) => Promise<Int32Array>} ondata invoked when the worker expect a response as `Int32Array` to populate the SharedArrayBuffer with.
26
- * @property {(data: unknown) => unknown} [onsend] invoked when the worker replies to a `worker.send(data)` call.
25
+ * @property {(payload: unknown) => Int32Array | Promise<Int32Array>} onsync invoked when the worker expect a response as `Int32Array` to populate the SharedArrayBuffer with.
26
+ * @property {(payload: unknown) => unknown | Promise<unknown>} [onsend] invoked when the worker replies to a `worker.send(data)` call.
27
27
  * @property {number} [initByteLength=1024] defines the initial byte length of the SharedArrayBuffer.
28
28
  * @property {number} [maxByteLength=8192] defines the maximum byte length (growth) of the SharedArrayBuffer.
29
29
  * @property {string | ServiceWorkerOptions} [serviceWorker] defines the service worker to use as fallback if SharedArrayBuffer is not supported. If not defined, the `async` fallback will be used so that no `sync` operations from the worker will be possible.
@@ -52,7 +52,7 @@ export const bootstrap = Worker => {
52
52
  export const handler = (sab, options, useAtomics) => {
53
53
  const i32a = new Int32Array(sab);
54
54
  return async ({ data }) => {
55
- const result = await options.ondata(data);
55
+ const result = await options.onsync(data);
56
56
  const length = result.length;
57
57
  const requiredByteLength = minByteLength + result.buffer.byteLength;
58
58
  if (sab.byteLength < requiredByteLength) sab.grow(requiredByteLength);
package/src/main/xhr.js CHANGED
@@ -18,11 +18,8 @@ sharedBC.addEventListener('message', async ({ data: [op, details] }) => {
18
18
  const [uid, [id, channel]] = details;
19
19
  const responses = channels.get(channel);
20
20
  if (responses) {
21
- const promise = responses.get(id);
22
- if (promise) {
23
- responses.delete(id);
24
- sharedBC.postMessage(['response', [uid, await promise]]);
25
- }
21
+ sharedBC.postMessage(['response', [uid, await responses.get(id)]]);
22
+ responses.delete(id);
26
23
  }
27
24
  }
28
25
  });
@@ -75,10 +72,10 @@ class Worker extends Sender {
75
72
  const i32a = new Int32Array(sab);
76
73
  const handle = handler(sab, options, false);
77
74
  channels.set(channel, responses);
78
- bc.addEventListener('message', async ({ data: [id, data] }) => {
75
+ bc.addEventListener('message', async ({ data: [id, payload] }) => {
79
76
  const { promise, resolve } = withResolvers();
80
77
  responses.set(id, promise);
81
- await handle({ data });
78
+ await handle({ data: payload });
82
79
  resolve(i32a.slice(0, 2 + i32a[1]));
83
80
  });
84
81
  super(...url(scriptURL, CHANNEL, options));
@@ -10,8 +10,8 @@ const url = `${protocol}//${host}${pathname}`;
10
10
  const bc = new BroadcastChannel(CHANNEL);
11
11
  bc.addEventListener('message', ({ data: [op, details] }) => {
12
12
  if (op === 'response') {
13
- const [uid, data] = details;
14
- resolve(uid, `[${data.join(',')}]`);
13
+ const [uid, payload] = details;
14
+ resolve(uid, `[${payload.join(',')}]`);
15
15
  }
16
16
  });
17
17
 
@@ -17,17 +17,17 @@ const handle = (channel, i32a, options) => {
17
17
  const bc = new BroadcastChannel(channel);
18
18
  const next = i32();
19
19
  const map = new Map;
20
- bc.addEventListener('message', ({ data: [id, data] }) => {
21
- const [resolve, rest] = map.get(id);
22
- i32a.set(data, 0);
23
- resolve(options.ondata(i32a.subarray(2, 2 + i32a[1])));
20
+ bc.addEventListener('message', ({ data: [id, payload] }) => {
21
+ i32a.set(payload, 0);
22
+ map.get(id)(options.onsync(i32a.subarray(2, 2 + i32a[1])));
23
+ map.delete(id);
24
24
  });
25
- return (data, ...rest) => {
25
+ return (payload, ...rest) => {
26
26
  const { promise, resolve } = withResolvers();
27
27
  const id = next();
28
- map.set(id, [resolve, rest]);
28
+ map.set(id, resolve);
29
29
  // @ts-ignore
30
- bc.postMessage([id, data], ...rest);
30
+ bc.postMessage([id, payload], ...rest);
31
31
  return promise;
32
32
  };
33
33
  };
@@ -4,22 +4,22 @@ const { load, store, wait } = Atomics;
4
4
 
5
5
  /**
6
6
  * @typedef {Object} Options
7
- * @property {(data: Int32Array) => unknown} ondata transforms the resulting `Int32Array` from *main* thread into a value usable within the worker.
8
- * @property {(data: unknown) => Promise<unknown>} onsend invoked to define what to return to the *main* thread when it calls `worker.send(data)`.
7
+ * @property {(payload: Int32Array) => unknown} onsync transforms the resulting `Int32Array` from *main* thread into a value usable within the worker.
8
+ * @property {(payload: unknown) => unknown |Promise<unknown>} onsend invoked to define what to return to the *main* thread when it calls `worker.send(payload)`.
9
9
  */
10
10
 
11
11
  /**
12
12
  * @param {MessageChannel | BroadcastChannel} channel
13
13
  * @param {Int32Array} i32a
14
14
  * @param {Options} options
15
- * @returns {(data: unknown, ...rest: unknown[]) => unknown}
15
+ * @returns {(payload: unknown, ...rest: unknown[]) => unknown}
16
16
  */
17
- const handle = (channel, i32a, options) => (data, ...rest) => {
17
+ const handle = (channel, i32a, options) => (payload, ...rest) => {
18
18
  // @ts-ignore
19
- channel.postMessage(data, ...rest);
19
+ channel.postMessage(payload, ...rest);
20
20
  wait(i32a, 0, 0);
21
21
  store(i32a, 0, 0);
22
- return options.ondata(i32a.subarray(2, 2 + load(i32a, 1)));
22
+ return options.onsync(i32a.subarray(2, 2 + load(i32a, 1)));
23
23
  };
24
24
 
25
25
  /**
package/src/worker/xhr.js CHANGED
@@ -19,16 +19,16 @@ const handle = (channel, i32a, options) => {
19
19
  const bc = new BroadcastChannel(channel);
20
20
  const next = i32();
21
21
  const { serviceWorker } = options;
22
- return (data, ...rest) => {
22
+ return (payload, ...rest) => {
23
23
  const id = next();
24
24
  // @ts-ignore
25
- bc.postMessage([id, data], ...rest);
25
+ bc.postMessage([id, payload], ...rest);
26
26
  const xhr = new XMLHttpRequest;
27
27
  xhr.open('POST', serviceWorker, false);
28
28
  xhr.setRequestHeader('Content-Type', 'application/json');
29
29
  xhr.send(stringify([id, channel]));
30
30
  i32a.set(parse(xhr.responseText), 0);
31
- return options.ondata(i32a.subarray(2, 2 + i32a[1]));
31
+ return options.onsync(i32a.subarray(2, 2 + i32a[1]));
32
32
  };
33
33
  };
34
34
 
@@ -0,0 +1,11 @@
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.0">
6
+ <style>body{font-family:sans-serif}</style>
7
+ <title>reflected README</title>
8
+ <script src="./mini-coi.js"></script>
9
+ <script type="module" src="./index.js"></script>
10
+ </head>
11
+ </html>
@@ -1,13 +1,4 @@
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.0">
6
- <style>body{font-family:sans-serif}</style>
7
- <title>reflected README</title>
8
- <script src="mini-coi.js"></script>
9
- <script type="module">
10
- import reflect, { channel } from '../dist/index.js';
1
+ import reflect, { channel } from '../../dist/index.js';
11
2
 
12
3
  function test_sum(...args) {
13
4
  let i = 0;
@@ -19,7 +10,7 @@ function test_sum(...args) {
19
10
  // ℹ️ must await the initialization
20
11
  const worker = await reflect(
21
12
  // Worker scriptURL
22
- './readme.js',
13
+ './worker.js',
23
14
  // Worker options + required utilities / helpers
24
15
  // ℹ️ type is enforced to be 'module' due top-level await
25
16
  {
@@ -30,7 +21,7 @@ const worker = await reflect(
30
21
  // ⚠️ the worker is not responsive until this returns so
31
22
  // be sure you handle errors gracefully to still provide
32
23
  // a result the worker can consume out of the shared buffer!
33
- async ondata(payload) {
24
+ async onsync(payload) {
34
25
  const { invoke, args } = payload;
35
26
 
36
27
  if (invoke === 'test_sum') {
@@ -61,6 +52,3 @@ const worker = await reflect(
61
52
 
62
53
  document.body.append(channel, ' ');
63
54
  document.body.append(JSON.stringify(await worker.send({ any: 'payload' })));
64
- </script>
65
- </head>
66
- </html>
@@ -0,0 +1,28 @@
1
+ /*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */
2
+ /*! mini-coi - Andrea Giammarchi and contributors, licensed under MIT */
3
+ (({ document: d, navigator: { serviceWorker: s } }) => {
4
+ if (d) {
5
+ const { currentScript: c } = d;
6
+ s.register(c.src, { scope: c.getAttribute('scope') || '.' }).then(r => {
7
+ r.addEventListener('updatefound', () => location.reload());
8
+ if (r.active && !s.controller) location.reload();
9
+ });
10
+ }
11
+ else {
12
+ addEventListener('install', () => skipWaiting());
13
+ addEventListener('activate', e => e.waitUntil(clients.claim()));
14
+ addEventListener('fetch', e => {
15
+ const { request: r } = e;
16
+ if (r.cache === 'only-if-cached' && r.mode !== 'same-origin') return;
17
+ e.respondWith(fetch(r).then(r => {
18
+ const { body, status, statusText } = r;
19
+ if (!status || status > 399) return r;
20
+ const h = new Headers(r.headers);
21
+ h.set('Cross-Origin-Opener-Policy', 'same-origin');
22
+ h.set('Cross-Origin-Embedder-Policy', 'require-corp');
23
+ h.set('Cross-Origin-Resource-Policy', 'cross-origin');
24
+ return new Response(status == 204 ? null : body, { status, statusText, headers: h });
25
+ }));
26
+ });
27
+ }
28
+ })(self);
@@ -1,4 +1,4 @@
1
- import reflect, { channel } from '../dist/index.js';
1
+ import reflect, { channel } from '../../dist/index.js';
2
2
 
3
3
  // ℹ️ must await the initialization
4
4
  const reflected = await reflect({
@@ -6,7 +6,7 @@ const reflected = await reflect({
6
6
  // use this helper to transform such data into something
7
7
  // that the worker can use/understand after invoke
8
8
  // ℹ️ must be synchronous and it's invoked synchronously
9
- ondata(response) {
9
+ onsync(response) {
10
10
  return response.length ? response[0] : undefined;
11
11
  },
12
12
 
package/test/index.js CHANGED
@@ -8,7 +8,7 @@ try {
8
8
  // console.log('onsend', data, rest);
9
9
  return data;
10
10
  },
11
- ondata: async (data, ...rest) => {
11
+ onsync: async (data, ...rest) => {
12
12
  // console.log('main', data, rest);
13
13
  // await new Promise(resolve => setTimeout(resolve, 1000));
14
14
  return new Int32Array([6, 7, 8, 9, 10]);
package/test/sw.js CHANGED
@@ -1 +1 @@
1
- const e=Promise.withResolvers||function(){var e,t,n=new this((n,s)=>{e=n,t=s});return{resolve:e,reject:t,promise:n}};var t=e.bind(Promise);const[n,s]=((e=e=>e)=>{const n=new Map,s=(()=>{const e=new Int32Array(1);return()=>e[0]++})();return[()=>{let r;do{r=e(s())}while(n.has(r));const a=t();return n.set(r,a),[r,a.promise]},(e,t,s)=>{const r=n.get(e);n.delete(e),s?r?.reject(s):r?.resolve(t)}]})(),{protocol:r,host:a,pathname:o}=location,i=`${r}//${a}${o}`,c=new BroadcastChannel("eac8422c-ea74-4190-9b8c-7966827497f0");c.addEventListener("message",({data:[e,t]})=>{if("response"===e){const[e,n]=t;s(e,`[${n.join(",")}]`)}});const d=async e=>{const[t,s]=n();return c.postMessage(["request",[t,e]]),new Response(await s)};addEventListener("activate",e=>e.waitUntil(clients.claim())),addEventListener("fetch",async e=>{const{request:t}=e;"POST"===t.method&&t.url.startsWith(i)&&(e.stopImmediatePropagation(),e.respondWith(t.json().then(d)),e.preventDefault())}),addEventListener("install",()=>skipWaiting());
1
+ const e=Promise.withResolvers||function(){var e,t,n=new this((n,s)=>{e=n,t=s});return{resolve:e,reject:t,promise:n}};var t=e.bind(Promise);const[n,s]=((e=e=>e)=>{const n=new Map,s=(()=>{const e=new Int32Array(1);return()=>e[0]++})();return[()=>{let a;do{a=e(s())}while(n.has(a));const r=t();return n.set(a,r),[a,r.promise]},(e,t,s)=>{const a=n.get(e);n.delete(e),s?a?.reject(s):a?.resolve(t)}]})(),{protocol:a,host:r,pathname:o}=location,i=`${a}//${r}${o}`,c=new BroadcastChannel("fc260aad-4404-43b8-ae9d-2c06554bb294");c.addEventListener("message",({data:[e,t]})=>{if("response"===e){const[e,n]=t;s(e,`[${n.join(",")}]`)}});const d=async e=>{const[t,s]=n();return c.postMessage(["request",[t,e]]),new Response(await s)};addEventListener("activate",e=>e.waitUntil(clients.claim())),addEventListener("fetch",async e=>{const{request:t}=e;"POST"===t.method&&t.url.startsWith(i)&&(e.stopImmediatePropagation(),e.respondWith(t.json().then(d)),e.preventDefault())}),addEventListener("install",()=>skipWaiting());
package/test/worker.js CHANGED
@@ -5,7 +5,7 @@ const sync = await reflected({
5
5
  // console.log('worker', [...data], rest);
6
6
  return data;
7
7
  },
8
- ondata: (data, ...rest) => {
8
+ onsync: (data, ...rest) => {
9
9
  // console.log('worker', [...data], rest);
10
10
  return data;
11
11
  }
@@ -17,5 +17,5 @@ declare const _default: ((scriptURL: string, options: import("./main/shared.js")
17
17
  onmessage: (this: Worker, ev: MessageEvent) => any;
18
18
  onmessageerror: (this: Worker, ev: MessageEvent) => any;
19
19
  };
20
- }>) | ((options: import("./worker/shared.js").Options) => Promise<(data: unknown, ...rest: unknown[]) => unknown>);
20
+ }>) | ((options: import("./worker/shared.js").Options) => Promise<(payload: unknown, ...rest: unknown[]) => unknown>);
21
21
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "eac8422c-ea74-4190-9b8c-7966827497f0";
1
+ declare const _default: "fc260aad-4404-43b8-ae9d-2c06554bb294";
2
2
  export default _default;
package/types/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export default module;
2
+ export type MainOptions = import("./main/shared.js").Options;
3
+ export type WorkerOptions = import("./worker/shared.js").Options;
4
+ /** @typedef {import('./main/shared.js').Options} MainOptions */
5
+ /** @typedef {import('./worker/shared.js').Options} WorkerOptions */
2
6
  /** @type {string} */
3
7
  export let channel: string;
4
8
  /** @type {Function} */
@@ -24,11 +24,11 @@ export type Options = {
24
24
  /**
25
25
  * invoked when the worker expect a response as `Int32Array` to populate the SharedArrayBuffer with.
26
26
  */
27
- ondata: (data: unknown) => Promise<Int32Array>;
27
+ onsync: (payload: unknown) => Int32Array | Promise<Int32Array>;
28
28
  /**
29
29
  * invoked when the worker replies to a `worker.send(data)` call.
30
30
  */
31
- onsend?: (data: unknown) => unknown;
31
+ onsend?: (payload: unknown) => unknown | Promise<unknown>;
32
32
  /**
33
33
  * defines the initial byte length of the SharedArrayBuffer.
34
34
  */
@@ -1,5 +1,5 @@
1
1
  export { channel } from "./worker/message.js";
2
- declare const _default: ((options: import("./worker/shared.js").Options) => Promise<(data: unknown, ...rest: unknown[]) => unknown>) | ((scriptURL: string, options: import("./main/shared.js").Options) => Promise<{
2
+ declare const _default: ((options: import("./worker/shared.js").Options) => Promise<(payload: unknown, ...rest: unknown[]) => unknown>) | ((scriptURL: string, options: import("./main/shared.js").Options) => Promise<{
3
3
  new (scriptURL: any, options: any, resolve: any): {
4
4
  get channel(): string;
5
5
  "__#private@#next": any;
@@ -24,7 +24,7 @@ export type Options = {
24
24
  /**
25
25
  * invoked when the worker expect a response as `Int32Array` to populate the SharedArrayBuffer with.
26
26
  */
27
- ondata: (data: unknown) => Promise<Int32Array>;
27
+ onsync: (data: unknown) => Promise<Int32Array>;
28
28
  /**
29
29
  * invoked when the worker replies to a `worker.send(data)` call.
30
30
  */
@@ -3,7 +3,7 @@ export type Options = {
3
3
  /**
4
4
  * transforms the resulting `Int32Array` from *main* thread into a value usable within the worker.
5
5
  */
6
- ondata: (data: Int32Array) => unknown;
6
+ onsync: (data: Int32Array) => unknown;
7
7
  /**
8
8
  * invoked to define what to return to the *main* thread when it calls `worker.send(data)`.
9
9
  */
@@ -1,3 +1,3 @@
1
1
  export const channel: "broadcast";
2
- declare const _default: (options: import("./shared.js").Options) => Promise<(data: unknown, ...rest: unknown[]) => unknown>;
2
+ declare const _default: (options: import("./shared.js").Options) => Promise<(payload: unknown, ...rest: unknown[]) => unknown>;
3
3
  export default _default;
@@ -1,3 +1,3 @@
1
1
  export const channel: "message";
2
- declare const _default: (options: import("./shared.js").Options) => Promise<(data: unknown, ...rest: unknown[]) => unknown>;
2
+ declare const _default: (options: import("./shared.js").Options) => Promise<(payload: unknown, ...rest: unknown[]) => unknown>;
3
3
  export default _default;
@@ -1,11 +1,11 @@
1
- export function handler(promise: Promise<[SharedArrayBuffer, Options, MessageChannel | BroadcastChannel]>, listener: (event: MessageEvent) => void): (options: Options) => Promise<(data: unknown, ...rest: unknown[]) => unknown>;
1
+ export function handler(promise: Promise<[SharedArrayBuffer, Options, MessageChannel | BroadcastChannel]>, listener: (event: MessageEvent) => void): (options: Options) => Promise<(payload: unknown, ...rest: unknown[]) => unknown>;
2
2
  export type Options = {
3
3
  /**
4
4
  * transforms the resulting `Int32Array` from *main* thread into a value usable within the worker.
5
5
  */
6
- ondata: (data: Int32Array) => unknown;
6
+ onsync: (payload: Int32Array) => unknown;
7
7
  /**
8
- * invoked to define what to return to the *main* thread when it calls `worker.send(data)`.
8
+ * invoked to define what to return to the *main* thread when it calls `worker.send(payload)`.
9
9
  */
10
- onsend: (data: unknown) => Promise<unknown>;
10
+ onsend: (payload: unknown) => unknown | Promise<unknown>;
11
11
  };
@@ -1 +0,0 @@
1
- import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as s}from"./i32-C78nBJH2.js";import{s as t}from"./sender-23_Enxlo.js";import"./channel-BwDpH9fR.js";const{promise:a,resolve:r}=e();addEventListener("message",({data:[e,s,t]})=>r([e,s,t]),{once:!0});const n="async";var o=r=>a.then(([a,n,o])=>(postMessage(1),((t,a,r)=>{const n=new BroadcastChannel(t),o=s(),d=new Map;return n.addEventListener("message",({data:[e,s]})=>{const[t,n]=d.get(e);a.set(s,0),t(r.ondata(a.subarray(2,2+a[1])))}),(s,...t)=>{const{promise:a,resolve:r}=e(),i=o();return d.set(i,[r,t]),n.postMessage([i,s],...t),a}})(o,new Int32Array(a),t({...n,...r}))));export{n as channel,o as default};
@@ -1 +0,0 @@
1
- var a="eac8422c-ea74-4190-9b8c-7966827497f0";export{a as S};
@@ -1 +0,0 @@
1
- import{w as e}from"./with-resolvers-CHEvl4oe.js";import{i as t}from"./i32-C78nBJH2.js";import{S as s}from"./channel-BwDpH9fR.js";const{isArray:r}=Array,n=e=>e;class a extends Worker{#e;#t;constructor(e,a){super(e,a),this.#e=t(),this.#t=new Map,a.onsend||(a.onsend=n),super.addEventListener("message",async e=>{const{data:t}=e;if(r(t)&&t[0]===s){e.stopImmediatePropagation(),e.preventDefault();const[s,r]=t[1],n=this.#t.get(s);this.#t.delete(s),n(await a.onsend(r))}})}send(t,...r){const n=this.#e(),{promise:a,resolve:o}=e();return this.#t.set(n,o),super.postMessage([s,[n,t]],...r),a}}const{notify:o,store:i}=Atomics,c=2*Int32Array.BYTES_PER_ELEMENT,u=({initByteLength:e=1024,maxByteLength:t=8192})=>new SharedArrayBuffer(c+e,{maxByteLength:c+t}),h=t=>(s,r)=>{const{promise:n,resolve:a}=e();return new t(s,r,a),n},m=(e,t,s)=>{const r=new Int32Array(e);return async({data:n})=>{const a=await t.ondata(n),u=a.length,h=c+a.buffer.byteLength;e.byteLength<h&&e.grow(h),r.set(a,2),s?(i(r,1,u),i(r,0,1),o(r,0)):(r[1]=u,r[0]=1)}},p=e=>{switch(typeof e){case"symbol":case"function":return!1}return!0},d=(e,t)=>{const s={};for(const e in t){const r=t[e];p(e)&&p(r)&&(s[e]=r)}return[e,s]},y=(e,t,s)=>{const r=new URL(e,location.href);return r.searchParams.set("reflected",t),[r,{...s,type:"module"}]};export{a as S,u as a,h as b,m as h,c as m,d as p,y as u};
@@ -1 +0,0 @@
1
- import{s}from"./sender-23_Enxlo.js";const{load:e,store:a,wait:t}=Atomics,o=(o,r)=>(addEventListener("message",r,{once:!0}),r=>o.then(([o,n,d])=>(postMessage(1),((s,o,r)=>(n,...d)=>(s.postMessage(n,...d),t(o,0,0),a(o,0,0),r.ondata(o.subarray(2,2+e(o,1)))))(d,new Int32Array(o),s({...n,...r})))));export{o as h};
@@ -1 +0,0 @@
1
- import{w as e}from"./with-resolvers-CHEvl4oe.js";import{m as t,S as s,u as n,p as a,h as r}from"./shared-D9sRqO2H.js";import{S as o}from"./shared-array-buffer-cwdMr2mc.js";import{r as i}from"./shared-RFmxa5x4.js";import{S as c}from"./channel-BwDpH9fR.js";import"./i32-C78nBJH2.js";var l=({initByteLength:e=1024,maxByteLength:s=8192})=>new o(t+e,{maxByteLength:t+s});const d="async";let h=class extends s{constructor(e,t,s){const o=i(),c=new BroadcastChannel(o),h=l(t),p=new Int32Array(h),g=r(h,t,!1);c.addEventListener("message",async({data:[e,t]})=>{await g({data:t}),c.postMessage([e,p.slice(0,2+p[1])])}),super(...n(e,d,t)),super.addEventListener("message",()=>s(this),{once:!0}),super.postMessage(a(h,t).concat(o))}get channel(){return d}};const p=new Map,g=new BroadcastChannel(c);g.addEventListener("message",async({data:[e,t]})=>{if("request"===e){const[e,[s,n]]=t,a=p.get(n);if(a){const t=a.get(s);t&&(a.delete(s),g.postMessage(["response",[e,await t]]))}}});const{promise:u,resolve:m}=e();let f=!0;const v=(e,t)=>{let s,n=!0,{url:a}=t;e.getRegistration(a).then(s=>s??e.register(a,t)).then(function r(o){const{controller:i}=e;if(n=n&&!!i,s=o.installing||o.waiting||o.active,!s)return v(e,t);if("activated"===s.state){if(n){if(i.scriptURL===a)return m();o.unregister()}location.reload()}else s.addEventListener("statechange",()=>r(o),{once:!0})})};class w extends s{#e;constructor(t,s,o){if(f){f=!1;let{serviceWorker:e}=s;if(!e)return new h(t,s,o);"string"==typeof e&&(e={url:e}),e.url=new URL(e.url,location.href).href,v(navigator.serviceWorker,e)}const c=i(),d=new BroadcastChannel(c),g=l(s),u=new Map,m=new Int32Array(g),w=r(g,s,!1);p.set(c,u),d.addEventListener("message",async({data:[t,s]})=>{const{promise:n,resolve:a}=e();u.set(t,n),await w({data:s}),a(m.slice(0,2+m[1]))}),super(...n(t,"xhr",s)),super.addEventListener("message",()=>o(this),{once:!0}),super.postMessage(a(g,s).concat(c)),this.#e=c}terminate(){p.delete(this.#e),super.terminate()}get channel(){return"xhr"}}var y=(t,s)=>{const{promise:n,resolve:a}=e();return new w(t,s,a)instanceof h?n:u.then(()=>n)};export{y as default};