databonk 0.0.4 → 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.
Files changed (45) hide show
  1. package/README.md +491 -96
  2. package/dist/dataframe-BggBYXYm.d.cts +886 -0
  3. package/dist/dataframe-BggBYXYm.d.ts +886 -0
  4. package/dist/index.cjs +5 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.d.cts +366 -0
  7. package/dist/index.d.ts +354 -31
  8. package/dist/index.js +4 -40
  9. package/dist/index.js.map +1 -1
  10. package/dist/parallel-fv5h4BkA.d.cts +152 -0
  11. package/dist/parallel-fv5h4BkA.d.ts +152 -0
  12. package/dist/parquet.cjs +3 -0
  13. package/dist/parquet.cjs.map +1 -0
  14. package/dist/parquet.d.cts +57 -0
  15. package/dist/parquet.d.ts +57 -0
  16. package/dist/parquet.js +3 -0
  17. package/dist/parquet.js.map +1 -0
  18. package/dist/scalar.wasm +0 -0
  19. package/dist/simd-threads.wasm +0 -0
  20. package/dist/simd.wasm +0 -0
  21. package/dist/workers.cjs +102 -0
  22. package/dist/workers.cjs.map +1 -0
  23. package/dist/workers.d.cts +74 -0
  24. package/dist/workers.d.ts +74 -0
  25. package/dist/workers.js +102 -0
  26. package/dist/workers.js.map +1 -0
  27. package/package.json +93 -32
  28. package/build/release.d.ts +0 -719
  29. package/build/release.js +0 -774
  30. package/build/release.wasm +0 -0
  31. package/build/release.wasm.map +0 -1
  32. package/build/release.wat +0 -22633
  33. package/dist/dataframe.d.ts +0 -82
  34. package/dist/dataframe.d.ts.map +0 -1
  35. package/dist/dataframe.js +0 -318
  36. package/dist/dataframe.js.map +0 -1
  37. package/dist/index.d.ts.map +0 -1
  38. package/dist/loader.d.ts +0 -86
  39. package/dist/loader.d.ts.map +0 -1
  40. package/dist/loader.js +0 -147
  41. package/dist/loader.js.map +0 -1
  42. package/dist/shared-memory.d.ts +0 -64
  43. package/dist/shared-memory.d.ts.map +0 -1
  44. package/dist/shared-memory.js +0 -113
  45. package/dist/shared-memory.js.map +0 -1
Binary file
Binary file
package/dist/simd.wasm ADDED
Binary file
@@ -0,0 +1,102 @@
1
+ 'use strict';var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var p=`
2
+ ;(function workerMain() {
3
+ var isNode = (
4
+ typeof process !== 'undefined' &&
5
+ typeof process.versions === 'object' &&
6
+ typeof process.versions.node === 'string'
7
+ );
8
+
9
+ /* Capture 'require' via a typeof guard so that the literal text
10
+ * 'require(' never appears in this file \u2014 packaging tools like publint
11
+ * use a regex heuristic (require\\s*\\() to classify CJS vs ESM, and a
12
+ * false-positive here would misclassify the ESM workers bundle.
13
+ * The guard is safe: in a Node.js eval worker this is always a function;
14
+ * in a browser worker it is undefined and the isNode guard short-circuits. */
15
+ var _workerRequire = typeof require === 'function' ? require : null;
16
+
17
+ var wasm = null; /* WebAssembly exports, set on 'init' */
18
+
19
+ /* ------------------------------------------------------------------ */
20
+ /* send a message back to the main thread */
21
+ /* ------------------------------------------------------------------ */
22
+ function send(msg) {
23
+ if (isNode) {
24
+ _workerRequire('worker_threads').parentPort.postMessage(msg);
25
+ } else {
26
+ /* global postMessage available in browser Worker scope */
27
+ postMessage(msg);
28
+ }
29
+ }
30
+
31
+ /* ------------------------------------------------------------------ */
32
+ /* message handler */
33
+ /* ------------------------------------------------------------------ */
34
+ function handle(msg) {
35
+ var type = msg.type;
36
+ var requestId = msg.requestId;
37
+
38
+ /* ---- init: receive wasm bytes + shared memory, instantiate ---- */
39
+ if (type === 'init') {
40
+ var bytes = msg.bytes;
41
+ /* Accept Uint8Array or ArrayBuffer */
42
+ var src = (bytes instanceof Uint8Array) ? bytes.buffer : bytes;
43
+ WebAssembly
44
+ .instantiate(src, { env: { memory: msg.memory } })
45
+ .then(function(r) {
46
+ wasm = r.instance.exports;
47
+ /* Workers NEVER call __wasm_init_memory \u2014 only the main thread does.
48
+ * All our static-mut arena variables are zero-initialised (BSS),
49
+ * so the shared linear memory already contains the correct values
50
+ * written by the main thread's instantiation. */
51
+ send({ type: 'ready', requestId: requestId });
52
+ })
53
+ .catch(function(e) {
54
+ send({ type: 'error', requestId: requestId, error: String(e) });
55
+ });
56
+ return;
57
+ }
58
+
59
+ if (!wasm) {
60
+ send({ type: 'error', requestId: requestId, error: 'worker not initialised' });
61
+ return;
62
+ }
63
+
64
+ /* ---- kernel: single wasm kernel call, returns one number ---- */
65
+ if (type === 'kernel') {
66
+ try {
67
+ var result = wasm[msg.fn].apply(null, msg.args);
68
+ send({ type: 'result', requestId: requestId, value: +result });
69
+ } catch(e) {
70
+ send({ type: 'error', requestId: requestId, error: String(e) });
71
+ }
72
+ return;
73
+ }
74
+
75
+ /* ---- meta: batch of kernel calls, returns one number per op ---- */
76
+ if (type === 'meta') {
77
+ try {
78
+ var ops = msg.ops;
79
+ var values = new Array(ops.length);
80
+ for (var i = 0; i < ops.length; i++) {
81
+ values[i] = +wasm[ops[i].fn].apply(null, ops[i].args);
82
+ }
83
+ send({ type: 'values', requestId: requestId, values: values });
84
+ } catch(e) {
85
+ send({ type: 'error', requestId: requestId, error: String(e) });
86
+ }
87
+ return;
88
+ }
89
+ }
90
+
91
+ /* ------------------------------------------------------------------ */
92
+ /* wire up message listener */
93
+ /* ------------------------------------------------------------------ */
94
+ if (isNode) {
95
+ _workerRequire('worker_threads').parentPort.on('message', handle);
96
+ } else {
97
+ /* browser Web Worker */
98
+ self.onmessage = function(e) { handle(e.data); };
99
+ }
100
+ })();
101
+ `;var v=typeof process<"u"&&typeof process.versions=="object"&&typeof process.versions.node=="string";async function g(){if(v){let{Worker:t}=await import('worker_threads');return new t(p,{eval:true})}let u=new Blob([p],{type:"text/javascript"}),e=URL.createObjectURL(u),r=new Worker(e);return URL.revokeObjectURL(e),r}function w(u,e){v&&typeof u.on=="function"?u.on("message",e):u.onmessage=r=>e(r.data);}var b=class u{memory;wasmBytes;timeoutMs;slots=[];nextId=1;nextSlot=0;terminated=false;constructor(e,r,t){this.memory=e,this.wasmBytes=r,this.timeoutMs=t;}static async create(e,r,t,n=3e4){let s=new u(r,e,n),o=[];for(let i=0;i<t;i++)o.push(s.addWorker());return await Promise.all(o),s}async addWorker(){let e=await g(),r=new Map,t={raw:e,pending:r};return this.slots.push(t),w(e,n=>this.handleMessage(t,n)),new Promise((n,s)=>{let o=this.nextId++;r.set(o,{resolve:()=>n(),reject:s,timer:null}),e.postMessage({type:"init",requestId:o,bytes:this.wasmBytes,memory:this.memory});})}handleMessage(e,r){if(typeof r!="object"||r===null)return;let t=r,n=t.requestId,s=e.pending.get(n);s&&(e.pending.delete(n),s.timer!==null&&clearTimeout(s.timer),t.type==="error"?s.reject(new Error(String(t.error))):s.resolve(r));}async sendKernel(e,r){let t=this.slots[this.nextSlot%this.slots.length];this.nextSlot++;let n=this.nextId++;return (await this.sendToSlot(t,n,{type:"kernel",requestId:n,fn:e,args:r})).value}async sendMeta(e){let r=this.slots[this.nextSlot%this.slots.length];this.nextSlot++;let t=this.nextId++;return (await this.sendToSlot(r,t,{type:"meta",requestId:t,ops:e})).values}async broadcastKernel(e){let r=Math.min(e.length,this.slots.length),t=[];for(let n=0;n<r;n++){let{fn:s,args:o}=e[n],i=this.slots[n],a=this.nextId++;t.push(this.sendToSlot(i,a,{type:"kernel",requestId:a,fn:s,args:o}).then(l=>l.value));}return Promise.all(t)}async broadcastMeta(e){let r=Math.min(e.length,this.slots.length),t=[];for(let n=0;n<r;n++){let s=e[n],o=this.slots[n],i=this.nextId++;t.push(this.sendToSlot(o,i,{type:"meta",requestId:i,ops:s}).then(a=>a.values));}return Promise.all(t)}sendToSlot(e,r,t){return new Promise((n,s)=>{let o=null;this.timeoutMs>0&&(o=setTimeout(()=>{e.pending.delete(r),this.replaceSlot(e).catch(()=>{}),s(new Error(`kernel worker timed out (${this.timeoutMs} ms)`));},this.timeoutMs)),e.pending.set(r,{resolve:n,reject:s,timer:o}),e.raw.postMessage(t);})}async replaceSlot(e){try{e.raw.terminate();}catch{}let r=this.slots.indexOf(e);if(r===-1)return;for(let[,o]of e.pending)o.timer!==null&&clearTimeout(o.timer),o.reject(new Error("worker replaced after crash/timeout"));e.pending.clear();let t=await g(),n={raw:t,pending:new Map};w(t,o=>this.handleMessage(n,o)),this.slots[r]=n;let s=this.nextId++;await new Promise((o,i)=>{n.pending.set(s,{resolve:()=>o(),reject:i,timer:null}),t.postMessage({type:"init",requestId:s,bytes:this.wasmBytes,memory:this.memory});});}get size(){return this.slots.length}terminate(){if(!this.terminated){this.terminated=true;for(let e of this.slots){for(let[,r]of e.pending)r.timer!==null&&clearTimeout(r.timer),r.reject(new Error("pool terminated"));e.pending.clear();try{e.raw.terminate();}catch{}}this.slots.length=0;}}};var k=typeof process<"u"&&typeof process.versions=="object"&&typeof process.versions.node=="string";function P(){return typeof SharedArrayBuffer>"u"?false:k?true:typeof crossOriginIsolated<"u"&&crossOriginIsolated===true}async function x(u,e){if(k){let[{readFile:s},{fileURLToPath:o}]=await Promise.all([import('fs/promises'),import('url')]),i;if(e===void 0)i=o(new URL(u,(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('workers.cjs', document.baseURI).href))));else if(e instanceof URL)i=o(new URL(u,e));else if(e.startsWith("file:"))i=o(new URL(u,e));else {let{join:m}=await import('path');i=m(e,u);}let a=await s(i),l=a.buffer.slice(a.byteOffset,a.byteOffset+a.byteLength);return new Uint8Array(l)}let r=e??new URL(".",(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('workers.cjs', document.baseURI).href))),t=new URL(u,r),n=await fetch(t);if(!n.ok)throw new Error(`Failed to fetch ${t}: ${n.status}`);return new Uint8Array(await n.arrayBuffer())}function c(u,e){if(u===0||e<=0)return [];let r=Math.ceil(u/e),t=Math.ceil(r/8)*8,n=[];for(let s=0;s<u;s+=t)n.push([s,Math.min(s+t,u)]);return n}var f=class{constructor(e,r,t){this.pool=e;this.exports=r.exports,this.memory=t;}pool;enabled=true;memory;exports;get workers(){return this.pool.size}alloc(e){let r=this.exports.alloc(e);if(r===0)throw new Error(`threads wasm OOM allocating ${e} bytes`);return r}free(e){this.exports.free(e);}callKernel(e,...r){let t=this.exports[e];if(typeof t!="function")throw new Error(`kernel not found: ${e}`);return t(...r)}async sumF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return 0;if(n.length===1)return this.pool.sendKernel("sum_f64_null",[e,r,t]);let s=n.map(([a,l])=>({fn:"sum_f64_null",args:[e+a*8,r===0?0:r+(a>>3),l-a]})),o=await this.pool.broadcastKernel(s),i=0;for(let a of o)i+=a;return i}async meanF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("mean_f64_null",[e,r,t]);let s=n.map(([l,m])=>{let d=e+l*8,h=r===0?0:r+(l>>3),y=m-l;return [{fn:"sum_f64_null",args:[d,h,y]},{fn:"count_null",args:[h,y]}]}),o=await this.pool.broadcastMeta(s),i=0,a=0;for(let[l,m]of o)i+=l,a+=m;return a===0?NaN:i/a}async minF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("min_f64_null",[e,r,t]);let s=n.map(([i,a])=>({fn:"min_f64_null",args:[e+i*8,r===0?0:r+(i>>3),a-i]})),o=await this.pool.broadcastKernel(s);return M(o)}async maxF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("max_f64_null",[e,r,t]);let s=n.map(([i,a])=>({fn:"max_f64_null",args:[e+i*8,r===0?0:r+(i>>3),a-i]})),o=await this.pool.broadcastKernel(s);return _(o)}addF64(e,r,t,n){return this.parallelElementwiseBinary("add_f64",e,r,t,n,8)}subF64(e,r,t,n){return this.parallelElementwiseBinary("sub_f64",e,r,t,n,8)}mulF64(e,r,t,n){return this.parallelElementwiseBinary("mul_f64",e,r,t,n,8)}async parallelElementwiseBinary(e,r,t,n,s,o){let i=c(s,this.pool.size);if(i.length===0)return;if(i.length===1){await this.pool.sendKernel(e,[r,t,n,s]);return}let a=i.map(([l,m])=>{let d=l*o;return {fn:e,args:[r+d,t+d,n+d,m-l]}});await this.pool.broadcastKernel(a);}async parallelReduce(e,r,t,n,s){let o=c(n,this.pool.size);if(o.length===0)return [];let i=o.map(([a,l])=>({fn:e,args:[r+a*s,t===0?0:t+(a>>3),l-a]}));return this.pool.broadcastKernel(i)}terminate(){this.pool.terminate();}};function M(u){let e=NaN;for(let r of u)Number.isNaN(r)||(e=Number.isNaN(e)?r:Math.min(e,r));return e}function _(u){let e=NaN;for(let r of u)Number.isNaN(r)||(e=Number.isNaN(e)?r:Math.max(e,r));return e}async function S(u={}){if(!P())return console.warn("[databonk] enableThreads: SharedArrayBuffer is not available or cross-origin isolation is missing (COOP/COEP headers required in browsers). Parallel mode not activated. See docs/threads.md for setup instructions."),false;let e=u.workers??4,r=u.timeoutMs??3e4,t=u.initialPages??32,n=u.maxPages??16384,s=await x("simd-threads.wasm",u.wasmDir),o=new WebAssembly.Memory({initial:t,maximum:n,shared:true}),i=await WebAssembly.compile(s.buffer),a=await WebAssembly.instantiate(i,{env:{memory:o}}),l=a.exports;typeof l.__wasm_init_memory=="function"&&l.__wasm_init_memory();let m=await b.create(s,o,e,r);return new f(m,a,o)}exports.KernelWorkerPool=b;exports.enableThreads=S;exports.splitChunks=c;//# sourceMappingURL=workers.cjs.map
102
+ //# sourceMappingURL=workers.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/workers/kernel-worker-script.ts","../src/workers/pool.ts","../src/workers/parallel.ts"],"names":["KERNEL_WORKER_SCRIPT","isNode","createRawWorker","Worker","blob","url","w","wireWorkerMessages","raw","onMsg","e","KernelWorkerPool","_KernelWorkerPool","memory","wasmBytes","timeoutMs","numWorkers","pool","readyPromises","pending","slot","msg","resolve","reject","id","m","entry","fn","args","ops","perSlot","count","promises","i","r","timer","idx","p","newSlot","isNode_","isIsolated","loadBytes","fileName","wasmDir","readFile","fileURLToPath","filePath","join","ab","base","resp","splitChunks","len","cs","chunks","ThreadsHandleImpl","mainInstance","sharedMemory","bytes","ptr","f","dataPtr","vpPtr","s","partials","total","adjData","adjVp","clen","results","totalSum","totalCount","sum","combineMinF64","combineMaxF64","aPtr","bPtr","outPtr","elemBytes","off","result","enableThreads","config","initialPages","maxPages","module","instance","exports"],"mappings":"kGAqBO,IAAMA,CAAAA,CAAwC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECHrD,IAAMC,CAAAA,CACJ,OAAO,OAAA,CAAY,GAAA,EACnB,OAAO,OAAA,CAAQ,QAAA,EAAa,QAAA,EAC5B,OAAO,OAAA,CAAQ,QAAA,CAAS,MAAS,QAAA,CAwBnC,eAAeC,CAAAA,EAAuC,CACpD,GAAID,CAAAA,CAAQ,CACV,GAAM,CAAE,MAAA,CAAAE,CAAO,CAAA,CAAI,aAAa,gBAAqB,CAAA,CACrD,OAAO,IAAIA,CAAAA,CAAOH,CAAAA,CAAsB,CAAE,IAAA,CAAM,IAAK,CAAC,CACxD,CAEA,IAAMI,EAAO,IAAI,IAAA,CAAK,CAACJ,CAAoB,CAAA,CAAG,CAAE,KAAM,iBAAkB,CAAC,CAAA,CACnEK,CAAAA,CAAM,GAAA,CAAI,eAAA,CAAgBD,CAAI,CAAA,CAC9BE,CAAAA,CAAI,IAAI,MAAA,CAAOD,CAAG,EACxB,OAAA,GAAA,CAAI,eAAA,CAAgBA,CAAG,CAAA,CAChBC,CACT,CAEA,SAASC,CAAAA,CACPC,CAAAA,CACAC,CAAAA,CACM,CACFR,CAAAA,EAAU,OAAOO,EAAI,EAAA,EAAO,UAAA,CAC9BA,CAAAA,CAAI,EAAA,CAAG,SAAA,CAAWC,CAAK,EAEtBD,CAAAA,CAA0B,SAAA,CAAaE,CAAAA,EAAoBD,CAAAA,CAAMC,CAAAA,CAAE,IAAI,EAE5E,CAYO,IAAMC,CAAAA,CAAN,MAAMC,CAAiB,CACX,OACA,SAAA,CACA,SAAA,CACA,KAAA,CAAoB,EAAC,CAC9B,MAAA,CAAS,EACT,QAAA,CAAW,CAAA,CACX,UAAA,CAAa,KAAA,CAGb,WAAA,CACNC,CAAAA,CACAC,EACAC,CAAAA,CACA,CACA,KAAK,MAAA,CAASF,CAAAA,CACd,KAAK,SAAA,CAAYC,CAAAA,CACjB,IAAA,CAAK,SAAA,CAAYC,EACnB,CAMA,aAAa,MAAA,CACXD,CAAAA,CACAD,CAAAA,CACAG,CAAAA,CACAD,CAAAA,CAAY,GAAA,CACe,CAC3B,IAAME,CAAAA,CAAO,IAAIL,CAAAA,CAAiBC,CAAAA,CAAQC,CAAAA,CAAWC,CAAS,CAAA,CACxDG,CAAAA,CAAiC,EAAC,CACxC,IAAA,IAAS,CAAA,CAAI,EAAG,CAAA,CAAIF,CAAAA,CAAY,CAAA,EAAA,CAC9BE,CAAAA,CAAc,IAAA,CAAKD,CAAAA,CAAK,WAAW,CAAA,CAErC,OAAA,MAAM,OAAA,CAAQ,GAAA,CAAIC,CAAa,EACxBD,CACT,CAGA,MAAc,SAAA,EAA2B,CACvC,IAAMT,EAAM,MAAMN,CAAAA,EAAgB,CAC5BiB,CAAAA,CAAU,IAAI,GAAA,CACdC,EAAiB,CAAE,GAAA,CAAAZ,CAAAA,CAAK,OAAA,CAAAW,CAAQ,CAAA,CACtC,YAAK,KAAA,CAAM,IAAA,CAAKC,CAAI,CAAA,CAEpBb,CAAAA,CAAmBC,CAAAA,CAAMa,GAAQ,IAAA,CAAK,aAAA,CAAcD,CAAAA,CAAMC,CAAG,CAAC,CAAA,CAEvD,IAAI,OAAA,CAAc,CAACC,CAAAA,CAASC,CAAAA,GAAW,CAC5C,IAAMC,EAAK,IAAA,CAAK,MAAA,EAAA,CAChBL,CAAAA,CAAQ,GAAA,CAAIK,CAAAA,CAAI,CACd,QAAS,IAAMF,CAAAA,EAAQ,CACvB,MAAA,CAAAC,CAAAA,CACA,KAAA,CAAO,IACT,CAAC,CAAA,CACDf,CAAAA,CAAI,WAAA,CAAY,CACd,IAAA,CAAM,OACN,SAAA,CAAWgB,CAAAA,CACX,MAAO,IAAA,CAAK,SAAA,CACZ,OAAQ,IAAA,CAAK,MACf,CAAC,EACH,CAAC,CACH,CAEQ,aAAA,CAAcJ,CAAAA,CAAgBC,CAAAA,CAAoB,CACxD,GAAI,OAAOA,GAAQ,QAAA,EAAYA,CAAAA,GAAQ,IAAA,CAAM,OAC7C,IAAMI,CAAAA,CAAIJ,EACJG,CAAAA,CAAKC,CAAAA,CAAE,SAAA,CACPC,CAAAA,CAAQN,CAAAA,CAAK,OAAA,CAAQ,IAAII,CAAE,CAAA,CAC5BE,CAAAA,GACLN,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAOI,CAAE,CAAA,CAClBE,CAAAA,CAAM,KAAA,GAAU,IAAA,EAAM,YAAA,CAAaA,CAAAA,CAAM,KAAK,CAAA,CAE9CD,CAAAA,CAAE,IAAA,GAAY,OAAA,CAChBC,CAAAA,CAAM,MAAA,CAAO,IAAI,KAAA,CAAM,MAAA,CAAOD,EAAE,KAAQ,CAAC,CAAC,CAAA,CAE1CC,CAAAA,CAAM,OAAA,CAAQL,CAAG,CAAA,EAErB,CAMA,MAAM,UAAA,CAAWM,CAAAA,CAAYC,CAAAA,CAAiC,CAC5D,IAAMR,CAAAA,CAAO,KAAK,KAAA,CAAM,IAAA,CAAK,QAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAM,EACzD,IAAA,CAAK,QAAA,EAAA,CACL,IAAMI,CAAAA,CAAK,IAAA,CAAK,MAAA,EAAA,CAOhB,QANe,MAAM,IAAA,CAAK,UAAA,CAA8BJ,CAAAA,CAAMI,CAAAA,CAAI,CAChE,KAAM,QAAA,CACN,SAAA,CAAWA,CAAAA,CACX,EAAA,CAAAG,CAAAA,CACA,IAAA,CAAAC,CACF,CAAC,CAAA,EACa,KAChB,CAMA,MAAM,QAAA,CAASC,EAA+D,CAC5E,IAAMT,EAAO,IAAA,CAAK,KAAA,CAAM,KAAK,QAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,CACzD,IAAA,CAAK,WACL,IAAMI,CAAAA,CAAK,IAAA,CAAK,MAAA,EAAA,CAMhB,OAAA,CALe,MAAM,KAAK,UAAA,CAAiCJ,CAAAA,CAAMI,CAAAA,CAAI,CACnE,IAAA,CAAM,MAAA,CACN,UAAWA,CAAAA,CACX,GAAA,CAAAK,CACF,CAAC,CAAA,EACa,MAChB,CAMA,MAAM,eAAA,CACJC,CAAAA,CACmB,CACnB,IAAMC,CAAAA,CAAQ,KAAK,GAAA,CAAID,CAAAA,CAAQ,MAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,MAAM,EAClDE,CAAAA,CAA8B,EAAC,CACrC,IAAA,IAASC,CAAAA,CAAI,CAAA,CAAGA,EAAIF,CAAAA,CAAOE,CAAAA,EAAAA,CAAK,CAC9B,GAAM,CAAE,EAAA,CAAAN,EAAI,IAAA,CAAAC,CAAK,CAAA,CAAIE,CAAAA,CAAQG,CAAC,CAAA,CACxBb,EAAO,IAAA,CAAK,KAAA,CAAMa,CAAC,CAAA,CACnBT,CAAAA,CAAK,IAAA,CAAK,SAChBQ,CAAAA,CAAS,IAAA,CACP,IAAA,CAAK,UAAA,CAA8BZ,CAAAA,CAAMI,CAAAA,CAAI,CAC3C,IAAA,CAAM,QAAA,CACN,SAAA,CAAWA,CAAAA,CACX,EAAA,CAAAG,CAAAA,CACA,KAAAC,CACF,CAAC,CAAA,CAAE,IAAA,CAAMM,CAAAA,EAAMA,CAAAA,CAAE,KAAK,CACxB,EACF,CACA,OAAO,OAAA,CAAQ,GAAA,CAAIF,CAAQ,CAC7B,CAMA,MAAM,aAAA,CACJF,CAAAA,CACqB,CACrB,IAAMC,CAAAA,CAAQ,IAAA,CAAK,IAAID,CAAAA,CAAQ,MAAA,CAAQ,KAAK,KAAA,CAAM,MAAM,CAAA,CAClDE,CAAAA,CAAgC,EAAC,CACvC,QAASC,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIF,CAAAA,CAAOE,CAAAA,EAAAA,CAAK,CAC9B,IAAMJ,CAAAA,CAAMC,CAAAA,CAAQG,CAAC,CAAA,CACfb,CAAAA,CAAO,IAAA,CAAK,MAAMa,CAAC,CAAA,CACnBT,CAAAA,CAAK,IAAA,CAAK,MAAA,EAAA,CAChBQ,CAAAA,CAAS,KACP,IAAA,CAAK,UAAA,CAAiCZ,CAAAA,CAAMI,CAAAA,CAAI,CAC9C,IAAA,CAAM,OACN,SAAA,CAAWA,CAAAA,CACX,GAAA,CAAAK,CACF,CAAC,CAAA,CAAE,KAAMK,CAAAA,EAAMA,CAAAA,CAAE,MAAM,CACzB,EACF,CACA,OAAO,OAAA,CAAQ,GAAA,CAAIF,CAAQ,CAC7B,CAEQ,WACNZ,CAAAA,CACAI,CAAAA,CACAH,CAAAA,CACY,CACZ,OAAO,IAAI,QAAW,CAACC,CAAAA,CAASC,CAAAA,GAAW,CACzC,IAAIY,CAAAA,CAA8C,KAC9C,IAAA,CAAK,SAAA,CAAY,CAAA,GACnBA,CAAAA,CAAQ,UAAA,CAAW,IAAM,CACvBf,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAOI,CAAE,CAAA,CAEtB,IAAA,CAAK,YAAYJ,CAAI,CAAA,CAAE,KAAA,CAAM,IAAM,CAAa,CAAC,EACjDG,CAAAA,CAAO,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAA,CAAK,SAAS,MAAM,CAAC,EACpE,CAAA,CAAG,IAAA,CAAK,SAAS,CAAA,CAAA,CAEnBH,EAAK,OAAA,CAAQ,GAAA,CAAII,EAAI,CACnB,OAAA,CAASF,EACT,MAAA,CAAAC,CAAAA,CACA,KAAA,CAAAY,CACF,CAAC,CAAA,CACDf,EAAK,GAAA,CAAI,WAAA,CAAYC,CAAG,EAC1B,CAAC,CACH,CAGA,MAAc,WAAA,CAAYD,CAAAA,CAA+B,CACvD,GAAI,CAAEA,EAAK,GAAA,CAAI,SAAA,GAAa,CAAA,KAAQ,CAAe,CACnD,IAAMgB,CAAAA,CAAM,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQhB,CAAI,CAAA,CACnC,GAAIgB,CAAAA,GAAQ,EAAA,CAAI,OAEhB,IAAA,GAAW,EAAGC,CAAC,CAAA,GAAKjB,CAAAA,CAAK,OAAA,CACnBiB,CAAAA,CAAE,KAAA,GAAU,IAAA,EAAM,aAAaA,CAAAA,CAAE,KAAK,CAAA,CAC1CA,CAAAA,CAAE,MAAA,CAAO,IAAI,MAAM,qCAAqC,CAAC,CAAA,CAE3DjB,CAAAA,CAAK,OAAA,CAAQ,KAAA,GACb,IAAMZ,CAAAA,CAAM,MAAMN,CAAAA,EAAgB,CAC5BoC,CAAAA,CAAoB,CAAE,GAAA,CAAA9B,CAAAA,CAAK,OAAA,CAAS,IAAI,GAAM,CAAA,CACpDD,EAAmBC,CAAAA,CAAMa,CAAAA,EAAQ,IAAA,CAAK,aAAA,CAAciB,CAAAA,CAASjB,CAAG,CAAC,CAAA,CACjE,IAAA,CAAK,KAAA,CAAMe,CAAG,CAAA,CAAIE,CAAAA,CAElB,IAAMd,CAAAA,CAAK,IAAA,CAAK,MAAA,EAAA,CAChB,MAAM,IAAI,OAAA,CAAc,CAACF,CAAAA,CAASC,CAAAA,GAAW,CAC3Ce,CAAAA,CAAQ,OAAA,CAAQ,GAAA,CAAId,EAAI,CAAE,OAAA,CAAS,IAAMF,CAAAA,EAAQ,CAAG,OAAAC,CAAAA,CAAQ,KAAA,CAAO,IAAK,CAAC,CAAA,CACzEf,CAAAA,CAAI,YAAY,CACd,IAAA,CAAM,MAAA,CACN,SAAA,CAAWgB,CAAAA,CACX,KAAA,CAAO,KAAK,SAAA,CACZ,MAAA,CAAQ,IAAA,CAAK,MACf,CAAC,EACH,CAAC,EACH,CAGA,IAAI,IAAA,EAAe,CACjB,OAAO,KAAK,KAAA,CAAM,MACpB,CAGA,SAAA,EAAkB,CAChB,GAAI,MAAK,UAAA,CACT,CAAA,IAAA,CAAK,UAAA,CAAa,IAAA,CAClB,IAAA,IAAWJ,CAAAA,IAAQ,KAAK,KAAA,CAAO,CAC7B,IAAA,GAAW,EAAGiB,CAAC,IAAKjB,CAAAA,CAAK,OAAA,CACnBiB,CAAAA,CAAE,KAAA,GAAU,IAAA,EAAM,YAAA,CAAaA,EAAE,KAAK,CAAA,CAC1CA,CAAAA,CAAE,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA,CAEvCjB,CAAAA,CAAK,OAAA,CAAQ,KAAA,EAAM,CACnB,GAAI,CAAEA,CAAAA,CAAK,GAAA,CAAI,SAAA,GAAa,CAAA,KAAQ,CAAe,CACrD,CACA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAS,EAAA,CACtB,CACF,EChJA,IAAMmB,CAAAA,CACJ,OAAO,OAAA,CAAY,GAAA,EACnB,OAAO,OAAA,CAAQ,QAAA,EAAa,QAAA,EAC5B,OAAO,OAAA,CAAQ,QAAA,CAAS,MAAS,QAAA,CAMnC,SAASC,CAAAA,EAAsB,CAC7B,OAAI,OAAO,kBAAsB,GAAA,CAAoB,KAAA,CACjDD,EAAgB,IAAA,CAEb,OAAO,oBAAwB,GAAA,EAAe,mBAAA,GAAwB,IAC/E,CAOA,eAAeE,CAAAA,CACbC,EACAC,CAAAA,CACqB,CACrB,GAAIJ,CAAAA,CAAS,CACX,GAAM,CAAC,CAAE,QAAA,CAAAK,CAAS,CAAA,CAAG,CAAE,aAAA,CAAAC,CAAc,CAAC,CAAA,CAAI,MAAM,OAAA,CAAQ,GAAA,CAAI,CAC1D,OAAO,aAAkB,CAAA,CACzB,OAAO,KAAU,CACnB,CAAC,EACGC,CAAAA,CACJ,GAAIH,CAAAA,GAAY,MAAA,CACdG,CAAAA,CAAWD,CAAAA,CAAc,IAAI,GAAA,CAAIH,CAAAA,CAAU,6PAAe,CAAC,CAAA,CAAA,KAAA,GAClDC,aAAmB,GAAA,CAC5BG,CAAAA,CAAWD,CAAAA,CAAc,IAAI,GAAA,CAAIH,CAAAA,CAAUC,CAAO,CAAC,CAAA,CAAA,KAAA,GAC1CA,CAAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,CACnCG,EAAWD,CAAAA,CAAc,IAAI,GAAA,CAAIH,CAAAA,CAAUC,CAAO,CAAC,OAC9C,CACL,GAAM,CAAE,IAAA,CAAAI,CAAK,CAAA,CAAI,MAAM,OAAO,MAAW,CAAA,CACzCD,CAAAA,CAAWC,CAAAA,CAAKJ,CAAAA,CAASD,CAAQ,EACnC,CACA,IAAMlC,CAAAA,CAAM,MAAMoC,CAAAA,CAASE,CAAQ,CAAA,CAE7BE,CAAAA,CAAKxC,CAAAA,CAAI,MAAA,CAAO,KAAA,CAAMA,CAAAA,CAAI,WAAYA,CAAAA,CAAI,UAAA,CAAaA,CAAAA,CAAI,UAAU,CAAA,CAC3E,OAAO,IAAI,UAAA,CAAWwC,CAAE,CAC1B,CACA,IAAMC,EAAON,CAAAA,EAAW,IAAI,GAAA,CAAI,GAAA,CAAK,6PAAe,EAC9CtC,CAAAA,CAAM,IAAI,GAAA,CAAIqC,CAAAA,CAAUO,CAAI,CAAA,CAC5BC,EAAO,MAAM,KAAA,CAAM7C,CAAG,CAAA,CAC5B,GAAI,CAAC6C,EAAK,EAAA,CAAI,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB7C,CAAG,KAAK6C,CAAAA,CAAK,MAAM,CAAA,CAAE,CAAA,CACtE,OAAO,IAAI,WAAW,MAAMA,CAAAA,CAAK,WAAA,EAAa,CAChD,CAWO,SAASC,CAAAA,CACdC,CAAAA,CACApC,CAAAA,CACyB,CACzB,GAAIoC,CAAAA,GAAQ,GAAKpC,CAAAA,EAAc,CAAA,CAAG,OAAO,EAAC,CAE1C,IAAMR,CAAAA,CAAM,IAAA,CAAK,IAAA,CAAK4C,CAAAA,CAAMpC,CAAU,CAAA,CAChCqC,EAAK,IAAA,CAAK,IAAA,CAAK7C,CAAAA,CAAM,CAAC,CAAA,CAAI,CAAA,CAC1B8C,EAAkC,EAAC,CACzC,IAAA,IAAS,CAAA,CAAI,CAAA,CAAG,CAAA,CAAIF,EAAK,CAAA,EAAKC,CAAAA,CAC5BC,CAAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAG,KAAK,GAAA,CAAI,CAAA,CAAID,CAAAA,CAAID,CAAG,CAAC,CAAC,EAExC,OAAOE,CACT,CAgBA,IAAMC,CAAAA,CAAN,KAAiD,CAO/C,WAAA,CACmBtC,CAAAA,CACjBuC,CAAAA,CACAC,CAAAA,CACA,CAHiB,IAAA,CAAA,IAAA,CAAAxC,EAIjB,IAAA,CAAK,OAAA,CAAUuC,EAAa,OAAA,CAC5B,IAAA,CAAK,OAASC,EAChB,CANmB,IAAA,CAPV,OAAA,CAAU,IAAA,CAGV,MAAA,CACQ,QAWjB,IAAI,OAAA,EAAkB,CACpB,OAAO,IAAA,CAAK,IAAA,CAAK,IACnB,CAEA,KAAA,CAAMC,CAAAA,CAAuB,CAC3B,IAAMC,CAAAA,CAAO,KAAK,OAAA,CAAQ,KAAA,CAAgCD,CAAK,CAAA,CAC/D,GAAIC,CAAAA,GAAQ,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+BD,CAAK,CAAA,MAAA,CAAQ,EAC3E,OAAOC,CACT,CAEA,IAAA,CAAKA,CAAAA,CAAmB,CACrB,KAAK,OAAA,CAAQ,IAAA,CAA6BA,CAAG,EAChD,CAEA,UAAA,CAAWhC,KAAeC,CAAAA,CAAwB,CAChD,IAAMgC,CAAAA,CAAI,IAAA,CAAK,OAAA,CAAQjC,CAAE,CAAA,CACzB,GAAI,OAAOiC,CAAAA,EAAM,UAAA,CAAY,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqBjC,CAAE,CAAA,CAAE,CAAA,CACtE,OAAQiC,EAAiC,GAAGhC,CAAI,CAClD,CAMA,MAAM,MAAA,CAAOiC,EAAiBC,CAAAA,CAAeV,CAAAA,CAA8B,CACzE,IAAME,CAAAA,CAASH,CAAAA,CAAYC,EAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,SAAW,CAAA,CAAG,OAAO,CAAA,CAChC,GAAIA,CAAAA,CAAO,MAAA,GAAW,EAEpB,OAAO,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,cAAA,CAAgB,CAC1CO,EAASC,CAAAA,CAAOV,CAClB,CAAC,CAAA,CAEH,IAAMtB,EAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,KAAO,CACtC,EAAA,CAAI,cAAA,CACJ,IAAA,CAAM,CACJmD,CAAAA,CAAUE,EAAI,CAAA,CACdD,CAAAA,GAAU,CAAA,CAAI,CAAA,CAAIA,CAAAA,EAASC,CAAAA,EAAK,GAChCrD,CAAAA,CAAIqD,CACN,CACF,CAAA,CAAE,CAAA,CACIC,CAAAA,CAAW,MAAM,IAAA,CAAK,IAAA,CAAK,eAAA,CAAgBlC,CAAO,CAAA,CAGpDmC,CAAAA,CAAQ,EACZ,IAAA,IAAW5B,CAAAA,IAAK2B,CAAAA,CAAUC,CAAAA,EAAS5B,CAAAA,CACnC,OAAO4B,CACT,CAEA,MAAM,OAAA,CAAQJ,CAAAA,CAAiBC,CAAAA,CAAeV,CAAAA,CAA8B,CAC1E,IAAME,CAAAA,CAASH,CAAAA,CAAYC,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,WACzB,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,OAAO,IAAA,CAAK,KAAK,UAAA,CAAW,eAAA,CAAiB,CAACO,CAAAA,CAASC,CAAAA,CAAOV,CAAG,CAAC,CAAA,CAGpE,IAAMtB,CAAAA,CAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,CAAA,GAAM,CACrC,IAAMwD,CAAAA,CAAUL,EAAUE,CAAAA,CAAI,CAAA,CACxBI,CAAAA,CAAQL,CAAAA,GAAU,CAAA,CAAI,CAAA,CAAIA,GAASC,CAAAA,EAAK,CAAA,CAAA,CACxCK,CAAAA,CAAO1D,CAAAA,CAAIqD,CAAAA,CACjB,OAAO,CACL,CAAE,EAAA,CAAI,eAAiB,IAAA,CAAM,CAACG,EAASC,CAAAA,CAAOC,CAAI,CAAE,CAAA,CACpD,CAAE,EAAA,CAAI,aAAiB,IAAA,CAAM,CAACD,CAAAA,CAAcC,CAAI,CAAE,CACpD,CACF,CAAC,CAAA,CACKC,CAAAA,CAAU,MAAM,IAAA,CAAK,IAAA,CAAK,cAAcvC,CAAO,CAAA,CACjDwC,CAAAA,CAAW,CAAA,CACXC,CAAAA,CAAa,CAAA,CACjB,OAAW,CAACC,CAAAA,CAAKzC,CAAK,CAAA,GAAKsC,CAAAA,CACzBC,CAAAA,EAAYE,EACZD,CAAAA,EAAcxC,CAAAA,CAEhB,OAAOwC,CAAAA,GAAe,CAAA,CAAI,GAAA,CAAMD,EAAWC,CAC7C,CAEA,MAAM,MAAA,CAAOV,CAAAA,CAAiBC,CAAAA,CAAeV,EAA8B,CACzE,IAAME,CAAAA,CAASH,CAAAA,CAAYC,CAAAA,CAAK,IAAA,CAAK,KAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,OAAO,GAAA,CAChC,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,OAAO,KAAK,IAAA,CAAK,UAAA,CAAW,cAAA,CAAgB,CAACO,CAAAA,CAASC,CAAAA,CAAOV,CAAG,CAAC,CAAA,CAEnE,IAAMtB,CAAAA,CAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,CAAA,IAAO,CACtC,EAAA,CAAI,eACJ,IAAA,CAAM,CAACmD,CAAAA,CAAUE,CAAAA,CAAI,CAAA,CAAGD,CAAAA,GAAU,EAAI,CAAA,CAAIA,CAAAA,EAASC,CAAAA,EAAK,CAAA,CAAA,CAAIrD,CAAAA,CAAIqD,CAAC,CACnE,CAAA,CAAE,CAAA,CACIC,EAAW,MAAM,IAAA,CAAK,KAAK,eAAA,CAAgBlC,CAAO,CAAA,CACxD,OAAO2C,CAAAA,CAAcT,CAAQ,CAC/B,CAEA,MAAM,MAAA,CAAOH,CAAAA,CAAiBC,CAAAA,CAAeV,CAAAA,CAA8B,CACzE,IAAME,CAAAA,CAASH,CAAAA,CAAYC,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,WACzB,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,OAAO,IAAA,CAAK,KAAK,UAAA,CAAW,cAAA,CAAgB,CAACO,CAAAA,CAASC,CAAAA,CAAOV,CAAG,CAAC,CAAA,CAEnE,IAAMtB,CAAAA,CAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,KAAO,CACtC,EAAA,CAAI,eACJ,IAAA,CAAM,CAACmD,CAAAA,CAAUE,CAAAA,CAAI,CAAA,CAAGD,CAAAA,GAAU,EAAI,CAAA,CAAIA,CAAAA,EAASC,CAAAA,EAAK,CAAA,CAAA,CAAIrD,CAAAA,CAAIqD,CAAC,CACnE,CAAA,CAAE,CAAA,CACIC,CAAAA,CAAW,MAAM,IAAA,CAAK,IAAA,CAAK,gBAAgBlC,CAAO,CAAA,CACxD,OAAO4C,CAAAA,CAAcV,CAAQ,CAC/B,CAMA,MAAA,CAAOW,CAAAA,CAAcC,CAAAA,CAAcC,CAAAA,CAAgBzB,CAAAA,CAA4B,CAC7E,OAAO,IAAA,CAAK,yBAAA,CAA0B,SAAA,CAAWuB,CAAAA,CAAMC,CAAAA,CAAMC,CAAAA,CAAQzB,EAAK,CAAC,CAC7E,CAEA,MAAA,CAAOuB,CAAAA,CAAcC,CAAAA,CAAcC,EAAgBzB,CAAAA,CAA4B,CAC7E,OAAO,IAAA,CAAK,yBAAA,CAA0B,UAAWuB,CAAAA,CAAMC,CAAAA,CAAMC,CAAAA,CAAQzB,CAAAA,CAAK,CAAC,CAC7E,CAEA,MAAA,CAAOuB,CAAAA,CAAcC,CAAAA,CAAcC,CAAAA,CAAgBzB,CAAAA,CAA4B,CAC7E,OAAO,IAAA,CAAK,yBAAA,CAA0B,SAAA,CAAWuB,CAAAA,CAAMC,CAAAA,CAAMC,CAAAA,CAAQzB,EAAK,CAAC,CAC7E,CAEA,MAAM,yBAAA,CACJzB,CAAAA,CACAgD,EACAC,CAAAA,CACAC,CAAAA,CACAzB,CAAAA,CACA0B,CAAAA,CACe,CACf,IAAMxB,EAASH,CAAAA,CAAYC,CAAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,OACzB,GAAIA,CAAAA,CAAO,SAAW,CAAA,CAAG,CACvB,MAAM,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW3B,EAAI,CAACgD,CAAAA,CAAMC,CAAAA,CAAMC,CAAAA,CAAQzB,CAAG,CAAC,EACxD,MACF,CACA,IAAMtB,CAAAA,CAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,CAAA,GAAM,CACrC,IAAMqE,EAAMhB,CAAAA,CAAIe,CAAAA,CAChB,OAAO,CAAE,EAAA,CAAAnD,CAAAA,CAAI,KAAM,CAACgD,CAAAA,CAAOI,CAAAA,CAAKH,CAAAA,CAAOG,CAAAA,CAAKF,CAAAA,CAASE,EAAKrE,CAAAA,CAAIqD,CAAC,CAAE,CACnE,CAAC,CAAA,CAED,MAAM,IAAA,CAAK,IAAA,CAAK,eAAA,CAAgBjC,CAAO,EACzC,CAEA,MAAM,cAAA,CACJH,CAAAA,CACAkC,EACAC,CAAAA,CACAV,CAAAA,CACA0B,EACmB,CACnB,IAAMxB,CAAAA,CAASH,CAAAA,CAAYC,CAAAA,CAAK,IAAA,CAAK,KAAK,IAAI,CAAA,CAC9C,GAAIE,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,OAAO,EAAC,CACjC,IAAMxB,CAAAA,CAAUwB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACS,CAAAA,CAAGrD,CAAC,CAAA,IAAO,CACtC,EAAA,CAAAiB,EACA,IAAA,CAAM,CACJkC,CAAAA,CAAUE,CAAAA,CAAIe,CAAAA,CACdhB,CAAAA,GAAU,EAAI,CAAA,CAAIA,CAAAA,EAASC,CAAAA,EAAK,CAAA,CAAA,CAChCrD,CAAAA,CAAIqD,CACN,CACF,CAAA,CAAE,CAAA,CACF,OAAO,IAAA,CAAK,IAAA,CAAK,eAAA,CAAgBjC,CAAO,CAC1C,CAEA,SAAA,EAAkB,CAChB,IAAA,CAAK,IAAA,CAAK,YACZ,CACF,CAAA,CAUA,SAAS2C,CAAAA,CAAcT,CAAAA,CAA4B,CACjD,IAAIgB,CAAAA,CAAS,GAAA,CACb,IAAA,IAAW3C,CAAAA,IAAK2B,CAAAA,CACT,OAAO,KAAA,CAAM3B,CAAC,CAAA,GACjB2C,CAAAA,CAAS,MAAA,CAAO,KAAA,CAAMA,CAAM,CAAA,CAAI3C,CAAAA,CAAI,IAAA,CAAK,GAAA,CAAI2C,CAAAA,CAAQ3C,CAAC,GAG1D,OAAO2C,CACT,CAGA,SAASN,CAAAA,CAAcV,CAAAA,CAA4B,CACjD,IAAIgB,CAAAA,CAAS,GAAA,CACb,IAAA,IAAW3C,CAAAA,IAAK2B,CAAAA,CACT,OAAO,KAAA,CAAM3B,CAAC,CAAA,GACjB2C,CAAAA,CAAS,MAAA,CAAO,KAAA,CAAMA,CAAM,CAAA,CAAI3C,CAAAA,CAAI,KAAK,GAAA,CAAI2C,CAAAA,CAAQ3C,CAAC,CAAA,CAAA,CAG1D,OAAO2C,CACT,CAsBA,eAAsBC,CAAAA,CACpBC,EAAwB,EAAC,CACO,CAEhC,GAAI,CAAC1C,CAAAA,GACH,OAAA,OAAA,CAAQ,IAAA,CACN,sNAGF,CAAA,CACO,KAAA,CAGT,IAAMxB,EAAakE,CAAAA,CAAO,OAAA,EAAW,CAAA,CAC/BnE,CAAAA,CAAYmE,CAAAA,CAAO,SAAA,EAAa,IAGhCC,CAAAA,CAAeD,CAAAA,CAAO,YAAA,EAAgB,EAAA,CACtCE,CAAAA,CAAWF,CAAAA,CAAO,UAAY,KAAA,CAG9BpE,CAAAA,CAAY,MAAM2B,CAAAA,CAAU,mBAAA,CAAqByC,CAAAA,CAAO,OAAO,CAAA,CAG/DrE,CAAAA,CAAS,IAAI,WAAA,CAAY,MAAA,CAAO,CACpC,QAASsE,CAAAA,CACT,OAAA,CAASC,CAAAA,CACT,MAAA,CAAQ,IACV,CAAC,EAMKC,CAAAA,CAAS,MAAM,WAAA,CAAY,OAAA,CAAQvE,CAAAA,CAAU,MAAqB,EAClEwE,CAAAA,CAAW,MAAM,WAAA,CAAY,WAAA,CAAYD,CAAAA,CAAQ,CACrD,IAAK,CAAE,MAAA,CAAAxE,CAAO,CAChB,CAAC,CAAA,CACK0E,EAAUD,CAAAA,CAAS,OAAA,CASrB,OAAOC,CAAAA,CAAQ,kBAAA,EAA0B,UAAA,EAC1CA,EAAQ,kBAAA,EAAqC,CAIhD,IAAMtE,CAAAA,CAAO,MAAMN,CAAAA,CAAiB,OAAOG,CAAAA,CAAWD,CAAAA,CAAQG,CAAAA,CAAYD,CAAS,CAAA,CAEnF,OAAO,IAAIwC,CAAAA,CAAkBtC,CAAAA,CAAMqE,CAAAA,CAAUzE,CAAM,CACrD","file":"workers.cjs","sourcesContent":["/**\n * Inline kernel-worker script (ADR-006 / P5.1).\n *\n * This string is passed to `new Worker(script, { eval: true })` in Node.js or\n * wrapped in a Blob URL for browser Workers. It must be self-contained CommonJS\n * (no ESM import/export) because Node eval workers run as CJS.\n *\n * Protocol:\n * host → worker: { type: 'init', requestId, bytes: Uint8Array, memory: WebAssembly.Memory }\n * host → worker: { type: 'kernel', requestId, fn: string, args: number[] }\n * host → worker: { type: 'meta', requestId, ops: Array<{ fn: string; args: number[] }> }\n * worker → host: { type: 'ready', requestId }\n * worker → host: { type: 'result', requestId, value: number } (kernel)\n * worker → host: { type: 'values', requestId, values: number[] } (meta)\n * worker → host: { type: 'error', requestId, error: string }\n *\n * Invariant: workers NEVER call alloc/free/realloc (ADR-006). They only call\n * stateless kernel functions on caller-provided pointer ranges. All allocation\n * is done by the main thread before dispatching work.\n */\n\nexport const KERNEL_WORKER_SCRIPT: string = /* js */ `\n;(function workerMain() {\n var isNode = (\n typeof process !== 'undefined' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string'\n );\n\n /* Capture 'require' via a typeof guard so that the literal text\n * 'require(' never appears in this file — packaging tools like publint\n * use a regex heuristic (require\\\\s*\\\\() to classify CJS vs ESM, and a\n * false-positive here would misclassify the ESM workers bundle.\n * The guard is safe: in a Node.js eval worker this is always a function;\n * in a browser worker it is undefined and the isNode guard short-circuits. */\n var _workerRequire = typeof require === 'function' ? require : null;\n\n var wasm = null; /* WebAssembly exports, set on 'init' */\n\n /* ------------------------------------------------------------------ */\n /* send a message back to the main thread */\n /* ------------------------------------------------------------------ */\n function send(msg) {\n if (isNode) {\n _workerRequire('worker_threads').parentPort.postMessage(msg);\n } else {\n /* global postMessage available in browser Worker scope */\n postMessage(msg);\n }\n }\n\n /* ------------------------------------------------------------------ */\n /* message handler */\n /* ------------------------------------------------------------------ */\n function handle(msg) {\n var type = msg.type;\n var requestId = msg.requestId;\n\n /* ---- init: receive wasm bytes + shared memory, instantiate ---- */\n if (type === 'init') {\n var bytes = msg.bytes;\n /* Accept Uint8Array or ArrayBuffer */\n var src = (bytes instanceof Uint8Array) ? bytes.buffer : bytes;\n WebAssembly\n .instantiate(src, { env: { memory: msg.memory } })\n .then(function(r) {\n wasm = r.instance.exports;\n /* Workers NEVER call __wasm_init_memory — only the main thread does.\n * All our static-mut arena variables are zero-initialised (BSS),\n * so the shared linear memory already contains the correct values\n * written by the main thread's instantiation. */\n send({ type: 'ready', requestId: requestId });\n })\n .catch(function(e) {\n send({ type: 'error', requestId: requestId, error: String(e) });\n });\n return;\n }\n\n if (!wasm) {\n send({ type: 'error', requestId: requestId, error: 'worker not initialised' });\n return;\n }\n\n /* ---- kernel: single wasm kernel call, returns one number ---- */\n if (type === 'kernel') {\n try {\n var result = wasm[msg.fn].apply(null, msg.args);\n send({ type: 'result', requestId: requestId, value: +result });\n } catch(e) {\n send({ type: 'error', requestId: requestId, error: String(e) });\n }\n return;\n }\n\n /* ---- meta: batch of kernel calls, returns one number per op ---- */\n if (type === 'meta') {\n try {\n var ops = msg.ops;\n var values = new Array(ops.length);\n for (var i = 0; i < ops.length; i++) {\n values[i] = +wasm[ops[i].fn].apply(null, ops[i].args);\n }\n send({ type: 'values', requestId: requestId, values: values });\n } catch(e) {\n send({ type: 'error', requestId: requestId, error: String(e) });\n }\n return;\n }\n }\n\n /* ------------------------------------------------------------------ */\n /* wire up message listener */\n /* ------------------------------------------------------------------ */\n if (isNode) {\n _workerRequire('worker_threads').parentPort.on('message', handle);\n } else {\n /* browser Web Worker */\n self.onmessage = function(e) { handle(e.data); };\n }\n})();\n`;\n","/**\n * KernelWorkerPool — manages a fixed set of Workers initialised with the\n * simd-threads WASM binary over a shared WebAssembly.Memory (ADR-006 / P5.1).\n *\n * Invariants:\n * - Workers NEVER call alloc/free/realloc (the arena is main-thread-only).\n * - Each worker holds its own WASM instance but they ALL share the same\n * linear memory, so pointers from the main-thread arena are valid in workers.\n * - Work items are dispatched round-robin; one pending item per worker at a time.\n *\n * Crash / timeout policy:\n * - If a worker doesn't respond within `timeoutMs` (default 30 s) we replace\n * it with a fresh instance and reject the pending promise. This ensures the\n * pool never deadlocks after a worker crash.\n */\n\nimport { KERNEL_WORKER_SCRIPT } from './kernel-worker-script.js';\n\nconst isNode =\n typeof process !== 'undefined' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** An in-flight request waiting for a worker reply. */\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\ntype WorkerLike = {\n postMessage(msg: unknown): void;\n on?(event: 'message', cb: (msg: unknown) => void): void;\n onmessage?: ((e: MessageEvent) => void) | null;\n terminate(): void;\n};\n\n/* ------------------------------------------------------------------ */\n/* Worker creation */\n/* ------------------------------------------------------------------ */\n\nasync function createRawWorker(): Promise<WorkerLike> {\n if (isNode) {\n const { Worker } = await import('node:worker_threads');\n return new Worker(KERNEL_WORKER_SCRIPT, { eval: true }) as unknown as WorkerLike;\n }\n /* Browser: wrap script in a Blob URL */\n const blob = new Blob([KERNEL_WORKER_SCRIPT], { type: 'text/javascript' });\n const url = URL.createObjectURL(blob);\n const w = new Worker(url);\n URL.revokeObjectURL(url);\n return w as unknown as WorkerLike;\n}\n\nfunction wireWorkerMessages(\n raw: WorkerLike,\n onMsg: (msg: unknown) => void,\n): void {\n if (isNode && typeof raw.on === 'function') {\n raw.on('message', onMsg);\n } else {\n (raw as unknown as Worker).onmessage = (e: MessageEvent) => onMsg(e.data);\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Pool */\n/* ------------------------------------------------------------------ */\n\n/** Single slot in the worker pool. */\ninterface PoolSlot {\n raw: WorkerLike;\n pending: Map<number, Pending>;\n}\n\nexport class KernelWorkerPool {\n private readonly memory: WebAssembly.Memory;\n private readonly wasmBytes: Uint8Array;\n private readonly timeoutMs: number;\n private readonly slots: PoolSlot[] = [];\n private nextId = 1;\n private nextSlot = 0;\n private terminated = false;\n\n /** Only {@link KernelWorkerPool.create} should be used (async init). */\n private constructor(\n memory: WebAssembly.Memory,\n wasmBytes: Uint8Array,\n timeoutMs: number,\n ) {\n this.memory = memory;\n this.wasmBytes = wasmBytes;\n this.timeoutMs = timeoutMs;\n }\n\n /**\n * Create and fully initialise a pool of `numWorkers` workers.\n * Each worker receives the threads WASM binary and the shared memory.\n */\n static async create(\n wasmBytes: Uint8Array,\n memory: WebAssembly.Memory,\n numWorkers: number,\n timeoutMs = 30_000,\n ): Promise<KernelWorkerPool> {\n const pool = new KernelWorkerPool(memory, wasmBytes, timeoutMs);\n const readyPromises: Promise<void>[] = [];\n for (let i = 0; i < numWorkers; i++) {\n readyPromises.push(pool.addWorker());\n }\n await Promise.all(readyPromises);\n return pool;\n }\n\n /** Add one worker slot and wait for it to signal 'ready'. */\n private async addWorker(): Promise<void> {\n const raw = await createRawWorker();\n const pending = new Map<number, Pending>();\n const slot: PoolSlot = { raw, pending };\n this.slots.push(slot);\n\n wireWorkerMessages(raw, (msg) => this.handleMessage(slot, msg));\n\n return new Promise<void>((resolve, reject) => {\n const id = this.nextId++;\n pending.set(id, {\n resolve: () => resolve(),\n reject,\n timer: null,\n });\n raw.postMessage({\n type: 'init',\n requestId: id,\n bytes: this.wasmBytes,\n memory: this.memory,\n });\n });\n }\n\n private handleMessage(slot: PoolSlot, msg: unknown): void {\n if (typeof msg !== 'object' || msg === null) return;\n const m = msg as Record<string, unknown>;\n const id = m['requestId'] as number;\n const entry = slot.pending.get(id);\n if (!entry) return;\n slot.pending.delete(id);\n if (entry.timer !== null) clearTimeout(entry.timer);\n\n if (m['type'] === 'error') {\n entry.reject(new Error(String(m['error'])));\n } else {\n entry.resolve(msg);\n }\n }\n\n /**\n * Send a 'kernel' message to the next available worker (round-robin) and\n * return the numeric result. Times out after `this.timeoutMs`.\n */\n async sendKernel(fn: string, args: number[]): Promise<number> {\n const slot = this.slots[this.nextSlot % this.slots.length]!;\n this.nextSlot++;\n const id = this.nextId++;\n const result = await this.sendToSlot<{ value: number }>(slot, id, {\n type: 'kernel',\n requestId: id,\n fn,\n args,\n });\n return result.value;\n }\n\n /**\n * Send a 'meta' (batched) message to the next worker (round-robin) and\n * return an array of numeric results (one per op in `ops`).\n */\n async sendMeta(ops: Array<{ fn: string; args: number[] }>): Promise<number[]> {\n const slot = this.slots[this.nextSlot % this.slots.length]!;\n this.nextSlot++;\n const id = this.nextId++;\n const result = await this.sendToSlot<{ values: number[] }>(slot, id, {\n type: 'meta',\n requestId: id,\n ops,\n });\n return result.values;\n }\n\n /**\n * Dispatch work to ALL slots (one message per slot) and await all results.\n * Used for parallel chunk dispatch.\n */\n async broadcastKernel(\n perSlot: Array<{ fn: string; args: number[] }>,\n ): Promise<number[]> {\n const count = Math.min(perSlot.length, this.slots.length);\n const promises: Promise<number>[] = [];\n for (let i = 0; i < count; i++) {\n const { fn, args } = perSlot[i]!;\n const slot = this.slots[i]!;\n const id = this.nextId++;\n promises.push(\n this.sendToSlot<{ value: number }>(slot, id, {\n type: 'kernel',\n requestId: id,\n fn,\n args,\n }).then((r) => r.value),\n );\n }\n return Promise.all(promises);\n }\n\n /**\n * Dispatch meta (batched) calls to ALL slots, one message per slot.\n * Returns an array of arrays: `result[i][j]` = value j from slot i.\n */\n async broadcastMeta(\n perSlot: Array<Array<{ fn: string; args: number[] }>>,\n ): Promise<number[][]> {\n const count = Math.min(perSlot.length, this.slots.length);\n const promises: Promise<number[]>[] = [];\n for (let i = 0; i < count; i++) {\n const ops = perSlot[i]!;\n const slot = this.slots[i]!;\n const id = this.nextId++;\n promises.push(\n this.sendToSlot<{ values: number[] }>(slot, id, {\n type: 'meta',\n requestId: id,\n ops,\n }).then((r) => r.values),\n );\n }\n return Promise.all(promises);\n }\n\n private sendToSlot<T>(\n slot: PoolSlot,\n id: number,\n msg: unknown,\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | null = null;\n if (this.timeoutMs > 0) {\n timer = setTimeout(() => {\n slot.pending.delete(id);\n /* Replace crashed/hung worker */\n this.replaceSlot(slot).catch(() => {/* ignore */});\n reject(new Error(`kernel worker timed out (${this.timeoutMs} ms)`));\n }, this.timeoutMs);\n }\n slot.pending.set(id, {\n resolve: resolve as (v: unknown) => void,\n reject,\n timer,\n });\n slot.raw.postMessage(msg);\n });\n }\n\n /** Replace a crashed slot with a fresh worker. */\n private async replaceSlot(slot: PoolSlot): Promise<void> {\n try { slot.raw.terminate(); } catch { /* ignore */ }\n const idx = this.slots.indexOf(slot);\n if (idx === -1) return;\n /* Reject any remaining pending requests for this slot */\n for (const [, p] of slot.pending) {\n if (p.timer !== null) clearTimeout(p.timer);\n p.reject(new Error('worker replaced after crash/timeout'));\n }\n slot.pending.clear();\n const raw = await createRawWorker();\n const newSlot: PoolSlot = { raw, pending: new Map() };\n wireWorkerMessages(raw, (msg) => this.handleMessage(newSlot, msg));\n this.slots[idx] = newSlot;\n /* Re-initialise */\n const id = this.nextId++;\n await new Promise<void>((resolve, reject) => {\n newSlot.pending.set(id, { resolve: () => resolve(), reject, timer: null });\n raw.postMessage({\n type: 'init',\n requestId: id,\n bytes: this.wasmBytes,\n memory: this.memory,\n });\n });\n }\n\n /** Number of active worker slots. */\n get size(): number {\n return this.slots.length;\n }\n\n /** Terminate all workers. Pool must not be used after this. */\n terminate(): void {\n if (this.terminated) return;\n this.terminated = true;\n for (const slot of this.slots) {\n for (const [, p] of slot.pending) {\n if (p.timer !== null) clearTimeout(p.timer);\n p.reject(new Error('pool terminated'));\n }\n slot.pending.clear();\n try { slot.raw.terminate(); } catch { /* ignore */ }\n }\n this.slots.length = 0;\n }\n}\n","/**\n * enableThreads — opt-in shared-memory parallel mode (ADR-006 / P5.1).\n *\n * Detection:\n * - Browser: requires `crossOriginIsolated === true` (COOP+COEP headers).\n * - Node.js: `SharedArrayBuffer` is always available (no isolation needed).\n * If isolation is absent → console.warn + returns `false`.\n *\n * When enabled:\n * - Loads `simd-threads.wasm` with a SAB-backed `WebAssembly.Memory`.\n * - Calls `__wasm_init_memory()` (if exported) on the main instance to apply\n * any passive data segments. Workers instantiate the same binary with the\n * same shared memory but skip `__wasm_init_memory` — the arena statics are\n * already zero-initialised by wasm's memory-zero guarantee, so re-applying\n * the data section from workers is neither needed nor safe.\n * - Spawns a pool of `workers` (default 4) kernel workers.\n * - Provides parallel chunked dispatch for elementwise and reduction kernels.\n *\n * Allocator invariant (ADR-006):\n * Workers NEVER call alloc/free/realloc. All memory allocation is done by\n * the main thread before dispatching work. This means:\n * • Workers only read from data buffers (reductions) or write to pre-allocated\n * output buffers (elementwise).\n * • There are no data races on the arena state (HEAP_TOP / FREE_HEAD / GENERATION).\n *\n * Bit-exactness note:\n * f64 sum/mean with parallel dispatch is NOT bit-identical to single-thread.\n * Single-thread uses 2-stripe accumulation over all elements; parallel dispatch\n * computes per-chunk partial sums (also 2-striped within each chunk) and then\n * combines them left-to-right. The combination order differs, producing\n * different floating-point rounding. Integer sums are always exact (no FP).\n * This is an ADR-006-scope deviation; results are still IEEE-754 correct and\n * deterministic for a fixed worker count. See docs/threads.md for details.\n *\n * Chunk boundary alignment:\n * All chunk boundaries are multiples of 8 elements so that validity-bitmap byte\n * offsets are integer-aligned. The sub-bitmap pointer for chunk starting at\n * element `s` (a multiple of 8) is `vpPtr + s/8`, which correctly addresses\n * the first byte of that chunk's portion of the Arrow-LSB bitmap.\n */\n\nimport { KernelWorkerPool } from './pool.js';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/** Configuration for {@link enableThreads}. */\nexport interface ThreadsConfig {\n /** Number of kernel workers (default 4). */\n workers?: number;\n /**\n * Directory containing `simd-threads.wasm`.\n * Node: filesystem path. Browser: base URL.\n * Default: resolved relative to the loader module (same as scalar/simd.wasm).\n */\n wasmDir?: string | URL;\n /** Worker request timeout in ms (default 30 000). 0 = no timeout. */\n timeoutMs?: number;\n /** Initial shared memory pages (64 KiB each; default 16 = 1 MiB). */\n initialPages?: number;\n /** Maximum shared memory pages (default 16384 = 1 GiB). Must match --max-memory in build.sh. */\n maxPages?: number;\n}\n\n/** Handle returned by a successful {@link enableThreads} call. */\nexport interface ThreadsHandle {\n /** Always `true` — threads are active. */\n readonly enabled: true;\n\n /** Number of active worker slots. */\n readonly workers: number;\n\n /**\n * The SAB-backed shared WebAssembly.Memory used by all workers.\n * Column data for parallel operations must reside in this memory.\n * Use {@link alloc} to allocate buffers here.\n */\n readonly memory: WebAssembly.Memory;\n\n /**\n * Allocate `bytes` in the shared memory arena (main-thread-only).\n * Returns a 16-byte-aligned pointer, or throws on OOM.\n * Workers NEVER call alloc — only the main thread does (ADR-006 invariant).\n */\n alloc(bytes: number): number;\n\n /** Free a pointer previously returned by {@link alloc}. */\n free(ptr: number): void;\n\n /**\n * Call a kernel function synchronously on the main thread (single-thread path).\n * Useful for correctness comparison: `callKernel('sum_f64_null', ptr, 0, len)`.\n */\n callKernel(fn: string, ...args: number[]): number;\n\n /**\n * Parallel f64 sum over elements [0, len). Null lanes (vpPtr ≠ 0) are skipped.\n * Returns the sum of non-null values, or 0 if all null.\n * NOTE: result may differ from single-thread due to FP accumulation order; see\n * docs/threads.md for the formal deviation note.\n */\n sumF64(dataPtr: number, vpPtr: number, len: number): Promise<number>;\n\n /**\n * Parallel f64 mean. Returns NaN if len == 0 or all null.\n * Computed as totalSum / totalCount (exact weights via count_null per chunk).\n */\n meanF64(dataPtr: number, vpPtr: number, len: number): Promise<number>;\n\n /**\n * Parallel f64 min (NaN-aware, null-skipping).\n * Returns NaN if no valid non-NaN elements exist.\n */\n minF64(dataPtr: number, vpPtr: number, len: number): Promise<number>;\n\n /**\n * Parallel f64 max (NaN-aware, null-skipping).\n * Returns NaN if no valid non-NaN elements exist.\n */\n maxF64(dataPtr: number, vpPtr: number, len: number): Promise<number>;\n\n /**\n * Parallel elementwise add_f64 over pre-allocated buffers in shared memory.\n * Workers write directly to the shared output buffer (zero-copy).\n */\n addF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void>;\n\n /** Parallel elementwise sub_f64 (shared memory). */\n subF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void>;\n\n /** Parallel elementwise mul_f64 (shared memory). */\n mulF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void>;\n\n /**\n * Run a generic parallel elementwise binary kernel by name.\n * The kernel must have signature (i32 a, i32 b, i32 out, i32 len) -> ().\n */\n parallelElementwiseBinary(\n fn: string,\n aPtr: number,\n bPtr: number,\n outPtr: number,\n len: number,\n elemBytes: number,\n ): Promise<void>;\n\n /**\n * Run a generic parallel reduction kernel by name.\n * The kernel must have signature (i32 data, i32 vp, i32 len) -> <scalar>.\n * Returns an array of per-chunk partial results (caller combines).\n */\n parallelReduce(\n fn: string,\n dataPtr: number,\n vpPtr: number,\n len: number,\n elemBytes: number,\n ): Promise<number[]>;\n\n /** Terminate all workers. The handle must not be used after this. */\n terminate(): void;\n}\n\n/* ------------------------------------------------------------------ */\n/* Detection helpers */\n/* ------------------------------------------------------------------ */\n\nconst isNode_ =\n typeof process !== 'undefined' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string';\n\n/**\n * Returns true if SharedArrayBuffer is available and cross-origin isolation is\n * satisfied (required for browser; not required for Node.js).\n */\nfunction isIsolated(): boolean {\n if (typeof SharedArrayBuffer === 'undefined') return false;\n if (isNode_) return true; /* Node.js never needs COOP/COEP */\n /* Browser: crossOriginIsolated must be true */\n return typeof crossOriginIsolated !== 'undefined' && crossOriginIsolated === true;\n}\n\n/* ------------------------------------------------------------------ */\n/* Wasm loader for the threads variant */\n/* ------------------------------------------------------------------ */\n\n/** Load a wasm file and return a Uint8Array backed by a plain ArrayBuffer. */\nasync function loadBytes(\n fileName: string,\n wasmDir: string | URL | undefined,\n): Promise<Uint8Array> {\n if (isNode_) {\n const [{ readFile }, { fileURLToPath }] = await Promise.all([\n import('node:fs/promises'),\n import('node:url'),\n ]);\n let filePath: string;\n if (wasmDir === undefined) {\n filePath = fileURLToPath(new URL(fileName, import.meta.url));\n } else if (wasmDir instanceof URL) {\n filePath = fileURLToPath(new URL(fileName, wasmDir));\n } else if (wasmDir.startsWith('file:')) {\n filePath = fileURLToPath(new URL(fileName, wasmDir));\n } else {\n const { join } = await import('node:path');\n filePath = join(wasmDir, fileName);\n }\n const raw = await readFile(filePath);\n /* Node.js Buffer may use a pooled underlying ArrayBuffer; copy to own ArrayBuffer */\n const ab = raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength) as ArrayBuffer;\n return new Uint8Array(ab);\n }\n const base = wasmDir ?? new URL('.', import.meta.url);\n const url = new URL(fileName, base);\n const resp = await fetch(url);\n if (!resp.ok) throw new Error(`Failed to fetch ${url}: ${resp.status}`);\n return new Uint8Array(await resp.arrayBuffer());\n}\n\n/* ------------------------------------------------------------------ */\n/* Chunk splitting */\n/* ------------------------------------------------------------------ */\n\n/**\n * Split [0, len) into at most `numWorkers` chunks, each starting at a\n * multiple of 8 elements (for Arrow-LSB validity-bitmap byte alignment).\n * Returns an array of [start, end) pairs.\n */\nexport function splitChunks(\n len: number,\n numWorkers: number,\n): Array<[number, number]> {\n if (len === 0 || numWorkers <= 0) return [];\n /* Raw chunk size, then round UP to next multiple of 8 */\n const raw = Math.ceil(len / numWorkers);\n const cs = Math.ceil(raw / 8) * 8;\n const chunks: Array<[number, number]> = [];\n for (let s = 0; s < len; s += cs) {\n chunks.push([s, Math.min(s + cs, len)]);\n }\n return chunks;\n}\n\n/* ------------------------------------------------------------------ */\n/* ThreadsHandle implementation */\n/* ------------------------------------------------------------------ */\n\n/**\n * Raw wasm exports from the main thread's simd-threads.wasm instance.\n * Note: simd-threads.wasm uses --import-memory, so memory is NOT in exports.\n */\ntype ThreadsExports = {\n alloc: unknown;\n free: unknown;\n [fn: string]: unknown;\n};\n\nclass ThreadsHandleImpl implements ThreadsHandle {\n readonly enabled = true as const;\n /** The SAB-backed shared memory — stored separately because simd-threads.wasm\n * IMPORTS its memory (--import-memory), so it does NOT appear in exports. */\n readonly memory: WebAssembly.Memory;\n private readonly exports: ThreadsExports;\n\n constructor(\n private readonly pool: KernelWorkerPool,\n mainInstance: WebAssembly.Instance,\n sharedMemory: WebAssembly.Memory,\n ) {\n this.exports = mainInstance.exports as unknown as ThreadsExports;\n this.memory = sharedMemory;\n }\n\n get workers(): number {\n return this.pool.size;\n }\n\n alloc(bytes: number): number {\n const ptr = (this.exports.alloc as (b: number) => number)(bytes);\n if (ptr === 0) throw new Error(`threads wasm OOM allocating ${bytes} bytes`);\n return ptr;\n }\n\n free(ptr: number): void {\n (this.exports.free as (p: number) => void)(ptr);\n }\n\n callKernel(fn: string, ...args: number[]): number {\n const f = this.exports[fn];\n if (typeof f !== 'function') throw new Error(`kernel not found: ${fn}`);\n return (f as (...a: number[]) => number)(...args);\n }\n\n /* ---------------------------------------------------------------- */\n /* f64 reductions */\n /* ---------------------------------------------------------------- */\n\n async sumF64(dataPtr: number, vpPtr: number, len: number): Promise<number> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return 0;\n if (chunks.length === 1) {\n /* Single chunk — skip worker overhead */\n return this.pool.sendKernel('sum_f64_null', [\n dataPtr, vpPtr, len,\n ]);\n }\n const perSlot = chunks.map(([s, e]) => ({\n fn: 'sum_f64_null',\n args: [\n dataPtr + s * 8,\n vpPtr === 0 ? 0 : vpPtr + (s >> 3),\n e - s,\n ],\n }));\n const partials = await this.pool.broadcastKernel(perSlot);\n /* Combine left-to-right (deterministic for a given worker count).\n * This is NOT bit-identical to single-thread 2-stripe; see docs/threads.md. */\n let total = 0;\n for (const p of partials) total += p;\n return total;\n }\n\n async meanF64(dataPtr: number, vpPtr: number, len: number): Promise<number> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return NaN;\n if (chunks.length === 1) {\n return this.pool.sendKernel('mean_f64_null', [dataPtr, vpPtr, len]);\n }\n /* Each worker returns [partial_sum, partial_count] */\n const perSlot = chunks.map(([s, e]) => {\n const adjData = dataPtr + s * 8;\n const adjVp = vpPtr === 0 ? 0 : vpPtr + (s >> 3);\n const clen = e - s;\n return [\n { fn: 'sum_f64_null', args: [adjData, adjVp, clen] },\n { fn: 'count_null', args: [adjVp, clen] },\n ];\n });\n const results = await this.pool.broadcastMeta(perSlot);\n let totalSum = 0;\n let totalCount = 0;\n for (const [sum, count] of results) {\n totalSum += sum!;\n totalCount += count!;\n }\n return totalCount === 0 ? NaN : totalSum / totalCount;\n }\n\n async minF64(dataPtr: number, vpPtr: number, len: number): Promise<number> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return NaN;\n if (chunks.length === 1) {\n return this.pool.sendKernel('min_f64_null', [dataPtr, vpPtr, len]);\n }\n const perSlot = chunks.map(([s, e]) => ({\n fn: 'min_f64_null',\n args: [dataPtr + s * 8, vpPtr === 0 ? 0 : vpPtr + (s >> 3), e - s],\n }));\n const partials = await this.pool.broadcastKernel(perSlot);\n return combineMinF64(partials);\n }\n\n async maxF64(dataPtr: number, vpPtr: number, len: number): Promise<number> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return NaN;\n if (chunks.length === 1) {\n return this.pool.sendKernel('max_f64_null', [dataPtr, vpPtr, len]);\n }\n const perSlot = chunks.map(([s, e]) => ({\n fn: 'max_f64_null',\n args: [dataPtr + s * 8, vpPtr === 0 ? 0 : vpPtr + (s >> 3), e - s],\n }));\n const partials = await this.pool.broadcastKernel(perSlot);\n return combineMaxF64(partials);\n }\n\n /* ---------------------------------------------------------------- */\n /* elementwise binary ops */\n /* ---------------------------------------------------------------- */\n\n addF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void> {\n return this.parallelElementwiseBinary('add_f64', aPtr, bPtr, outPtr, len, 8);\n }\n\n subF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void> {\n return this.parallelElementwiseBinary('sub_f64', aPtr, bPtr, outPtr, len, 8);\n }\n\n mulF64(aPtr: number, bPtr: number, outPtr: number, len: number): Promise<void> {\n return this.parallelElementwiseBinary('mul_f64', aPtr, bPtr, outPtr, len, 8);\n }\n\n async parallelElementwiseBinary(\n fn: string,\n aPtr: number,\n bPtr: number,\n outPtr: number,\n len: number,\n elemBytes: number,\n ): Promise<void> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return;\n if (chunks.length === 1) {\n await this.pool.sendKernel(fn, [aPtr, bPtr, outPtr, len]);\n return;\n }\n const perSlot = chunks.map(([s, e]) => {\n const off = s * elemBytes;\n return { fn, args: [aPtr + off, bPtr + off, outPtr + off, e - s] };\n });\n /* Workers write directly to shared output buffer — no combination needed */\n await this.pool.broadcastKernel(perSlot);\n }\n\n async parallelReduce(\n fn: string,\n dataPtr: number,\n vpPtr: number,\n len: number,\n elemBytes: number,\n ): Promise<number[]> {\n const chunks = splitChunks(len, this.pool.size);\n if (chunks.length === 0) return [];\n const perSlot = chunks.map(([s, e]) => ({\n fn,\n args: [\n dataPtr + s * elemBytes,\n vpPtr === 0 ? 0 : vpPtr + (s >> 3),\n e - s,\n ],\n }));\n return this.pool.broadcastKernel(perSlot);\n }\n\n terminate(): void {\n this.pool.terminate();\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Combination helpers */\n/* ------------------------------------------------------------------ */\n\n/**\n * Combine partial f64 mins. Kernels return NaN for all-null/all-NaN chunks;\n * those are skipped. If all partials are NaN, returns NaN.\n */\nfunction combineMinF64(partials: number[]): number {\n let result = NaN;\n for (const p of partials) {\n if (!Number.isNaN(p)) {\n result = Number.isNaN(result) ? p : Math.min(result, p);\n }\n }\n return result;\n}\n\n/** Combine partial f64 maxes (symmetric to combineMinF64). */\nfunction combineMaxF64(partials: number[]): number {\n let result = NaN;\n for (const p of partials) {\n if (!Number.isNaN(p)) {\n result = Number.isNaN(result) ? p : Math.max(result, p);\n }\n }\n return result;\n}\n\n/* ------------------------------------------------------------------ */\n/* enableThreads */\n/* ------------------------------------------------------------------ */\n\n/**\n * Opt-in parallel mode (ADR-006).\n *\n * Returns a {@link ThreadsHandle} when threads are available and enabled,\n * or `false` (with a console.warn) when cross-origin isolation is absent.\n *\n * @example\n * ```ts\n * const th = await enableThreads({ workers: 4 });\n * if (th) {\n * const sum = await th.sumF64(ptr, vp, len);\n * // ...\n * th.terminate();\n * }\n * ```\n */\nexport async function enableThreads(\n config: ThreadsConfig = {},\n): Promise<ThreadsHandle | false> {\n /* ---- isolation detection (ADR-006) ---- */\n if (!isIsolated()) {\n console.warn(\n '[databonk] enableThreads: SharedArrayBuffer is not available or ' +\n 'cross-origin isolation is missing (COOP/COEP headers required in browsers). ' +\n 'Parallel mode not activated. See docs/threads.md for setup instructions.',\n );\n return false;\n }\n\n const numWorkers = config.workers ?? 4;\n const timeoutMs = config.timeoutMs ?? 30_000;\n /* simd-threads.wasm requires ≥17 pages (17 × 64 KiB) to cover the shadow stack\n * and BSS region laid out by wasm-ld. Default to 32 pages (2 MiB) for headroom. */\n const initialPages = config.initialPages ?? 32;\n const maxPages = config.maxPages ?? 16_384; /* 1 GiB (matches --max-memory in build.sh) */\n\n /* ---- load the threads wasm binary ---- */\n const wasmBytes = await loadBytes('simd-threads.wasm', config.wasmDir);\n\n /* ---- create shared memory ---- */\n const memory = new WebAssembly.Memory({\n initial: initialPages,\n maximum: maxPages,\n shared: true,\n });\n\n /* ---- instantiate main thread's wasm instance ---- */\n /* Use compile + instantiate(Module, imports) to avoid TypeScript overload\n * ambiguity (instantiate(BufferSource) vs instantiate(Module)). wasmBytes\n * is backed by a plain ArrayBuffer (guaranteed by loadBytes above). */\n const module = await WebAssembly.compile(wasmBytes.buffer as ArrayBuffer);\n const instance = await WebAssembly.instantiate(module, {\n env: { memory },\n });\n const exports = instance.exports as Record<string, unknown>;\n\n /* ---- apply passive data segments (if any) ---- */\n /* wasm-ld with --shared-memory may generate __wasm_init_memory to apply\n * passive data segments exactly once. Our static-mut arena vars are all\n * zero-initialised (BSS) so there are typically no data segments to apply;\n * calling the function is a safe no-op in that case.\n * Workers intentionally skip this call — they see whatever the main thread\n * wrote, which is the correct initial state (all zeros). */\n if (typeof exports['__wasm_init_memory'] === 'function') {\n (exports['__wasm_init_memory'] as () => void)();\n }\n\n /* ---- build worker pool (workers share the same memory) ---- */\n const pool = await KernelWorkerPool.create(wasmBytes, memory, numWorkers, timeoutMs);\n\n return new ThreadsHandleImpl(pool, instance, memory);\n}\n"]}
@@ -0,0 +1,74 @@
1
+ export { T as ThreadsConfig, a as ThreadsHandle, e as enableThreads, s as splitChunks } from './parallel-fv5h4BkA.cjs';
2
+
3
+ /**
4
+ * KernelWorkerPool — manages a fixed set of Workers initialised with the
5
+ * simd-threads WASM binary over a shared WebAssembly.Memory (ADR-006 / P5.1).
6
+ *
7
+ * Invariants:
8
+ * - Workers NEVER call alloc/free/realloc (the arena is main-thread-only).
9
+ * - Each worker holds its own WASM instance but they ALL share the same
10
+ * linear memory, so pointers from the main-thread arena are valid in workers.
11
+ * - Work items are dispatched round-robin; one pending item per worker at a time.
12
+ *
13
+ * Crash / timeout policy:
14
+ * - If a worker doesn't respond within `timeoutMs` (default 30 s) we replace
15
+ * it with a fresh instance and reject the pending promise. This ensures the
16
+ * pool never deadlocks after a worker crash.
17
+ */
18
+ declare class KernelWorkerPool {
19
+ private readonly memory;
20
+ private readonly wasmBytes;
21
+ private readonly timeoutMs;
22
+ private readonly slots;
23
+ private nextId;
24
+ private nextSlot;
25
+ private terminated;
26
+ /** Only {@link KernelWorkerPool.create} should be used (async init). */
27
+ private constructor();
28
+ /**
29
+ * Create and fully initialise a pool of `numWorkers` workers.
30
+ * Each worker receives the threads WASM binary and the shared memory.
31
+ */
32
+ static create(wasmBytes: Uint8Array, memory: WebAssembly.Memory, numWorkers: number, timeoutMs?: number): Promise<KernelWorkerPool>;
33
+ /** Add one worker slot and wait for it to signal 'ready'. */
34
+ private addWorker;
35
+ private handleMessage;
36
+ /**
37
+ * Send a 'kernel' message to the next available worker (round-robin) and
38
+ * return the numeric result. Times out after `this.timeoutMs`.
39
+ */
40
+ sendKernel(fn: string, args: number[]): Promise<number>;
41
+ /**
42
+ * Send a 'meta' (batched) message to the next worker (round-robin) and
43
+ * return an array of numeric results (one per op in `ops`).
44
+ */
45
+ sendMeta(ops: Array<{
46
+ fn: string;
47
+ args: number[];
48
+ }>): Promise<number[]>;
49
+ /**
50
+ * Dispatch work to ALL slots (one message per slot) and await all results.
51
+ * Used for parallel chunk dispatch.
52
+ */
53
+ broadcastKernel(perSlot: Array<{
54
+ fn: string;
55
+ args: number[];
56
+ }>): Promise<number[]>;
57
+ /**
58
+ * Dispatch meta (batched) calls to ALL slots, one message per slot.
59
+ * Returns an array of arrays: `result[i][j]` = value j from slot i.
60
+ */
61
+ broadcastMeta(perSlot: Array<Array<{
62
+ fn: string;
63
+ args: number[];
64
+ }>>): Promise<number[][]>;
65
+ private sendToSlot;
66
+ /** Replace a crashed slot with a fresh worker. */
67
+ private replaceSlot;
68
+ /** Number of active worker slots. */
69
+ get size(): number;
70
+ /** Terminate all workers. Pool must not be used after this. */
71
+ terminate(): void;
72
+ }
73
+
74
+ export { KernelWorkerPool };
@@ -0,0 +1,74 @@
1
+ export { T as ThreadsConfig, a as ThreadsHandle, e as enableThreads, s as splitChunks } from './parallel-fv5h4BkA.js';
2
+
3
+ /**
4
+ * KernelWorkerPool — manages a fixed set of Workers initialised with the
5
+ * simd-threads WASM binary over a shared WebAssembly.Memory (ADR-006 / P5.1).
6
+ *
7
+ * Invariants:
8
+ * - Workers NEVER call alloc/free/realloc (the arena is main-thread-only).
9
+ * - Each worker holds its own WASM instance but they ALL share the same
10
+ * linear memory, so pointers from the main-thread arena are valid in workers.
11
+ * - Work items are dispatched round-robin; one pending item per worker at a time.
12
+ *
13
+ * Crash / timeout policy:
14
+ * - If a worker doesn't respond within `timeoutMs` (default 30 s) we replace
15
+ * it with a fresh instance and reject the pending promise. This ensures the
16
+ * pool never deadlocks after a worker crash.
17
+ */
18
+ declare class KernelWorkerPool {
19
+ private readonly memory;
20
+ private readonly wasmBytes;
21
+ private readonly timeoutMs;
22
+ private readonly slots;
23
+ private nextId;
24
+ private nextSlot;
25
+ private terminated;
26
+ /** Only {@link KernelWorkerPool.create} should be used (async init). */
27
+ private constructor();
28
+ /**
29
+ * Create and fully initialise a pool of `numWorkers` workers.
30
+ * Each worker receives the threads WASM binary and the shared memory.
31
+ */
32
+ static create(wasmBytes: Uint8Array, memory: WebAssembly.Memory, numWorkers: number, timeoutMs?: number): Promise<KernelWorkerPool>;
33
+ /** Add one worker slot and wait for it to signal 'ready'. */
34
+ private addWorker;
35
+ private handleMessage;
36
+ /**
37
+ * Send a 'kernel' message to the next available worker (round-robin) and
38
+ * return the numeric result. Times out after `this.timeoutMs`.
39
+ */
40
+ sendKernel(fn: string, args: number[]): Promise<number>;
41
+ /**
42
+ * Send a 'meta' (batched) message to the next worker (round-robin) and
43
+ * return an array of numeric results (one per op in `ops`).
44
+ */
45
+ sendMeta(ops: Array<{
46
+ fn: string;
47
+ args: number[];
48
+ }>): Promise<number[]>;
49
+ /**
50
+ * Dispatch work to ALL slots (one message per slot) and await all results.
51
+ * Used for parallel chunk dispatch.
52
+ */
53
+ broadcastKernel(perSlot: Array<{
54
+ fn: string;
55
+ args: number[];
56
+ }>): Promise<number[]>;
57
+ /**
58
+ * Dispatch meta (batched) calls to ALL slots, one message per slot.
59
+ * Returns an array of arrays: `result[i][j]` = value j from slot i.
60
+ */
61
+ broadcastMeta(perSlot: Array<Array<{
62
+ fn: string;
63
+ args: number[];
64
+ }>>): Promise<number[][]>;
65
+ private sendToSlot;
66
+ /** Replace a crashed slot with a fresh worker. */
67
+ private replaceSlot;
68
+ /** Number of active worker slots. */
69
+ get size(): number;
70
+ /** Terminate all workers. Pool must not be used after this. */
71
+ terminate(): void;
72
+ }
73
+
74
+ export { KernelWorkerPool };
@@ -0,0 +1,102 @@
1
+ var p=`
2
+ ;(function workerMain() {
3
+ var isNode = (
4
+ typeof process !== 'undefined' &&
5
+ typeof process.versions === 'object' &&
6
+ typeof process.versions.node === 'string'
7
+ );
8
+
9
+ /* Capture 'require' via a typeof guard so that the literal text
10
+ * 'require(' never appears in this file \u2014 packaging tools like publint
11
+ * use a regex heuristic (require\\s*\\() to classify CJS vs ESM, and a
12
+ * false-positive here would misclassify the ESM workers bundle.
13
+ * The guard is safe: in a Node.js eval worker this is always a function;
14
+ * in a browser worker it is undefined and the isNode guard short-circuits. */
15
+ var _workerRequire = typeof require === 'function' ? require : null;
16
+
17
+ var wasm = null; /* WebAssembly exports, set on 'init' */
18
+
19
+ /* ------------------------------------------------------------------ */
20
+ /* send a message back to the main thread */
21
+ /* ------------------------------------------------------------------ */
22
+ function send(msg) {
23
+ if (isNode) {
24
+ _workerRequire('worker_threads').parentPort.postMessage(msg);
25
+ } else {
26
+ /* global postMessage available in browser Worker scope */
27
+ postMessage(msg);
28
+ }
29
+ }
30
+
31
+ /* ------------------------------------------------------------------ */
32
+ /* message handler */
33
+ /* ------------------------------------------------------------------ */
34
+ function handle(msg) {
35
+ var type = msg.type;
36
+ var requestId = msg.requestId;
37
+
38
+ /* ---- init: receive wasm bytes + shared memory, instantiate ---- */
39
+ if (type === 'init') {
40
+ var bytes = msg.bytes;
41
+ /* Accept Uint8Array or ArrayBuffer */
42
+ var src = (bytes instanceof Uint8Array) ? bytes.buffer : bytes;
43
+ WebAssembly
44
+ .instantiate(src, { env: { memory: msg.memory } })
45
+ .then(function(r) {
46
+ wasm = r.instance.exports;
47
+ /* Workers NEVER call __wasm_init_memory \u2014 only the main thread does.
48
+ * All our static-mut arena variables are zero-initialised (BSS),
49
+ * so the shared linear memory already contains the correct values
50
+ * written by the main thread's instantiation. */
51
+ send({ type: 'ready', requestId: requestId });
52
+ })
53
+ .catch(function(e) {
54
+ send({ type: 'error', requestId: requestId, error: String(e) });
55
+ });
56
+ return;
57
+ }
58
+
59
+ if (!wasm) {
60
+ send({ type: 'error', requestId: requestId, error: 'worker not initialised' });
61
+ return;
62
+ }
63
+
64
+ /* ---- kernel: single wasm kernel call, returns one number ---- */
65
+ if (type === 'kernel') {
66
+ try {
67
+ var result = wasm[msg.fn].apply(null, msg.args);
68
+ send({ type: 'result', requestId: requestId, value: +result });
69
+ } catch(e) {
70
+ send({ type: 'error', requestId: requestId, error: String(e) });
71
+ }
72
+ return;
73
+ }
74
+
75
+ /* ---- meta: batch of kernel calls, returns one number per op ---- */
76
+ if (type === 'meta') {
77
+ try {
78
+ var ops = msg.ops;
79
+ var values = new Array(ops.length);
80
+ for (var i = 0; i < ops.length; i++) {
81
+ values[i] = +wasm[ops[i].fn].apply(null, ops[i].args);
82
+ }
83
+ send({ type: 'values', requestId: requestId, values: values });
84
+ } catch(e) {
85
+ send({ type: 'error', requestId: requestId, error: String(e) });
86
+ }
87
+ return;
88
+ }
89
+ }
90
+
91
+ /* ------------------------------------------------------------------ */
92
+ /* wire up message listener */
93
+ /* ------------------------------------------------------------------ */
94
+ if (isNode) {
95
+ _workerRequire('worker_threads').parentPort.on('message', handle);
96
+ } else {
97
+ /* browser Web Worker */
98
+ self.onmessage = function(e) { handle(e.data); };
99
+ }
100
+ })();
101
+ `;var v=typeof process<"u"&&typeof process.versions=="object"&&typeof process.versions.node=="string";async function g(){if(v){let{Worker:t}=await import('worker_threads');return new t(p,{eval:true})}let u=new Blob([p],{type:"text/javascript"}),e=URL.createObjectURL(u),r=new Worker(e);return URL.revokeObjectURL(e),r}function w(u,e){v&&typeof u.on=="function"?u.on("message",e):u.onmessage=r=>e(r.data);}var b=class u{memory;wasmBytes;timeoutMs;slots=[];nextId=1;nextSlot=0;terminated=false;constructor(e,r,t){this.memory=e,this.wasmBytes=r,this.timeoutMs=t;}static async create(e,r,t,n=3e4){let s=new u(r,e,n),o=[];for(let i=0;i<t;i++)o.push(s.addWorker());return await Promise.all(o),s}async addWorker(){let e=await g(),r=new Map,t={raw:e,pending:r};return this.slots.push(t),w(e,n=>this.handleMessage(t,n)),new Promise((n,s)=>{let o=this.nextId++;r.set(o,{resolve:()=>n(),reject:s,timer:null}),e.postMessage({type:"init",requestId:o,bytes:this.wasmBytes,memory:this.memory});})}handleMessage(e,r){if(typeof r!="object"||r===null)return;let t=r,n=t.requestId,s=e.pending.get(n);s&&(e.pending.delete(n),s.timer!==null&&clearTimeout(s.timer),t.type==="error"?s.reject(new Error(String(t.error))):s.resolve(r));}async sendKernel(e,r){let t=this.slots[this.nextSlot%this.slots.length];this.nextSlot++;let n=this.nextId++;return (await this.sendToSlot(t,n,{type:"kernel",requestId:n,fn:e,args:r})).value}async sendMeta(e){let r=this.slots[this.nextSlot%this.slots.length];this.nextSlot++;let t=this.nextId++;return (await this.sendToSlot(r,t,{type:"meta",requestId:t,ops:e})).values}async broadcastKernel(e){let r=Math.min(e.length,this.slots.length),t=[];for(let n=0;n<r;n++){let{fn:s,args:o}=e[n],i=this.slots[n],a=this.nextId++;t.push(this.sendToSlot(i,a,{type:"kernel",requestId:a,fn:s,args:o}).then(l=>l.value));}return Promise.all(t)}async broadcastMeta(e){let r=Math.min(e.length,this.slots.length),t=[];for(let n=0;n<r;n++){let s=e[n],o=this.slots[n],i=this.nextId++;t.push(this.sendToSlot(o,i,{type:"meta",requestId:i,ops:s}).then(a=>a.values));}return Promise.all(t)}sendToSlot(e,r,t){return new Promise((n,s)=>{let o=null;this.timeoutMs>0&&(o=setTimeout(()=>{e.pending.delete(r),this.replaceSlot(e).catch(()=>{}),s(new Error(`kernel worker timed out (${this.timeoutMs} ms)`));},this.timeoutMs)),e.pending.set(r,{resolve:n,reject:s,timer:o}),e.raw.postMessage(t);})}async replaceSlot(e){try{e.raw.terminate();}catch{}let r=this.slots.indexOf(e);if(r===-1)return;for(let[,o]of e.pending)o.timer!==null&&clearTimeout(o.timer),o.reject(new Error("worker replaced after crash/timeout"));e.pending.clear();let t=await g(),n={raw:t,pending:new Map};w(t,o=>this.handleMessage(n,o)),this.slots[r]=n;let s=this.nextId++;await new Promise((o,i)=>{n.pending.set(s,{resolve:()=>o(),reject:i,timer:null}),t.postMessage({type:"init",requestId:s,bytes:this.wasmBytes,memory:this.memory});});}get size(){return this.slots.length}terminate(){if(!this.terminated){this.terminated=true;for(let e of this.slots){for(let[,r]of e.pending)r.timer!==null&&clearTimeout(r.timer),r.reject(new Error("pool terminated"));e.pending.clear();try{e.raw.terminate();}catch{}}this.slots.length=0;}}};var k=typeof process<"u"&&typeof process.versions=="object"&&typeof process.versions.node=="string";function P(){return typeof SharedArrayBuffer>"u"?false:k?true:typeof crossOriginIsolated<"u"&&crossOriginIsolated===true}async function x(u,e){if(k){let[{readFile:s},{fileURLToPath:o}]=await Promise.all([import('fs/promises'),import('url')]),i;if(e===void 0)i=o(new URL(u,import.meta.url));else if(e instanceof URL)i=o(new URL(u,e));else if(e.startsWith("file:"))i=o(new URL(u,e));else {let{join:m}=await import('path');i=m(e,u);}let a=await s(i),l=a.buffer.slice(a.byteOffset,a.byteOffset+a.byteLength);return new Uint8Array(l)}let r=e??new URL(".",import.meta.url),t=new URL(u,r),n=await fetch(t);if(!n.ok)throw new Error(`Failed to fetch ${t}: ${n.status}`);return new Uint8Array(await n.arrayBuffer())}function c(u,e){if(u===0||e<=0)return [];let r=Math.ceil(u/e),t=Math.ceil(r/8)*8,n=[];for(let s=0;s<u;s+=t)n.push([s,Math.min(s+t,u)]);return n}var f=class{constructor(e,r,t){this.pool=e;this.exports=r.exports,this.memory=t;}pool;enabled=true;memory;exports;get workers(){return this.pool.size}alloc(e){let r=this.exports.alloc(e);if(r===0)throw new Error(`threads wasm OOM allocating ${e} bytes`);return r}free(e){this.exports.free(e);}callKernel(e,...r){let t=this.exports[e];if(typeof t!="function")throw new Error(`kernel not found: ${e}`);return t(...r)}async sumF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return 0;if(n.length===1)return this.pool.sendKernel("sum_f64_null",[e,r,t]);let s=n.map(([a,l])=>({fn:"sum_f64_null",args:[e+a*8,r===0?0:r+(a>>3),l-a]})),o=await this.pool.broadcastKernel(s),i=0;for(let a of o)i+=a;return i}async meanF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("mean_f64_null",[e,r,t]);let s=n.map(([l,m])=>{let d=e+l*8,h=r===0?0:r+(l>>3),y=m-l;return [{fn:"sum_f64_null",args:[d,h,y]},{fn:"count_null",args:[h,y]}]}),o=await this.pool.broadcastMeta(s),i=0,a=0;for(let[l,m]of o)i+=l,a+=m;return a===0?NaN:i/a}async minF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("min_f64_null",[e,r,t]);let s=n.map(([i,a])=>({fn:"min_f64_null",args:[e+i*8,r===0?0:r+(i>>3),a-i]})),o=await this.pool.broadcastKernel(s);return M(o)}async maxF64(e,r,t){let n=c(t,this.pool.size);if(n.length===0)return NaN;if(n.length===1)return this.pool.sendKernel("max_f64_null",[e,r,t]);let s=n.map(([i,a])=>({fn:"max_f64_null",args:[e+i*8,r===0?0:r+(i>>3),a-i]})),o=await this.pool.broadcastKernel(s);return _(o)}addF64(e,r,t,n){return this.parallelElementwiseBinary("add_f64",e,r,t,n,8)}subF64(e,r,t,n){return this.parallelElementwiseBinary("sub_f64",e,r,t,n,8)}mulF64(e,r,t,n){return this.parallelElementwiseBinary("mul_f64",e,r,t,n,8)}async parallelElementwiseBinary(e,r,t,n,s,o){let i=c(s,this.pool.size);if(i.length===0)return;if(i.length===1){await this.pool.sendKernel(e,[r,t,n,s]);return}let a=i.map(([l,m])=>{let d=l*o;return {fn:e,args:[r+d,t+d,n+d,m-l]}});await this.pool.broadcastKernel(a);}async parallelReduce(e,r,t,n,s){let o=c(n,this.pool.size);if(o.length===0)return [];let i=o.map(([a,l])=>({fn:e,args:[r+a*s,t===0?0:t+(a>>3),l-a]}));return this.pool.broadcastKernel(i)}terminate(){this.pool.terminate();}};function M(u){let e=NaN;for(let r of u)Number.isNaN(r)||(e=Number.isNaN(e)?r:Math.min(e,r));return e}function _(u){let e=NaN;for(let r of u)Number.isNaN(r)||(e=Number.isNaN(e)?r:Math.max(e,r));return e}async function S(u={}){if(!P())return console.warn("[databonk] enableThreads: SharedArrayBuffer is not available or cross-origin isolation is missing (COOP/COEP headers required in browsers). Parallel mode not activated. See docs/threads.md for setup instructions."),false;let e=u.workers??4,r=u.timeoutMs??3e4,t=u.initialPages??32,n=u.maxPages??16384,s=await x("simd-threads.wasm",u.wasmDir),o=new WebAssembly.Memory({initial:t,maximum:n,shared:true}),i=await WebAssembly.compile(s.buffer),a=await WebAssembly.instantiate(i,{env:{memory:o}}),l=a.exports;typeof l.__wasm_init_memory=="function"&&l.__wasm_init_memory();let m=await b.create(s,o,e,r);return new f(m,a,o)}export{b as KernelWorkerPool,S as enableThreads,c as splitChunks};//# sourceMappingURL=workers.js.map
102
+ //# sourceMappingURL=workers.js.map