@electric-sql/pglite
Advanced tools
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import{j as g}from"./chunk-QY3QWFKW.js";g();var u=Object.defineProperty,f=(t,e)=>{for(var a in e)u(t,a,{get:e[a],enumerable:!0})},d={};f(d,{IN_NODE:()=>s,getFsBundle:()=>p,instantiateWasm:()=>m,startArtifactDownload:()=>c,toPostgresName:()=>y,uuid:()=>b});var s=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",r=new Map;async function c(t){s||r.has(t.toString())||r.set(t.toString(),fetch(t))}var o=new Map;async function m(t,e,a){if(a||o.has(e.toString())){let n=a||o.get(e.toString());return{instance:await WebAssembly.instantiate(n,t),module:n}}if(s){let n=await(await import("fs/promises")).readFile(e),{module:i,instance:l}=await WebAssembly.instantiate(n,t);return o.set(e.toString(),i),{instance:l,module:i}}else{r.has(e.toString())||c(e);let n=await r.get(e.toString()),{module:i,instance:l}=await WebAssembly.instantiateStreaming(n.clone(),t);return o.set(e.toString(),i),{instance:l,module:i}}}async function p(t){return s?(await(await import("fs/promises")).readFile(t)).buffer:(c(t),(await r.get(t.toString())).clone().arrayBuffer())}var b=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let t=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(t);else for(let a=0;a<t.length;a++)t[a]=Math.floor(Math.random()*256);t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=[];return t.forEach(a=>{e.push(a.toString(16).padStart(2,"0"))}),e.slice(0,4).join("")+"-"+e.slice(4,6).join("")+"-"+e.slice(6,8).join("")+"-"+e.slice(8,10).join("")+"-"+e.slice(10).join("")};function y(t){let e;return t.startsWith('"')&&t.endsWith('"')?e=t.substring(1,t.length-1):e=t.toLowerCase(),e}export{d as a}; | ||
| //# sourceMappingURL=chunk-XP4OYHYJ.js.map |
| {"version":3,"sources":["../../pglite-utils/src/utils.ts"],"sourcesContent":["export const IN_NODE =\n typeof process === 'object' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string'\n\nconst artifactDownloadPromises = new Map<string, Promise<Response>>()\n\nexport async function startArtifactDownload(url: URL) {\n if (IN_NODE || artifactDownloadPromises.has(url.toString())) {\n return\n }\n artifactDownloadPromises.set(url.toString(), fetch(url))\n}\n\n// This is a global cache of the Wasm modules to avoid having to re-download or\n// compile them on subsequent calls.\nconst cachedWasmModules = new Map<string, WebAssembly.Module>()\n\nexport async function instantiateWasm(\n imports: WebAssembly.Imports,\n moduleUrl: URL,\n module?: WebAssembly.Module,\n): Promise<{\n instance: WebAssembly.Instance\n module: WebAssembly.Module\n}> {\n if (module || cachedWasmModules.has(moduleUrl.toString())) {\n const mod = module || cachedWasmModules.get(moduleUrl.toString())!\n return {\n instance: await WebAssembly.instantiate(mod, imports),\n module: mod,\n }\n }\n if (IN_NODE) {\n const fs = await import('fs/promises')\n const buffer = await fs.readFile(moduleUrl)\n const { module: newModule, instance } = await WebAssembly.instantiate(\n buffer,\n imports,\n )\n cachedWasmModules.set(moduleUrl.toString(), newModule)\n return {\n instance,\n module: newModule,\n }\n } else {\n if (!artifactDownloadPromises.has(moduleUrl.toString())) {\n startArtifactDownload(moduleUrl)\n // wasmDownloadPromises.set(moduleUrl, fetch(moduleUrl))\n }\n const response = await artifactDownloadPromises.get(moduleUrl.toString())\n const { module: newModule, instance } =\n await WebAssembly.instantiateStreaming(response!.clone(), imports)\n cachedWasmModules.set(moduleUrl.toString(), newModule)\n return {\n instance,\n module: newModule,\n }\n }\n}\n\nexport async function getFsBundle(fsBundleUrl: URL): Promise<ArrayBuffer> {\n if (IN_NODE) {\n const fs = await import('fs/promises')\n const fileData = await fs.readFile(fsBundleUrl)\n return fileData.buffer\n } else {\n startArtifactDownload(fsBundleUrl)\n const response = await artifactDownloadPromises.get(fsBundleUrl.toString())\n return response!.clone().arrayBuffer()\n }\n}\n\nexport const uuid = (): string => {\n // best case, `crypto.randomUUID` is available\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID()\n }\n\n const bytes = new Uint8Array(16)\n\n if (globalThis.crypto?.getRandomValues) {\n // `crypto.getRandomValues` is available even in non-secure contexts\n globalThis.crypto.getRandomValues(bytes)\n } else {\n // fallback to Math.random, if the Crypto API is completely missing\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n }\n\n bytes[6] = (bytes[6] & 0x0f) | 0x40 // Set the 4 most significant bits to 0100\n bytes[8] = (bytes[8] & 0x3f) | 0x80 // Set the 2 most significant bits to 10\n\n const hexValues: string[] = []\n bytes.forEach((byte) => {\n hexValues.push(byte.toString(16).padStart(2, '0'))\n })\n\n return (\n hexValues.slice(0, 4).join('') +\n '-' +\n hexValues.slice(4, 6).join('') +\n '-' +\n hexValues.slice(6, 8).join('') +\n '-' +\n hexValues.slice(8, 10).join('') +\n '-' +\n hexValues.slice(10).join('')\n )\n}\n\n/**\n * Postgresql handles quoted names as CaseSensitive and unquoted as lower case.\n * If input is quoted, returns an unquoted string (same casing)\n * If input is unquoted, returns a lower-case string\n */\nexport function toPostgresName(input: string): string {\n let output\n if (input.startsWith('\"') && input.endsWith('\"')) {\n // Postgres sensitive case\n output = input.substring(1, input.length - 1)\n } else {\n // Postgres case insensitive - all to lower\n output = input.toLowerCase()\n }\n return output\n}\n"],"mappings":"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","names":["utils_exports","__export","IN_NODE","getFsBundle","instantiateWasm","startArtifactDownload","toPostgresName","uuid","artifactDownloadPromises","url","cachedWasmModules","imports","moduleUrl","module","mod","buffer","newModule","instance","response","fsBundleUrl","bytes","i","hexValues","byte","input","output"]} |
+1
-1
@@ -1,2 +0,2 @@ | ||
| import{f as a,g as b,h as c,i as d}from"../chunk-2X2C5D2I.js";import"../chunk-3KNDAXZT.js";import"../chunk-QY3QWFKW.js";export{c as BaseFilesystem,d as ERRNO_CODES,b as EmscriptenBuiltinFilesystem,a as WASM_PREFIX}; | ||
| import{f as a,g as b,h as c,i as d}from"../chunk-4QMGOB4T.js";import"../chunk-XP4OYHYJ.js";import"../chunk-QY3QWFKW.js";export{c as BaseFilesystem,d as ERRNO_CODES,b as EmscriptenBuiltinFilesystem,a as WASM_PREFIX}; | ||
| //# sourceMappingURL=base.js.map |
@@ -1,2 +0,2 @@ | ||
| import{d as i,g as p}from"../chunk-2X2C5D2I.js";import"../chunk-3KNDAXZT.js";import{j as n}from"../chunk-QY3QWFKW.js";n();import*as s from"fs";import*as o from"path";var m=class extends p{constructor(t){super(t),this.rootDir=o.resolve(t),s.existsSync(o.join(this.rootDir))||s.mkdirSync(this.rootDir)}async init(t,e){return this.pg=t,{emscriptenOpts:{...e,preRun:[...e.preRun||[],r=>{let c=r.FS.filesystems.NODEFS;r.FS.mkdir(i),r.FS.mount(c,{root:this.rootDir},i)}]}}}async closeFs(){this.pg.Module.FS.quit()}};export{m as NodeFS}; | ||
| import{d as i,g as p}from"../chunk-4QMGOB4T.js";import"../chunk-XP4OYHYJ.js";import{j as n}from"../chunk-QY3QWFKW.js";n();import*as s from"fs";import*as o from"path";var m=class extends p{constructor(t){super(t),this.rootDir=o.resolve(t),s.existsSync(o.join(this.rootDir))||s.mkdirSync(this.rootDir)}async init(t,e){return this.pg=t,{emscriptenOpts:{...e,preRun:[...e.preRun||[],r=>{let c=r.FS.filesystems.NODEFS;r.FS.mkdir(i),r.FS.mount(c,{root:this.rootDir},i)}]}}}async closeFs(){this.pg.Module.FS.quit()}};export{m as NodeFS}; | ||
| //# sourceMappingURL=nodefs.js.map |
@@ -1,4 +0,4 @@ | ||
| import{h as B,i as z}from"../chunk-2X2C5D2I.js";import"../chunk-3KNDAXZT.js";import{e as s,f as g,g as E,h as r,i as _,j as R}from"../chunk-QY3QWFKW.js";R();var $="state.txt",G="data",T={DIR:16384,FILE:32768},H,v,F,M,y,b,m,x,P,D,S,n,C,O,k,w,f,I,W,j,L=class extends B{constructor(e,{initialPoolSize:t=1e3,maintainedPoolSize:o=100,debug:i=!1}={}){super(e,{debug:i});g(this,n);g(this,H);g(this,v);g(this,F);g(this,M);g(this,y);g(this,b,new Map);g(this,m,new Map);g(this,x,0);g(this,P,new Map);g(this,D,new Map);this.lastCheckpoint=0;this.checkpointInterval=1e3*60;this.poolCounter=0;g(this,S,new Set);this.initialPoolSize=t,this.maintainedPoolSize=o}async init(e,t){return await r(this,n,C).call(this),super.init(e,t)}async syncToFs(e=!1){await this.maybeCheckpointState(),await this.maintainPool(),e||this.flush()}async closeFs(){for(let e of s(this,m).values())e.close();s(this,y).flush(),s(this,y).close(),this.pg.Module.FS.quit()}async maintainPool(e){e=e||this.maintainedPoolSize;let t=e-this.state.pool.length,o=[];for(let i=0;i<t;i++)o.push(new Promise(async c=>{++this.poolCounter;let a=`${(Date.now()-1704063600).toString(16).padStart(8,"0")}-${this.poolCounter.toString(16).padStart(8,"0")}`,h=await s(this,F).getFileHandle(a,{create:!0}),d=await h.createSyncAccessHandle();s(this,b).set(a,h),s(this,m).set(a,d),r(this,n,k).call(this,{opp:"createPoolFile",args:[a]}),this.state.pool.push(a),c()}));for(let i=0;i>t;i--)o.push(new Promise(async c=>{let a=this.state.pool.pop();r(this,n,k).call(this,{opp:"deletePoolFile",args:[a]});let h=s(this,b).get(a);s(this,m).get(a)?.close(),await s(this,F).removeEntry(h.name),s(this,b).delete(a),s(this,m).delete(a),c()}));await Promise.all(o)}_createPoolFileState(e){this.state.pool.push(e)}_deletePoolFileState(e){let t=this.state.pool.indexOf(e);t>-1&&this.state.pool.splice(t,1)}async maybeCheckpointState(){Date.now()-this.lastCheckpoint>this.checkpointInterval&&await this.checkpointState()}async checkpointState(){let e=new TextEncoder().encode(JSON.stringify(this.state));s(this,y).truncate(0),s(this,y).write(e,{at:0}),s(this,y).flush(),this.lastCheckpoint=Date.now()}flush(){for(let e of s(this,S))try{e.flush()}catch{}s(this,S).clear()}chmod(e,t){r(this,n,O).call(this,{opp:"chmod",args:[e,t]},()=>{this._chmodState(e,t)})}_chmodState(e,t){let o=r(this,n,f).call(this,e);o.mode=t}close(e){let t=r(this,n,I).call(this,e);s(this,P).delete(e),s(this,D).delete(t)}fstat(e){let t=r(this,n,I).call(this,e);return this.lstat(t)}lstat(e){let t=r(this,n,f).call(this,e),o=t.type==="file"?s(this,m).get(t.backingFilename).getSize():0,i=4096;return{dev:0,ino:0,mode:t.mode,nlink:1,uid:0,gid:0,rdev:0,size:o,blksize:i,blocks:Math.ceil(o/i),atime:t.lastModified,mtime:t.lastModified,ctime:t.lastModified}}mkdir(e,t){r(this,n,O).call(this,{opp:"mkdir",args:[e,t]},()=>{this._mkdirState(e,t)})}_mkdirState(e,t){let o=r(this,n,w).call(this,e),i=o.pop(),c=[],a=this.state.root;for(let d of o){if(c.push(e),!Object.prototype.hasOwnProperty.call(a.children,d))if(t?.recursive)this.mkdir(c.join("/"));else throw new p("ENOENT","No such file or directory");if(a.children[d].type!=="directory")throw new p("ENOTDIR","Not a directory");a=a.children[d]}if(Object.prototype.hasOwnProperty.call(a.children,i))throw new p("EEXIST","File exists");let h={type:"directory",lastModified:Date.now(),mode:t?.mode||T.DIR,children:{}};a.children[i]=h}open(e,t,o){if(r(this,n,f).call(this,e).type!=="file")throw new p("EISDIR","Is a directory");let c=r(this,n,W).call(this);return s(this,P).set(c,e),s(this,D).set(e,c),c}readdir(e){let t=r(this,n,f).call(this,e);if(t.type!=="directory")throw new p("ENOTDIR","Not a directory");return Object.keys(t.children)}read(e,t,o,i,c){let a=r(this,n,I).call(this,e),h=r(this,n,f).call(this,a);if(h.type!=="file")throw new p("EISDIR","Is a directory");return s(this,m).get(h.backingFilename).read(new Uint8Array(t.buffer,o,i),{at:c})}rename(e,t){r(this,n,O).call(this,{opp:"rename",args:[e,t]},()=>{this._renameState(e,t,!0)})}_renameState(e,t,o=!1){let i=r(this,n,w).call(this,e),c=i.pop(),a=r(this,n,f).call(this,i.join("/"));if(!Object.prototype.hasOwnProperty.call(a.children,c))throw new p("ENOENT","No such file or directory");let h=r(this,n,w).call(this,t),d=h.pop(),l=r(this,n,f).call(this,h.join("/"));if(o&&Object.prototype.hasOwnProperty.call(l.children,d)){let u=l.children[d];s(this,m).get(u.backingFilename).truncate(0),this.state.pool.push(u.backingFilename)}l.children[d]=a.children[c],delete a.children[c]}rmdir(e){r(this,n,O).call(this,{opp:"rmdir",args:[e]},()=>{this._rmdirState(e)})}_rmdirState(e){let t=r(this,n,w).call(this,e),o=t.pop(),i=r(this,n,f).call(this,t.join("/"));if(!Object.prototype.hasOwnProperty.call(i.children,o))throw new p("ENOENT","No such file or directory");let c=i.children[o];if(c.type!=="directory")throw new p("ENOTDIR","Not a directory");if(Object.keys(c.children).length>0)throw new p("ENOTEMPTY","Directory not empty");delete i.children[o]}truncate(e,t=0){let o=r(this,n,f).call(this,e);if(o.type!=="file")throw new p("EISDIR","Is a directory");let i=s(this,m).get(o.backingFilename);if(!i)throw new p("ENOENT","No such file or directory");i.truncate(t),s(this,S).add(i)}unlink(e){r(this,n,O).call(this,{opp:"unlink",args:[e]},()=>{this._unlinkState(e,!0)})}_unlinkState(e,t=!1){let o=r(this,n,w).call(this,e),i=o.pop(),c=r(this,n,f).call(this,o.join("/"));if(!Object.prototype.hasOwnProperty.call(c.children,i))throw new p("ENOENT","No such file or directory");let a=c.children[i];if(a.type!=="file")throw new p("EISDIR","Is a directory");if(delete c.children[i],t){let h=s(this,m).get(a.backingFilename);h?.truncate(0),s(this,S).add(h),s(this,D).has(e)&&(s(this,P).delete(s(this,D).get(e)),s(this,D).delete(e))}this.state.pool.push(a.backingFilename)}utimes(e,t,o){r(this,n,O).call(this,{opp:"utimes",args:[e,t,o]},()=>{this._utimesState(e,t,o)})}_utimesState(e,t,o){let i=r(this,n,f).call(this,e);i.lastModified=o}writeFile(e,t,o){let i=r(this,n,w).call(this,e),c=i.pop(),a=r(this,n,f).call(this,i.join("/"));if(Object.prototype.hasOwnProperty.call(a.children,c)){let l=a.children[c];l.lastModified=Date.now(),r(this,n,k).call(this,{opp:"setLastModified",args:[e,l.lastModified]})}else{if(this.state.pool.length===0)throw new Error("No more file handles available in the pool");let l={type:"file",lastModified:Date.now(),mode:o?.mode||T.FILE,backingFilename:this.state.pool.pop()};a.children[c]=l,r(this,n,k).call(this,{opp:"createFileNode",args:[e,l]})}let h=a.children[c],d=s(this,m).get(h.backingFilename);t.length>0&&(d.write(typeof t=="string"?new TextEncoder().encode(t):new Uint8Array(t),{at:0}),e.startsWith("/pg_wal")&&s(this,S).add(d))}_createFileNodeState(e,t){let o=r(this,n,w).call(this,e),i=o.pop(),c=r(this,n,f).call(this,o.join("/"));c.children[i]=t;let a=this.state.pool.indexOf(t.backingFilename);return a>-1&&this.state.pool.splice(a,1),t}_setLastModifiedState(e,t){let o=r(this,n,f).call(this,e);o.lastModified=t}write(e,t,o,i,c){let a=r(this,n,I).call(this,e),h=r(this,n,f).call(this,a);if(h.type!=="file")throw new p("EISDIR","Is a directory");let d=s(this,m).get(h.backingFilename);if(!d)throw new p("EBADF","Bad file descriptor");let l=d.write(new Uint8Array(t,o,i),{at:c});return a.startsWith("/pg_wal")&&s(this,S).add(d),l}};H=new WeakMap,v=new WeakMap,F=new WeakMap,M=new WeakMap,y=new WeakMap,b=new WeakMap,m=new WeakMap,x=new WeakMap,P=new WeakMap,D=new WeakMap,S=new WeakMap,n=new WeakSet,C=async function(){E(this,H,await navigator.storage.getDirectory()),E(this,v,await r(this,n,j).call(this,this.dataDir,{create:!0})),E(this,F,await r(this,n,j).call(this,G,{from:s(this,v),create:!0})),E(this,M,await s(this,v).getFileHandle($,{create:!0})),E(this,y,await s(this,M).createSyncAccessHandle());let e=new ArrayBuffer(s(this,y).getSize());s(this,y).read(e,{at:0});let t,o=new TextDecoder().decode(e).split(` | ||
| import{h as B,i as z}from"../chunk-4QMGOB4T.js";import"../chunk-XP4OYHYJ.js";import{e as s,f as g,g as E,h as r,i as _,j as R}from"../chunk-QY3QWFKW.js";R();var $="state.txt",G="data",T={DIR:16384,FILE:32768},H,v,F,M,y,b,m,x,P,D,S,n,C,O,k,w,f,I,W,j,L=class extends B{constructor(e,{initialPoolSize:t=1e3,maintainedPoolSize:o=100,debug:i=!1}={}){super(e,{debug:i});g(this,n);g(this,H);g(this,v);g(this,F);g(this,M);g(this,y);g(this,b,new Map);g(this,m,new Map);g(this,x,0);g(this,P,new Map);g(this,D,new Map);this.lastCheckpoint=0;this.checkpointInterval=1e3*60;this.poolCounter=0;g(this,S,new Set);this.initialPoolSize=t,this.maintainedPoolSize=o}async init(e,t){return await r(this,n,C).call(this),super.init(e,t)}async syncToFs(e=!1){await this.maybeCheckpointState(),await this.maintainPool(),e||this.flush()}async closeFs(){for(let e of s(this,m).values())e.close();s(this,y).flush(),s(this,y).close(),this.pg.Module.FS.quit()}async maintainPool(e){e=e||this.maintainedPoolSize;let t=e-this.state.pool.length,o=[];for(let i=0;i<t;i++)o.push(new Promise(async c=>{++this.poolCounter;let a=`${(Date.now()-1704063600).toString(16).padStart(8,"0")}-${this.poolCounter.toString(16).padStart(8,"0")}`,h=await s(this,F).getFileHandle(a,{create:!0}),d=await h.createSyncAccessHandle();s(this,b).set(a,h),s(this,m).set(a,d),r(this,n,k).call(this,{opp:"createPoolFile",args:[a]}),this.state.pool.push(a),c()}));for(let i=0;i>t;i--)o.push(new Promise(async c=>{let a=this.state.pool.pop();r(this,n,k).call(this,{opp:"deletePoolFile",args:[a]});let h=s(this,b).get(a);s(this,m).get(a)?.close(),await s(this,F).removeEntry(h.name),s(this,b).delete(a),s(this,m).delete(a),c()}));await Promise.all(o)}_createPoolFileState(e){this.state.pool.push(e)}_deletePoolFileState(e){let t=this.state.pool.indexOf(e);t>-1&&this.state.pool.splice(t,1)}async maybeCheckpointState(){Date.now()-this.lastCheckpoint>this.checkpointInterval&&await this.checkpointState()}async checkpointState(){let e=new TextEncoder().encode(JSON.stringify(this.state));s(this,y).truncate(0),s(this,y).write(e,{at:0}),s(this,y).flush(),this.lastCheckpoint=Date.now()}flush(){for(let e of s(this,S))try{e.flush()}catch{}s(this,S).clear()}chmod(e,t){r(this,n,O).call(this,{opp:"chmod",args:[e,t]},()=>{this._chmodState(e,t)})}_chmodState(e,t){let o=r(this,n,f).call(this,e);o.mode=t}close(e){let t=r(this,n,I).call(this,e);s(this,P).delete(e),s(this,D).delete(t)}fstat(e){let t=r(this,n,I).call(this,e);return this.lstat(t)}lstat(e){let t=r(this,n,f).call(this,e),o=t.type==="file"?s(this,m).get(t.backingFilename).getSize():0,i=4096;return{dev:0,ino:0,mode:t.mode,nlink:1,uid:0,gid:0,rdev:0,size:o,blksize:i,blocks:Math.ceil(o/i),atime:t.lastModified,mtime:t.lastModified,ctime:t.lastModified}}mkdir(e,t){r(this,n,O).call(this,{opp:"mkdir",args:[e,t]},()=>{this._mkdirState(e,t)})}_mkdirState(e,t){let o=r(this,n,w).call(this,e),i=o.pop(),c=[],a=this.state.root;for(let d of o){if(c.push(e),!Object.prototype.hasOwnProperty.call(a.children,d))if(t?.recursive)this.mkdir(c.join("/"));else throw new p("ENOENT","No such file or directory");if(a.children[d].type!=="directory")throw new p("ENOTDIR","Not a directory");a=a.children[d]}if(Object.prototype.hasOwnProperty.call(a.children,i))throw new p("EEXIST","File exists");let h={type:"directory",lastModified:Date.now(),mode:t?.mode||T.DIR,children:{}};a.children[i]=h}open(e,t,o){if(r(this,n,f).call(this,e).type!=="file")throw new p("EISDIR","Is a directory");let c=r(this,n,W).call(this);return s(this,P).set(c,e),s(this,D).set(e,c),c}readdir(e){let t=r(this,n,f).call(this,e);if(t.type!=="directory")throw new p("ENOTDIR","Not a directory");return Object.keys(t.children)}read(e,t,o,i,c){let a=r(this,n,I).call(this,e),h=r(this,n,f).call(this,a);if(h.type!=="file")throw new p("EISDIR","Is a directory");return s(this,m).get(h.backingFilename).read(new Uint8Array(t.buffer,o,i),{at:c})}rename(e,t){r(this,n,O).call(this,{opp:"rename",args:[e,t]},()=>{this._renameState(e,t,!0)})}_renameState(e,t,o=!1){let i=r(this,n,w).call(this,e),c=i.pop(),a=r(this,n,f).call(this,i.join("/"));if(!Object.prototype.hasOwnProperty.call(a.children,c))throw new p("ENOENT","No such file or directory");let h=r(this,n,w).call(this,t),d=h.pop(),l=r(this,n,f).call(this,h.join("/"));if(o&&Object.prototype.hasOwnProperty.call(l.children,d)){let u=l.children[d];s(this,m).get(u.backingFilename).truncate(0),this.state.pool.push(u.backingFilename)}l.children[d]=a.children[c],delete a.children[c]}rmdir(e){r(this,n,O).call(this,{opp:"rmdir",args:[e]},()=>{this._rmdirState(e)})}_rmdirState(e){let t=r(this,n,w).call(this,e),o=t.pop(),i=r(this,n,f).call(this,t.join("/"));if(!Object.prototype.hasOwnProperty.call(i.children,o))throw new p("ENOENT","No such file or directory");let c=i.children[o];if(c.type!=="directory")throw new p("ENOTDIR","Not a directory");if(Object.keys(c.children).length>0)throw new p("ENOTEMPTY","Directory not empty");delete i.children[o]}truncate(e,t=0){let o=r(this,n,f).call(this,e);if(o.type!=="file")throw new p("EISDIR","Is a directory");let i=s(this,m).get(o.backingFilename);if(!i)throw new p("ENOENT","No such file or directory");i.truncate(t),s(this,S).add(i)}unlink(e){r(this,n,O).call(this,{opp:"unlink",args:[e]},()=>{this._unlinkState(e,!0)})}_unlinkState(e,t=!1){let o=r(this,n,w).call(this,e),i=o.pop(),c=r(this,n,f).call(this,o.join("/"));if(!Object.prototype.hasOwnProperty.call(c.children,i))throw new p("ENOENT","No such file or directory");let a=c.children[i];if(a.type!=="file")throw new p("EISDIR","Is a directory");if(delete c.children[i],t){let h=s(this,m).get(a.backingFilename);h?.truncate(0),s(this,S).add(h),s(this,D).has(e)&&(s(this,P).delete(s(this,D).get(e)),s(this,D).delete(e))}this.state.pool.push(a.backingFilename)}utimes(e,t,o){r(this,n,O).call(this,{opp:"utimes",args:[e,t,o]},()=>{this._utimesState(e,t,o)})}_utimesState(e,t,o){let i=r(this,n,f).call(this,e);i.lastModified=o}writeFile(e,t,o){let i=r(this,n,w).call(this,e),c=i.pop(),a=r(this,n,f).call(this,i.join("/"));if(Object.prototype.hasOwnProperty.call(a.children,c)){let l=a.children[c];l.lastModified=Date.now(),r(this,n,k).call(this,{opp:"setLastModified",args:[e,l.lastModified]})}else{if(this.state.pool.length===0)throw new Error("No more file handles available in the pool");let l={type:"file",lastModified:Date.now(),mode:o?.mode||T.FILE,backingFilename:this.state.pool.pop()};a.children[c]=l,r(this,n,k).call(this,{opp:"createFileNode",args:[e,l]})}let h=a.children[c],d=s(this,m).get(h.backingFilename);t.length>0&&(d.write(typeof t=="string"?new TextEncoder().encode(t):new Uint8Array(t),{at:0}),e.startsWith("/pg_wal")&&s(this,S).add(d))}_createFileNodeState(e,t){let o=r(this,n,w).call(this,e),i=o.pop(),c=r(this,n,f).call(this,o.join("/"));c.children[i]=t;let a=this.state.pool.indexOf(t.backingFilename);return a>-1&&this.state.pool.splice(a,1),t}_setLastModifiedState(e,t){let o=r(this,n,f).call(this,e);o.lastModified=t}write(e,t,o,i,c){let a=r(this,n,I).call(this,e),h=r(this,n,f).call(this,a);if(h.type!=="file")throw new p("EISDIR","Is a directory");let d=s(this,m).get(h.backingFilename);if(!d)throw new p("EBADF","Bad file descriptor");let l=d.write(new Uint8Array(t,o,i),{at:c});return a.startsWith("/pg_wal")&&s(this,S).add(d),l}};H=new WeakMap,v=new WeakMap,F=new WeakMap,M=new WeakMap,y=new WeakMap,b=new WeakMap,m=new WeakMap,x=new WeakMap,P=new WeakMap,D=new WeakMap,S=new WeakMap,n=new WeakSet,C=async function(){E(this,H,await navigator.storage.getDirectory()),E(this,v,await r(this,n,j).call(this,this.dataDir,{create:!0})),E(this,F,await r(this,n,j).call(this,G,{from:s(this,v),create:!0})),E(this,M,await s(this,v).getFileHandle($,{create:!0})),E(this,y,await s(this,M).createSyncAccessHandle());let e=new ArrayBuffer(s(this,y).getSize());s(this,y).read(e,{at:0});let t,o=new TextDecoder().decode(e).split(` | ||
| `),i=!1;try{t=JSON.parse(o[0])}catch{t={root:{type:"directory",lastModified:Date.now(),mode:T.DIR,children:{}},pool:[]},s(this,y).truncate(0),s(this,y).write(new TextEncoder().encode(JSON.stringify(t)),{at:0}),i=!0}this.state=t;let c=o.slice(1).filter(Boolean).map(l=>JSON.parse(l));for(let l of c){let u=`_${l.opp}State`;if(typeof this[u]=="function")try{this[u].bind(this)(...l.args)}catch(N){console.warn("Error applying OPFS AHP WAL entry",l,N)}}let a=[],h=async l=>{if(l.type==="file")try{let u=await s(this,F).getFileHandle(l.backingFilename),N=await u.createSyncAccessHandle();s(this,b).set(l.backingFilename,u),s(this,m).set(l.backingFilename,N)}catch(u){console.error("Error opening file handle for node",l,u)}else for(let u of Object.values(l.children))a.push(h(u))};await h(this.state.root);let d=[];for(let l of this.state.pool)d.push(new Promise(async u=>{s(this,b).has(l)&&console.warn("File handle already exists for pool file",l);let N=await s(this,F).getFileHandle(l),U=await N.createSyncAccessHandle();s(this,b).set(l,N),s(this,m).set(l,U),u()}));await Promise.all([...a,...d]),await this.maintainPool(i?this.initialPoolSize:this.maintainedPoolSize)},O=function(e,t){let o=r(this,n,k).call(this,e);try{t()}catch(i){throw s(this,y).truncate(o),i}},k=function(e){let t=JSON.stringify(e),o=new TextEncoder().encode(` | ||
| ${t}`),i=s(this,y).getSize();return s(this,y).write(o,{at:i}),s(this,S).add(s(this,y)),i},w=function(e){return e.split("/").filter(Boolean)},f=function(e,t){let o=r(this,n,w).call(this,e),i=t||this.state.root;for(let c of o){if(i.type!=="directory")throw new p("ENOTDIR","Not a directory");if(!Object.prototype.hasOwnProperty.call(i.children,c))throw new p("ENOENT","No such file or directory");i=i.children[c]}return i},I=function(e){let t=s(this,P).get(e);if(!t)throw new p("EBADF","Bad file descriptor");return t},W=function(){let e=++_(this,x)._;for(;s(this,P).has(e);)_(this,x)._++;return e},j=async function(e,t){let o=r(this,n,w).call(this,e),i=t?.from||s(this,H);for(let c of o)i=await i.getDirectoryHandle(c,{create:t?.create});return i};var p=class extends Error{constructor(A,e){super(e),typeof A=="number"?this.code=A:typeof A=="string"&&(this.code=z[A])}};export{L as OpfsAhpFS}; | ||
| //# sourceMappingURL=opfs-ahp.js.map |
@@ -1,2 +0,2 @@ | ||
| "use strict";var _e=Object.create;var Q=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var Ae=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var ae=e=>{throw TypeError(e)};var Re=(e,t)=>{for(var n in t)Q(e,n,{get:t[n],enumerable:!0})},oe=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of we(t))!Te.call(e,r)&&r!==n&&Q(e,r,{get:()=>t[r],enumerable:!(s=Ee(t,r))||s.enumerable});return e};var ue=(e,t,n)=>(n=e!=null?_e(Ae(e)):{},oe(t||!e||!e.__esModule?Q(n,"default",{value:e,enumerable:!0}):n,e)),Se=e=>oe(Q({},"__esModule",{value:!0}),e);var te=(e,t,n)=>t.has(e)||ae("Cannot "+n);var c=(e,t,n)=>(te(e,t,"read from private field"),n?n.call(e):t.get(e)),O=(e,t,n)=>t.has(e)?ae("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),v=(e,t,n,s)=>(te(e,t,"write to private field"),s?s.call(e,n):t.set(e,n),n),L=(e,t,n)=>(te(e,t,"access private method"),n);var ne=(e,t,n,s)=>({set _(r){v(e,t,r,n)},get _(){return c(e,t,s)}});var Tt={};Re(Tt,{live:()=>wt});module.exports=Se(Tt);function U(e){let t=e.length;for(let n=e.length-1;n>=0;n--){let s=e.charCodeAt(n);s>127&&s<=2047?t++:s>2047&&s<=65535&&(t+=2),s>=56320&&s<=57343&&n--}return t}var A,T,k,H,V,S,W,F,ce,x=class{constructor(t=256){this.size=t;O(this,S);O(this,A);O(this,T,5);O(this,k,!1);O(this,H,new TextEncoder);O(this,V,0);v(this,A,L(this,S,W).call(this,t))}addInt32(t){return L(this,S,F).call(this,4),c(this,A).setInt32(c(this,T),t,c(this,k)),v(this,T,c(this,T)+4),this}addInt16(t){return L(this,S,F).call(this,2),c(this,A).setInt16(c(this,T),t,c(this,k)),v(this,T,c(this,T)+2),this}addCString(t){return t&&this.addString(t),L(this,S,F).call(this,1),c(this,A).setUint8(c(this,T),0),ne(this,T)._++,this}addString(t=""){let n=U(t);return L(this,S,F).call(this,n),c(this,H).encodeInto(t,new Uint8Array(c(this,A).buffer,c(this,T))),v(this,T,c(this,T)+n),this}add(t){return L(this,S,F).call(this,t.byteLength),new Uint8Array(c(this,A).buffer).set(new Uint8Array(t),c(this,T)),v(this,T,c(this,T)+t.byteLength),this}flush(t){let n=L(this,S,ce).call(this,t);return v(this,T,5),v(this,A,L(this,S,W).call(this,this.size)),new Uint8Array(n)}};A=new WeakMap,T=new WeakMap,k=new WeakMap,H=new WeakMap,V=new WeakMap,S=new WeakSet,W=function(t){return new DataView(new ArrayBuffer(t))},F=function(t){if(c(this,A).byteLength-c(this,T)<t){let s=c(this,A).buffer,r=s.byteLength+(s.byteLength>>1)+t;v(this,A,L(this,S,W).call(this,r)),new Uint8Array(c(this,A).buffer).set(new Uint8Array(s))}},ce=function(t){if(t){c(this,A).setUint8(c(this,V),t);let n=c(this,T)-(c(this,V)+1);c(this,A).setInt32(c(this,V)+1,n,c(this,k))}return c(this,A).buffer.slice(t?0:5,c(this,T))};var g=new x,Ie=e=>{g.addInt16(3).addInt16(0);for(let s of Object.keys(e))g.addCString(s).addCString(e[s]);g.addCString("client_encoding").addCString("UTF8");let t=g.addCString("").flush(),n=t.byteLength+4;return new x().addInt32(n).add(t).flush()},ve=()=>{let e=new DataView(new ArrayBuffer(8));return e.setInt32(0,8,!1),e.setInt32(4,80877103,!1),new Uint8Array(e.buffer)},Ce=e=>g.addCString(e).flush(112),Ne=(e,t)=>(g.addCString(e).addInt32(U(t)).addString(t),g.flush(112)),Le=e=>g.addString(e).flush(112),De=e=>g.addCString(e).flush(81),Oe=[],Me=e=>{let t=e.name??"";t.length>63&&(console.error("Warning! Postgres only supports 63 characters for query names."),console.error("You supplied %s (%s)",t,t.length),console.error("This can cause conflicts and silent errors executing queries"));let n=g.addCString(t).addCString(e.text).addInt16(e.types?.length??0);return e.types?.forEach(s=>n.addInt32(s)),g.flush(80)},G=new x;var Be=(e,t)=>{for(let n=0;n<e.length;n++){let s=t?t(e[n],n):e[n];if(s===null)g.addInt16(0),G.addInt32(-1);else if(s instanceof ArrayBuffer||ArrayBuffer.isView(s)){let r=ArrayBuffer.isView(s)?s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength):s;g.addInt16(1),G.addInt32(r.byteLength),G.add(r)}else g.addInt16(0),G.addInt32(U(s)),G.addString(s)}},Pe=(e={})=>{let t=e.portal??"",n=e.statement??"",s=e.binary??!1,r=e.values??Oe,a=r.length;return g.addCString(t).addCString(n),g.addInt16(a),Be(r,e.valueMapper),g.addInt16(a),g.add(G.flush()),g.addInt16(s?1:0),g.flush(66)},xe=new Uint8Array([69,0,0,0,9,0,0,0,0,0]),$e=e=>{if(!e||!e.portal&&!e.rows)return xe;let t=e.portal??"",n=e.rows??0,s=U(t),r=4+s+1+4,a=new DataView(new ArrayBuffer(1+r));return a.setUint8(0,69),a.setInt32(1,r,!1),new TextEncoder().encodeInto(t,new Uint8Array(a.buffer,5)),a.setUint8(s+5,0),a.setUint32(a.byteLength-4,n,!1),new Uint8Array(a.buffer)},Ue=(e,t)=>{let n=new DataView(new ArrayBuffer(16));return n.setInt32(0,16,!1),n.setInt16(4,1234,!1),n.setInt16(6,5678,!1),n.setInt32(8,e,!1),n.setInt32(12,t,!1),new Uint8Array(n.buffer)},re=(e,t)=>{let n=new x;return n.addCString(t),n.flush(e)},Fe=g.addCString("P").flush(68),ke=g.addCString("S").flush(68),Ve=e=>e.name?re(68,`${e.type}${e.name??""}`):e.type==="P"?Fe:ke,Ge=e=>{let t=`${e.type}${e.name??""}`;return re(67,t)},qe=e=>g.add(e).flush(100),je=e=>re(102,e),z=e=>new Uint8Array([e,0,0,0,4]),Qe=z(72),We=z(83),He=z(88),ze=z(99),q={startup:Ie,password:Ce,requestSsl:ve,sendSASLInitialResponseMessage:Ne,sendSCRAMClientFinalMessage:Le,query:De,parse:Me,bind:Pe,execute:$e,describe:Ve,close:Ge,flush:()=>Qe,sync:()=>We,end:()=>He,copyData:qe,copyDone:()=>ze,copyFail:je,cancel:Ue};var Ut=new ArrayBuffer(0);var Je=1,Ye=4,Sn=Je+Ye,In=new ArrayBuffer(0);var Ke=globalThis.JSON.parse,Ze=globalThis.JSON.stringify,le=16,de=17;var pe=20,et=21,tt=23;var X=25,nt=26;var fe=114;var rt=700,st=701;var it=1042,at=1043,ot=1082;var ut=1114,me=1184;var ct=3802;var lt={string:{to:X,from:[X,at,it],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return e.toString();throw new Error("Invalid input for string type")},parse:e=>e},number:{to:0,from:[et,tt,nt,rt,st],serialize:e=>e.toString(),parse:e=>+e},bigint:{to:pe,from:[pe],serialize:e=>e.toString(),parse:e=>{let t=BigInt(e);return t<Number.MIN_SAFE_INTEGER||t>Number.MAX_SAFE_INTEGER?t:Number(t)}},json:{to:fe,from:[fe,ct],serialize:e=>typeof e=="string"?e:Ze(e),parse:e=>Ke(e)},boolean:{to:le,from:[le],serialize:e=>{if(typeof e!="boolean")throw new Error("Invalid input for boolean type");return e?"t":"f"},parse:e=>e==="t"},date:{to:me,from:[ot,ut,me],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return new Date(e).toISOString();if(e instanceof Date)return e.toISOString();throw new Error("Invalid input for date type")},parse:e=>new Date(e)},bytea:{to:de,from:[de],serialize:e=>{if(!(e instanceof Uint8Array))throw new Error("Invalid input for bytea type");return"\\x"+Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")},parse:e=>{let t=e.slice(2);return Uint8Array.from({length:t.length/2},(n,s)=>parseInt(t.substring(s*2,(s+1)*2),16))}}},ye=dt(lt),Pn=ye.parsers,xn=ye.serializers;function dt(e){return Object.keys(e).reduce(({parsers:t,serializers:n},s)=>{let{to:r,from:a,serialize:i,parse:b}=e[s];return n[r]=i,n[s]=i,t[s]=b,Array.isArray(a)?a.forEach(y=>{t[y]=b,n[y]=i}):(t[a]=b,n[a]=i),{parsers:t,serializers:n}},{parsers:{},serializers:{}})}function he(e){let t=e.find(n=>n.name==="parameterDescription");return t?t.dataTypeIDs:[]}async function se(e,t,n,s){if(!n||n.length===0)return t;s=s??e;let r=[];try{await e.execProtocol(q.parse({text:t}),{syncToFs:!1}),r.push(...(await e.execProtocol(q.describe({type:"S"}),{syncToFs:!1})).messages)}finally{r.push(...(await e.execProtocol(q.sync(),{syncToFs:!1})).messages)}let a=he(r),i=t.replace(/\$([0-9]+)/g,(y,l)=>"%"+l+"L");return(await s.query(`SELECT format($1, ${n.map((y,l)=>`$${l+2}`).join(", ")}) as query`,[i,...n],{paramTypes:[X,...a]})).rows[0].query}function ie(e){let t,n=!1,s=async()=>{if(!t){n=!1;return}n=!0;let{args:r,resolve:a,reject:i}=t;t=void 0;try{let b=await e(...r);a(b)}catch(b){i(b)}finally{s()}};return async(...r)=>{t&&t.resolve(void 0);let a=new Promise((i,b)=>{t={args:r,resolve:i,reject:b}});return n||s(),a}}var pt=Object.defineProperty,ft=(e,t)=>{for(var n in t)pt(e,n,{get:t[n],enumerable:!0})},Y={};ft(Y,{IN_NODE:()=>K,getFsBundle:()=>ht,instantiateWasm:()=>yt,startWasmDownload:()=>mt,toPostgresName:()=>bt,uuid:()=>gt});var K=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",j=new Map;async function mt(e){K||j.has(e)||j.set(e,fetch(e))}var J=new Map;async function yt(e,t,n){if(n||J.has(t)){let s=n||J.get(t);return{instance:await WebAssembly.instantiate(s,e),module:s}}if(K){let s=await(await import("fs/promises")).readFile(t),{module:r,instance:a}=await WebAssembly.instantiate(s,e);return J.set(t,r),{instance:a,module:r}}else{j.has(t)||j.set(t,fetch(t));let s=await j.get(t),{module:r,instance:a}=await WebAssembly.instantiateStreaming(s,e);return J.set(t,r),{instance:a,module:r}}}async function ht(e){return K?(await(await import("fs/promises")).readFile(e)).buffer:(await fetch(e)).arrayBuffer()}var gt=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let e=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(e);else for(let n=0;n<e.length;n++)e[n]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[];return e.forEach(n=>{t.push(n.toString(16).padStart(2,"0"))}),t.slice(0,4).join("")+"-"+t.slice(4,6).join("")+"-"+t.slice(6,8).join("")+"-"+t.slice(8,10).join("")+"-"+t.slice(10).join("")};function bt(e){let t;return e.startsWith('"')&&e.endsWith('"')?t=e.substring(1,e.length-1):t=e.toLowerCase(),t}var _t=5,Et=async(e,t)=>{let n=new Set,s={async query(r,a,i){let b,y,l;if(typeof r!="string"&&(b=r.signal,a=r.params,i=r.callback,y=r.offset,l=r.limit,r=r.query),y===void 0!=(l===void 0))throw new Error("offset and limit must be provided together");let o=y!==void 0&&l!==void 0,R;if(o&&(typeof y!="number"||isNaN(y)||typeof l!="number"||isNaN(l)))throw new Error("offset and limit must be numbers");let _=i?[i]:[],m=Y.uuid().replace(/-/g,""),D=!1,I,M,$=async()=>{await e.transaction(async u=>{let d=a&&a.length>0?await se(e,r,a,u):r;await u.exec(`CREATE OR REPLACE TEMP VIEW live_query_${m}_view AS ${d}`);let E=await ge(u,`live_query_${m}_view`);await be(u,E,n),o?(await u.exec(` | ||
| "use strict";var Ee=Object.create;var Q=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var Te=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var oe=e=>{throw TypeError(e)};var Re=(e,t)=>{for(var n in t)Q(e,n,{get:t[n],enumerable:!0})},ue=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ae(t))!Se.call(e,r)&&r!==n&&Q(e,r,{get:()=>t[r],enumerable:!(s=we(t,r))||s.enumerable});return e};var ce=(e,t,n)=>(n=e!=null?Ee(Te(e)):{},ue(t||!e||!e.__esModule?Q(n,"default",{value:e,enumerable:!0}):n,e)),Ie=e=>ue(Q({},"__esModule",{value:!0}),e);var te=(e,t,n)=>t.has(e)||oe("Cannot "+n);var c=(e,t,n)=>(te(e,t,"read from private field"),n?n.call(e):t.get(e)),O=(e,t,n)=>t.has(e)?oe("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),v=(e,t,n,s)=>(te(e,t,"write to private field"),s?s.call(e,n):t.set(e,n),n),L=(e,t,n)=>(te(e,t,"access private method"),n);var ne=(e,t,n,s)=>({set _(r){v(e,t,r,n)},get _(){return c(e,t,s)}});var Tt={};Re(Tt,{live:()=>wt});module.exports=Ie(Tt);function U(e){let t=e.length;for(let n=e.length-1;n>=0;n--){let s=e.charCodeAt(n);s>127&&s<=2047?t++:s>2047&&s<=65535&&(t+=2),s>=56320&&s<=57343&&n--}return t}var A,T,k,H,V,R,W,F,le,x=class{constructor(t=256){this.size=t;O(this,R);O(this,A);O(this,T,5);O(this,k,!1);O(this,H,new TextEncoder);O(this,V,0);v(this,A,L(this,R,W).call(this,t))}addInt32(t){return L(this,R,F).call(this,4),c(this,A).setInt32(c(this,T),t,c(this,k)),v(this,T,c(this,T)+4),this}addInt16(t){return L(this,R,F).call(this,2),c(this,A).setInt16(c(this,T),t,c(this,k)),v(this,T,c(this,T)+2),this}addCString(t){return t&&this.addString(t),L(this,R,F).call(this,1),c(this,A).setUint8(c(this,T),0),ne(this,T)._++,this}addString(t=""){let n=U(t);return L(this,R,F).call(this,n),c(this,H).encodeInto(t,new Uint8Array(c(this,A).buffer,c(this,T))),v(this,T,c(this,T)+n),this}add(t){return L(this,R,F).call(this,t.byteLength),new Uint8Array(c(this,A).buffer).set(new Uint8Array(t),c(this,T)),v(this,T,c(this,T)+t.byteLength),this}flush(t){let n=L(this,R,le).call(this,t);return v(this,T,5),v(this,A,L(this,R,W).call(this,this.size)),new Uint8Array(n)}};A=new WeakMap,T=new WeakMap,k=new WeakMap,H=new WeakMap,V=new WeakMap,R=new WeakSet,W=function(t){return new DataView(new ArrayBuffer(t))},F=function(t){if(c(this,A).byteLength-c(this,T)<t){let s=c(this,A).buffer,r=s.byteLength+(s.byteLength>>1)+t;v(this,A,L(this,R,W).call(this,r)),new Uint8Array(c(this,A).buffer).set(new Uint8Array(s))}},le=function(t){if(t){c(this,A).setUint8(c(this,V),t);let n=c(this,T)-(c(this,V)+1);c(this,A).setInt32(c(this,V)+1,n,c(this,k))}return c(this,A).buffer.slice(t?0:5,c(this,T))};var g=new x,ve=e=>{g.addInt16(3).addInt16(0);for(let s of Object.keys(e))g.addCString(s).addCString(e[s]);g.addCString("client_encoding").addCString("UTF8");let t=g.addCString("").flush(),n=t.byteLength+4;return new x().addInt32(n).add(t).flush()},Ce=()=>{let e=new DataView(new ArrayBuffer(8));return e.setInt32(0,8,!1),e.setInt32(4,80877103,!1),new Uint8Array(e.buffer)},Ne=e=>g.addCString(e).flush(112),Le=(e,t)=>(g.addCString(e).addInt32(U(t)).addString(t),g.flush(112)),De=e=>g.addString(e).flush(112),Oe=e=>g.addCString(e).flush(81),Me=[],Be=e=>{let t=e.name??"";t.length>63&&(console.error("Warning! Postgres only supports 63 characters for query names."),console.error("You supplied %s (%s)",t,t.length),console.error("This can cause conflicts and silent errors executing queries"));let n=g.addCString(t).addCString(e.text).addInt16(e.types?.length??0);return e.types?.forEach(s=>n.addInt32(s)),g.flush(80)},G=new x;var Pe=(e,t)=>{for(let n=0;n<e.length;n++){let s=t?t(e[n],n):e[n];if(s===null)g.addInt16(0),G.addInt32(-1);else if(s instanceof ArrayBuffer||ArrayBuffer.isView(s)){let r=ArrayBuffer.isView(s)?s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength):s;g.addInt16(1),G.addInt32(r.byteLength),G.add(r)}else g.addInt16(0),G.addInt32(U(s)),G.addString(s)}},xe=(e={})=>{let t=e.portal??"",n=e.statement??"",s=e.binary??!1,r=e.values??Me,a=r.length;return g.addCString(t).addCString(n),g.addInt16(a),Pe(r,e.valueMapper),g.addInt16(a),g.add(G.flush()),g.addInt16(s?1:0),g.flush(66)},$e=new Uint8Array([69,0,0,0,9,0,0,0,0,0]),Ue=e=>{if(!e||!e.portal&&!e.rows)return $e;let t=e.portal??"",n=e.rows??0,s=U(t),r=4+s+1+4,a=new DataView(new ArrayBuffer(1+r));return a.setUint8(0,69),a.setInt32(1,r,!1),new TextEncoder().encodeInto(t,new Uint8Array(a.buffer,5)),a.setUint8(s+5,0),a.setUint32(a.byteLength-4,n,!1),new Uint8Array(a.buffer)},Fe=(e,t)=>{let n=new DataView(new ArrayBuffer(16));return n.setInt32(0,16,!1),n.setInt16(4,1234,!1),n.setInt16(6,5678,!1),n.setInt32(8,e,!1),n.setInt32(12,t,!1),new Uint8Array(n.buffer)},re=(e,t)=>{let n=new x;return n.addCString(t),n.flush(e)},ke=g.addCString("P").flush(68),Ve=g.addCString("S").flush(68),Ge=e=>e.name?re(68,`${e.type}${e.name??""}`):e.type==="P"?ke:Ve,qe=e=>{let t=`${e.type}${e.name??""}`;return re(67,t)},je=e=>g.add(e).flush(100),Qe=e=>re(102,e),z=e=>new Uint8Array([e,0,0,0,4]),We=z(72),He=z(83),ze=z(88),Xe=z(99),q={startup:ve,password:Ne,requestSsl:Ce,sendSASLInitialResponseMessage:Le,sendSCRAMClientFinalMessage:De,query:Oe,parse:Be,bind:xe,execute:Ue,describe:Ge,close:qe,flush:()=>We,sync:()=>He,end:()=>ze,copyData:je,copyDone:()=>Xe,copyFail:Qe,cancel:Fe};var Ut=new ArrayBuffer(0);var Ye=1,Ke=4,Rn=Ye+Ke,In=new ArrayBuffer(0);var Ze=globalThis.JSON.parse,et=globalThis.JSON.stringify,de=16,pe=17;var fe=20,tt=21,nt=23;var X=25,rt=26;var me=114;var st=700,it=701;var at=1042,ot=1043,ut=1082;var ct=1114,ye=1184;var lt=3802;var dt={string:{to:X,from:[X,ot,at],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return e.toString();throw new Error("Invalid input for string type")},parse:e=>e},number:{to:0,from:[tt,nt,rt,st,it],serialize:e=>e.toString(),parse:e=>+e},bigint:{to:fe,from:[fe],serialize:e=>e.toString(),parse:e=>{let t=BigInt(e);return t<Number.MIN_SAFE_INTEGER||t>Number.MAX_SAFE_INTEGER?t:Number(t)}},json:{to:me,from:[me,lt],serialize:e=>typeof e=="string"?e:et(e),parse:e=>Ze(e)},boolean:{to:de,from:[de],serialize:e=>{if(typeof e!="boolean")throw new Error("Invalid input for boolean type");return e?"t":"f"},parse:e=>e==="t"},date:{to:ye,from:[ut,ct,ye],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return new Date(e).toISOString();if(e instanceof Date)return e.toISOString();throw new Error("Invalid input for date type")},parse:e=>new Date(e)},bytea:{to:pe,from:[pe],serialize:e=>{if(!(e instanceof Uint8Array))throw new Error("Invalid input for bytea type");return"\\x"+Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")},parse:e=>{let t=e.slice(2);return Uint8Array.from({length:t.length/2},(n,s)=>parseInt(t.substring(s*2,(s+1)*2),16))}}},he=pt(dt),Pn=he.parsers,xn=he.serializers;function pt(e){return Object.keys(e).reduce(({parsers:t,serializers:n},s)=>{let{to:r,from:a,serialize:i,parse:b}=e[s];return n[r]=i,n[s]=i,t[s]=b,Array.isArray(a)?a.forEach(y=>{t[y]=b,n[y]=i}):(t[a]=b,n[a]=i),{parsers:t,serializers:n}},{parsers:{},serializers:{}})}function ge(e){let t=e.find(n=>n.name==="parameterDescription");return t?t.dataTypeIDs:[]}async function se(e,t,n,s){if(!n||n.length===0)return t;s=s??e;let r=[];try{await e.execProtocol(q.parse({text:t}),{syncToFs:!1}),r.push(...(await e.execProtocol(q.describe({type:"S"}),{syncToFs:!1})).messages)}finally{r.push(...(await e.execProtocol(q.sync(),{syncToFs:!1})).messages)}let a=ge(r),i=t.replace(/\$([0-9]+)/g,(y,l)=>"%"+l+"L");return(await s.query(`SELECT format($1, ${n.map((y,l)=>`$${l+2}`).join(", ")}) as query`,[i,...n],{paramTypes:[X,...a]})).rows[0].query}function ie(e){let t,n=!1,s=async()=>{if(!t){n=!1;return}n=!0;let{args:r,resolve:a,reject:i}=t;t=void 0;try{let b=await e(...r);a(b)}catch(b){i(b)}finally{s()}};return async(...r)=>{t&&t.resolve(void 0);let a=new Promise((i,b)=>{t={args:r,resolve:i,reject:b}});return n||s(),a}}var ft=Object.defineProperty,mt=(e,t)=>{for(var n in t)ft(e,n,{get:t[n],enumerable:!0})},Y={};mt(Y,{IN_NODE:()=>K,getFsBundle:()=>ht,instantiateWasm:()=>yt,startArtifactDownload:()=>ae,toPostgresName:()=>bt,uuid:()=>gt});var K=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",j=new Map;async function ae(e){K||j.has(e.toString())||j.set(e.toString(),fetch(e))}var J=new Map;async function yt(e,t,n){if(n||J.has(t.toString())){let s=n||J.get(t.toString());return{instance:await WebAssembly.instantiate(s,e),module:s}}if(K){let s=await(await import("fs/promises")).readFile(t),{module:r,instance:a}=await WebAssembly.instantiate(s,e);return J.set(t.toString(),r),{instance:a,module:r}}else{j.has(t.toString())||ae(t);let s=await j.get(t.toString()),{module:r,instance:a}=await WebAssembly.instantiateStreaming(s.clone(),e);return J.set(t.toString(),r),{instance:a,module:r}}}async function ht(e){return K?(await(await import("fs/promises")).readFile(e)).buffer:(ae(e),(await j.get(e.toString())).clone().arrayBuffer())}var gt=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let e=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(e);else for(let n=0;n<e.length;n++)e[n]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[];return e.forEach(n=>{t.push(n.toString(16).padStart(2,"0"))}),t.slice(0,4).join("")+"-"+t.slice(4,6).join("")+"-"+t.slice(6,8).join("")+"-"+t.slice(8,10).join("")+"-"+t.slice(10).join("")};function bt(e){let t;return e.startsWith('"')&&e.endsWith('"')?t=e.substring(1,e.length-1):t=e.toLowerCase(),t}var _t=5,Et=async(e,t)=>{let n=new Set,s={async query(r,a,i){let b,y,l;if(typeof r!="string"&&(b=r.signal,a=r.params,i=r.callback,y=r.offset,l=r.limit,r=r.query),y===void 0!=(l===void 0))throw new Error("offset and limit must be provided together");let o=y!==void 0&&l!==void 0,S;if(o&&(typeof y!="number"||isNaN(y)||typeof l!="number"||isNaN(l)))throw new Error("offset and limit must be numbers");let _=i?[i]:[],m=Y.uuid().replace(/-/g,""),D=!1,I,M,$=async()=>{await e.transaction(async u=>{let d=a&&a.length>0?await se(e,r,a,u):r;await u.exec(`CREATE OR REPLACE TEMP VIEW live_query_${m}_view AS ${d}`);let E=await be(u,`live_query_${m}_view`);await _e(u,E,n),o?(await u.exec(` | ||
| PREPARE live_query_${m}_get(int, int) AS | ||
@@ -8,9 +8,9 @@ SELECT * FROM live_query_${m}_view | ||
| SELECT COUNT(*) FROM live_query_${m}_view; | ||
| `),R=(await u.query(`EXECUTE live_query_${m}_get_total_count;`)).rows[0].count,I={...await u.query(`EXECUTE live_query_${m}_get(${l}, ${y});`),offset:y,limit:l,totalCount:R}):(await u.exec(` | ||
| `),S=(await u.query(`EXECUTE live_query_${m}_get_total_count;`)).rows[0].count,I={...await u.query(`EXECUTE live_query_${m}_get(${l}, ${y});`),offset:y,limit:l,totalCount:S}):(await u.exec(` | ||
| PREPARE live_query_${m}_get AS | ||
| SELECT * FROM live_query_${m}_view; | ||
| `),I=await u.query(`EXECUTE live_query_${m}_get;`)),M=await Promise.all(E.map(w=>u.listen(`"table_change__${w.schema_oid}__${w.table_oid}"`,async()=>{N()})))})};await $();let N=ie(async({offset:u,limit:d}={})=>{if(!o&&(u!==void 0||d!==void 0))throw new Error("offset and limit cannot be provided for non-windowed queries");if(u&&(typeof u!="number"||isNaN(u))||d&&(typeof d!="number"||isNaN(d)))throw new Error("offset and limit must be numbers");y=u??y,l=d??l;let E=async(w=0)=>{if(_.length!==0){try{o?I={...await e.query(`EXECUTE live_query_${m}_get(${l}, ${y});`),offset:y,limit:l,totalCount:R}:I=await e.query(`EXECUTE live_query_${m}_get;`)}catch(h){let p=h.message;if(p.startsWith(`prepared statement "live_query_${m}`)&&p.endsWith("does not exist")){if(w>_t)throw h;await $(),E(w+1)}else throw h}if(Z(_,I),o){let h=(await e.query(`EXECUTE live_query_${m}_get_total_count;`)).rows[0].count;h!==R&&(R=h,N())}}};await E()}),B=u=>{if(D)throw new Error("Live query is no longer active and cannot be subscribed to");_.push(u)},f=async u=>{u?_=_.filter(d=>d!==d):_=[],_.length===0&&!D&&(D=!0,await e.transaction(async d=>{await Promise.all(M.map(E=>E(d))),await d.exec(` | ||
| `),I=await u.query(`EXECUTE live_query_${m}_get;`)),M=await Promise.all(E.map(w=>u.listen(`"table_change__${w.schema_oid}__${w.table_oid}"`,async()=>{N()})))})};await $();let N=ie(async({offset:u,limit:d}={})=>{if(!o&&(u!==void 0||d!==void 0))throw new Error("offset and limit cannot be provided for non-windowed queries");if(u&&(typeof u!="number"||isNaN(u))||d&&(typeof d!="number"||isNaN(d)))throw new Error("offset and limit must be numbers");y=u??y,l=d??l;let E=async(w=0)=>{if(_.length!==0){try{o?I={...await e.query(`EXECUTE live_query_${m}_get(${l}, ${y});`),offset:y,limit:l,totalCount:S}:I=await e.query(`EXECUTE live_query_${m}_get;`)}catch(h){let p=h.message;if(p.startsWith(`prepared statement "live_query_${m}`)&&p.endsWith("does not exist")){if(w>_t)throw h;await $(),E(w+1)}else throw h}if(Z(_,I),o){let h=(await e.query(`EXECUTE live_query_${m}_get_total_count;`)).rows[0].count;h!==S&&(S=h,N())}}};await E()}),B=u=>{if(D)throw new Error("Live query is no longer active and cannot be subscribed to");_.push(u)},f=async u=>{u?_=_.filter(d=>d!==d):_=[],_.length===0&&!D&&(D=!0,await e.transaction(async d=>{await Promise.all(M.map(E=>E(d))),await d.exec(` | ||
| DROP VIEW IF EXISTS live_query_${m}_view; | ||
| DEALLOCATE live_query_${m}_get; | ||
| `)}))};return b?.aborted?await f():b?.addEventListener("abort",()=>{f()},{once:!0}),Z(_,I),{initialResults:I,subscribe:B,unsubscribe:f,refresh:N}},async changes(r,a,i,b){let y;if(typeof r!="string"&&(y=r.signal,a=r.params,i=r.key,b=r.callback,r=r.query),!i)throw new Error("key is required for changes queries");let l=b?[b]:[],o=Y.uuid().replace(/-/g,""),R=!1,_=1,m,D,I=async()=>{await e.transaction(async f=>{let u=await se(e,r,a,f);await f.query(`CREATE OR REPLACE TEMP VIEW live_query_${o}_view AS ${u}`);let d=await ge(f,`live_query_${o}_view`);await be(f,d,n);let E=[...(await f.query(` | ||
| `)}))};return b?.aborted?await f():b?.addEventListener("abort",()=>{f()},{once:!0}),Z(_,I),{initialResults:I,subscribe:B,unsubscribe:f,refresh:N}},async changes(r,a,i,b){let y;if(typeof r!="string"&&(y=r.signal,a=r.params,i=r.key,b=r.callback,r=r.query),!i)throw new Error("key is required for changes queries");let l=b?[b]:[],o=Y.uuid().replace(/-/g,""),S=!1,_=1,m,D,I=async()=>{await e.transaction(async f=>{let u=await se(e,r,a,f);await f.query(`CREATE OR REPLACE TEMP VIEW live_query_${o}_view AS ${u}`);let d=await be(f,`live_query_${o}_view`);await _e(f,d,n);let E=[...(await f.query(` | ||
| SELECT column_name, data_type, udt_name | ||
@@ -72,3 +72,3 @@ FROM information_schema.columns | ||
| TRUNCATE live_query_${o}_state${_}; | ||
| `)});break}catch(d){if(d.message===`relation "live_query_${o}_state${_}" does not exist`){f=!0,await I();continue}else throw d}At(l,[...f?[{__op__:"RESET"}]:[],...m.rows])}),$=f=>{if(R)throw new Error("Live query is no longer active and cannot be subscribed to");l.push(f)},N=async f=>{f?l=l.filter(u=>u!==u):l=[],l.length===0&&!R&&(R=!0,await e.transaction(async u=>{await Promise.all(D.map(d=>d(u))),await u.exec(` | ||
| `)});break}catch(d){if(d.message===`relation "live_query_${o}_state${_}" does not exist`){f=!0,await I();continue}else throw d}At(l,[...f?[{__op__:"RESET"}]:[],...m.rows])}),$=f=>{if(S)throw new Error("Live query is no longer active and cannot be subscribed to");l.push(f)},N=async f=>{f?l=l.filter(u=>u!==u):l=[],l.length===0&&!S&&(S=!0,await e.transaction(async u=>{await Promise.all(D.map(d=>d(u))),await u.exec(` | ||
| DROP VIEW IF EXISTS live_query_${o}_view; | ||
@@ -79,3 +79,3 @@ DROP TABLE IF EXISTS live_query_${o}_state1; | ||
| DEALLOCATE live_query_${o}_diff2; | ||
| `)}))};return y?.aborted?await N():y?.addEventListener("abort",()=>{N()},{once:!0}),await M(),{fields:m.fields.filter(f=>!["__after__","__op__","__changed_columns__"].includes(f.name)),initialChanges:m.rows,subscribe:$,unsubscribe:N,refresh:M}},async incrementalQuery(r,a,i,b){let y;if(typeof r!="string"&&(y=r.signal,a=r.params,i=r.key,b=r.callback,r=r.query),!i)throw new Error("key is required for incremental queries");let l=b?[b]:[],o=new Map,R=new Map,_=[],m=!0,{fields:D,unsubscribe:I,refresh:M}=await s.changes(r,a,i,B=>{for(let d of B){let{__op__:E,__changed_columns__:w,...h}=d;switch(E){case"RESET":o.clear(),R.clear();break;case"INSERT":o.set(h[i],h),R.set(h.__after__,h[i]);break;case"DELETE":{let p=o.get(h[i]);o.delete(h[i]),p.__after__!==null&&R.delete(p.__after__);break}case"UPDATE":{let p={...o.get(h[i])??{}};for(let P of w)p[P]=h[P],P==="__after__"&&R.set(h.__after__,h[i]);o.set(h[i],p);break}}}let f=[],u=null;for(let d=0;d<o.size;d++){let E=R.get(u),w=o.get(E);if(!w)break;let h={...w};delete h.__after__,f.push(h),u=E}_=f,m||Z(l,{rows:f,fields:D})});m=!1,Z(l,{rows:_,fields:D});let $=B=>{l.push(B)},N=async B=>{B?l=l.filter(f=>f!==f):l=[],l.length===0&&await I()};return y?.aborted?await N():y?.addEventListener("abort",()=>{N()},{once:!0}),{initialResults:{rows:_,fields:D},subscribe:$,unsubscribe:N,refresh:M}}};return{namespaceObj:s}},wt={name:"Live Queries",setup:Et};async function ge(e,t){return(await e.query(` | ||
| `)}))};return y?.aborted?await N():y?.addEventListener("abort",()=>{N()},{once:!0}),await M(),{fields:m.fields.filter(f=>!["__after__","__op__","__changed_columns__"].includes(f.name)),initialChanges:m.rows,subscribe:$,unsubscribe:N,refresh:M}},async incrementalQuery(r,a,i,b){let y;if(typeof r!="string"&&(y=r.signal,a=r.params,i=r.key,b=r.callback,r=r.query),!i)throw new Error("key is required for incremental queries");let l=b?[b]:[],o=new Map,S=new Map,_=[],m=!0,{fields:D,unsubscribe:I,refresh:M}=await s.changes(r,a,i,B=>{for(let d of B){let{__op__:E,__changed_columns__:w,...h}=d;switch(E){case"RESET":o.clear(),S.clear();break;case"INSERT":o.set(h[i],h),S.set(h.__after__,h[i]);break;case"DELETE":{let p=o.get(h[i]);o.delete(h[i]),p.__after__!==null&&S.delete(p.__after__);break}case"UPDATE":{let p={...o.get(h[i])??{}};for(let P of w)p[P]=h[P],P==="__after__"&&S.set(h.__after__,h[i]);o.set(h[i],p);break}}}let f=[],u=null;for(let d=0;d<o.size;d++){let E=S.get(u),w=o.get(E);if(!w)break;let h={...w};delete h.__after__,f.push(h),u=E}_=f,m||Z(l,{rows:f,fields:D})});m=!1,Z(l,{rows:_,fields:D});let $=B=>{l.push(B)},N=async B=>{B?l=l.filter(f=>f!==f):l=[],l.length===0&&await I()};return y?.aborted?await N():y?.addEventListener("abort",()=>{N()},{once:!0}),{initialResults:{rows:_,fields:D},subscribe:$,unsubscribe:N,refresh:M}}};return{namespaceObj:s}},wt={name:"Live Queries",setup:Et};async function be(e,t){return(await e.query(` | ||
| WITH RECURSIVE view_dependencies AS ( | ||
@@ -124,3 +124,3 @@ -- Base case: Get the initial view's dependencies | ||
| WHERE NOT is_view; -- Exclude intermediate views | ||
| `,[t])).rows.map(s=>({table_name:s.table_name,schema_name:s.schema_name,table_oid:s.table_oid,schema_oid:s.schema_oid}))}async function be(e,t,n){let s=t.filter(r=>!n.has(`${r.schema_oid}_${r.table_oid}`)).map(r=>` | ||
| `,[t])).rows.map(s=>({table_name:s.table_name,schema_name:s.schema_name,table_oid:s.table_oid,schema_oid:s.schema_oid}))}async function _e(e,t,n){let s=t.filter(r=>!n.has(`${r.schema_oid}_${r.table_oid}`)).map(r=>` | ||
| CREATE OR REPLACE FUNCTION "_notify_${r.schema_oid}_${r.table_oid}"() RETURNS TRIGGER AS $$ | ||
@@ -127,0 +127,0 @@ BEGIN |
@@ -1,2 +0,2 @@ | ||
| import{a as O,b as C}from"../chunk-WCYGQFD6.js";import"../chunk-ACJ7KGEC.js";import{a as I}from"../chunk-3KNDAXZT.js";import{j as P}from"../chunk-QY3QWFKW.js";P();var M=5,U=async(E,y)=>{let p=new Set,g={async query(e,$,a){let m,c,_;if(typeof e!="string"&&(m=e.signal,$=e.params,a=e.callback,c=e.offset,_=e.limit,e=e.query),c===void 0!=(_===void 0))throw new Error("offset and limit must be provided together");let t=c!==void 0&&_!==void 0,T;if(t&&(typeof c!="number"||isNaN(c)||typeof _!="number"||isNaN(_)))throw new Error("offset and limit must be numbers");let d=a?[a]:[],o=I.uuid().replace(/-/g,""),A=!1,v,w,S=async()=>{await E.transaction(async i=>{let n=$&&$.length>0?await O(E,e,$,i):e;await i.exec(`CREATE OR REPLACE TEMP VIEW live_query_${o}_view AS ${n}`);let u=await q(i,`live_query_${o}_view`);await F(i,u,p),t?(await i.exec(` | ||
| import{a as O,b as C}from"../chunk-WCYGQFD6.js";import"../chunk-ACJ7KGEC.js";import{a as I}from"../chunk-XP4OYHYJ.js";import{j as P}from"../chunk-QY3QWFKW.js";P();var M=5,U=async(E,y)=>{let p=new Set,g={async query(e,$,a){let m,c,_;if(typeof e!="string"&&(m=e.signal,$=e.params,a=e.callback,c=e.offset,_=e.limit,e=e.query),c===void 0!=(_===void 0))throw new Error("offset and limit must be provided together");let t=c!==void 0&&_!==void 0,T;if(t&&(typeof c!="number"||isNaN(c)||typeof _!="number"||isNaN(_)))throw new Error("offset and limit must be numbers");let d=a?[a]:[],o=I.uuid().replace(/-/g,""),A=!1,v,w,S=async()=>{await E.transaction(async i=>{let n=$&&$.length>0?await O(E,e,$,i):e;await i.exec(`CREATE OR REPLACE TEMP VIEW live_query_${o}_view AS ${n}`);let u=await q(i,`live_query_${o}_view`);await F(i,u,p),t?(await i.exec(` | ||
| PREPARE live_query_${o}_get(int, int) AS | ||
@@ -3,0 +3,0 @@ SELECT * FROM live_query_${o}_view |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/live/index.ts"],"sourcesContent":["import type {\n Extension,\n PGliteInterface,\n Results,\n Transaction,\n} from '../interface'\nimport type {\n LiveQueryOptions,\n LiveIncrementalQueryOptions,\n LiveChangesOptions,\n LiveNamespace,\n LiveQuery,\n LiveChanges,\n Change,\n LiveQueryResults,\n} from './interface'\nimport { formatQuery, debounceMutex } from '../utils.js'\nimport { pglUtils } from '@electric-sql/pglite-utils'\n\nexport type {\n LiveNamespace,\n LiveQuery,\n LiveChanges,\n Change,\n LiveQueryResults,\n} from './interface.js'\n\nconst MAX_RETRIES = 5\n\nconst setup = async (pg: PGliteInterface, _emscriptenOpts: any) => {\n // The notify triggers are only ever added and never removed\n // Keep track of which triggers have been added to avoid adding them multiple times\n const tableNotifyTriggersAdded = new Set<string>()\n\n const namespaceObj: LiveNamespace = {\n async query<T>(\n query: string | LiveQueryOptions<T>,\n params?: any[] | null,\n callback?: (results: Results<T>) => void,\n ) {\n let signal: AbortSignal | undefined\n let offset: number | undefined\n let limit: number | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n callback = query.callback\n offset = query.offset\n limit = query.limit\n query = query.query\n }\n\n // Offset and limit must be provided together\n if ((offset === undefined) !== (limit === undefined)) {\n throw new Error('offset and limit must be provided together')\n }\n\n const isWindowed = offset !== undefined && limit !== undefined\n let totalCount: number | undefined = undefined\n\n if (\n isWindowed &&\n (typeof offset !== 'number' ||\n isNaN(offset) ||\n typeof limit !== 'number' ||\n isNaN(limit))\n ) {\n throw new Error('offset and limit must be numbers')\n }\n\n let callbacks: Array<(results: Results<T>) => void> = callback\n ? [callback]\n : []\n const id = pglUtils.uuid().replace(/-/g, '')\n let dead = false\n\n let results: LiveQueryResults<T>\n\n let unsubList: Array<(tx?: Transaction) => Promise<void>>\n const init = async () => {\n await pg.transaction(async (tx) => {\n // Create a temporary view with the query\n const formattedQuery =\n params && params.length > 0\n ? await formatQuery(pg, query, params, tx)\n : query\n await tx.exec(\n `CREATE OR REPLACE TEMP VIEW live_query_${id}_view AS ${formattedQuery}`,\n )\n\n // Get the tables used in the view and add triggers to notify when they change\n const tables = await getTablesForView(tx, `live_query_${id}_view`)\n await addNotifyTriggersToTables(tx, tables, tableNotifyTriggersAdded)\n\n if (isWindowed) {\n await tx.exec(`\n PREPARE live_query_${id}_get(int, int) AS\n SELECT * FROM live_query_${id}_view\n LIMIT $1 OFFSET $2;\n `)\n await tx.exec(`\n PREPARE live_query_${id}_get_total_count AS\n SELECT COUNT(*) FROM live_query_${id}_view;\n `)\n totalCount = (\n await tx.query<{ count: number }>(\n `EXECUTE live_query_${id}_get_total_count;`,\n )\n ).rows[0].count\n results = {\n ...(await tx.query<T>(\n `EXECUTE live_query_${id}_get(${limit}, ${offset});`,\n )),\n offset,\n limit,\n totalCount,\n }\n } else {\n await tx.exec(`\n PREPARE live_query_${id}_get AS\n SELECT * FROM live_query_${id}_view;\n `)\n results = await tx.query<T>(`EXECUTE live_query_${id}_get;`)\n }\n // Setup the listeners\n unsubList = await Promise.all(\n tables!.map((table) =>\n tx.listen(\n `\"table_change__${table.schema_oid}__${table.table_oid}\"`,\n async () => {\n refresh()\n },\n ),\n ),\n )\n })\n }\n await init()\n\n // Function to refresh the query\n const refresh = debounceMutex(\n async ({\n offset: newOffset,\n limit: newLimit,\n }: {\n offset?: number\n limit?: number\n } = {}) => {\n // We can optionally provide new offset and limit values to refresh with\n if (\n !isWindowed &&\n (newOffset !== undefined || newLimit !== undefined)\n ) {\n throw new Error(\n 'offset and limit cannot be provided for non-windowed queries',\n )\n }\n if (\n (newOffset &&\n (typeof newOffset !== 'number' || isNaN(newOffset))) ||\n (newLimit && (typeof newLimit !== 'number' || isNaN(newLimit)))\n ) {\n throw new Error('offset and limit must be numbers')\n }\n offset = newOffset ?? offset\n limit = newLimit ?? limit\n\n const run = async (count = 0) => {\n if (callbacks.length === 0) {\n return\n }\n try {\n if (isWindowed) {\n // For a windowed query we defer the refresh of the total count until\n // after we have returned the results with the old total count. This\n // is due to a count(*) being a fairly slow query and we want to update\n // the rows on screen as quickly as possible.\n results = {\n ...(await pg.query<T>(\n `EXECUTE live_query_${id}_get(${limit}, ${offset});`,\n )),\n offset,\n limit,\n totalCount, // This is the old total count\n }\n } else {\n results = await pg.query<T>(`EXECUTE live_query_${id}_get;`)\n }\n } catch (e) {\n const msg = (e as Error).message\n if (\n msg.startsWith(`prepared statement \"live_query_${id}`) &&\n msg.endsWith('does not exist')\n ) {\n // If the prepared statement does not exist, reset and try again\n // This can happen if using the multi-tab worker\n if (count > MAX_RETRIES) {\n throw e\n }\n await init()\n run(count + 1)\n } else {\n throw e\n }\n }\n\n runResultCallbacks(callbacks, results)\n\n // Update the total count\n // If the total count has changed, refresh the query\n if (isWindowed) {\n const newTotalCount = (\n await pg.query<{ count: number }>(\n `EXECUTE live_query_${id}_get_total_count;`,\n )\n ).rows[0].count\n if (newTotalCount !== totalCount) {\n // The total count has changed, refresh the query\n totalCount = newTotalCount\n refresh()\n }\n }\n }\n await run()\n },\n )\n\n // Function to subscribe to the query\n const subscribe = (callback: (results: Results<T>) => void) => {\n if (dead) {\n throw new Error(\n 'Live query is no longer active and cannot be subscribed to',\n )\n }\n callbacks.push(callback)\n }\n\n // Function to unsubscribe from the query\n // If no function is provided, unsubscribe all callbacks\n // If there are no callbacks, unsubscribe from the notify triggers\n const unsubscribe = async (callback?: (results: Results<T>) => void) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0 && !dead) {\n dead = true\n await pg.transaction(async (tx) => {\n await Promise.all(unsubList.map((unsub) => unsub(tx)))\n await tx.exec(`\n DROP VIEW IF EXISTS live_query_${id}_view;\n DEALLOCATE live_query_${id}_get;\n `)\n })\n }\n }\n\n // If the signal has already been aborted, unsubscribe\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n // Add an event listener to unsubscribe if the signal is aborted\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n // Run the callback with the initial results\n runResultCallbacks(callbacks, results!)\n\n // Return the initial results\n return {\n initialResults: results!,\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveQuery<T>\n },\n\n async changes<T>(\n query: string | LiveChangesOptions<T>,\n params?: any[] | null,\n key?: string,\n callback?: (changes: Array<Change<T>>) => void,\n ) {\n let signal: AbortSignal | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n key = query.key\n callback = query.callback\n query = query.query\n }\n if (!key) {\n throw new Error('key is required for changes queries')\n }\n let callbacks: Array<(changes: Array<Change<T>>) => void> = callback\n ? [callback]\n : []\n const id = pglUtils.uuid().replace(/-/g, '')\n let dead = false\n\n let stateSwitch: 1 | 2 = 1\n let changes: Results<Change<T>>\n\n let unsubList: Array<(tx?: Transaction) => Promise<void>>\n\n const init = async () => {\n await pg.transaction(async (tx) => {\n // Create a temporary view with the query\n const formattedQuery = await formatQuery(pg, query, params, tx)\n await tx.query(\n `CREATE OR REPLACE TEMP VIEW live_query_${id}_view AS ${formattedQuery}`,\n )\n\n // Get the tables used in the view and add triggers to notify when they change\n const tables = await getTablesForView(tx, `live_query_${id}_view`)\n await addNotifyTriggersToTables(tx, tables, tableNotifyTriggersAdded)\n\n // Get the columns of the view\n const columns = [\n ...(\n await tx.query<any>(`\n SELECT column_name, data_type, udt_name\n FROM information_schema.columns \n WHERE table_name = 'live_query_${id}_view'\n `)\n ).rows,\n { column_name: '__after__', data_type: 'integer' },\n ]\n\n // Init state tables as empty temp table\n await tx.exec(`\n CREATE TEMP TABLE live_query_${id}_state1 (LIKE live_query_${id}_view INCLUDING ALL);\n CREATE TEMP TABLE live_query_${id}_state2 (LIKE live_query_${id}_view INCLUDING ALL);\n `)\n\n // Create Diff views and prepared statements\n for (const curr of [1, 2]) {\n const prev = curr === 1 ? 2 : 1\n await tx.exec(`\n PREPARE live_query_${id}_diff${curr} AS\n WITH\n prev AS (SELECT LAG(\"${key}\") OVER () as __after__, * FROM live_query_${id}_state${prev}),\n curr AS (SELECT LAG(\"${key}\") OVER () as __after__, * FROM live_query_${id}_state${curr}),\n data_diff AS (\n -- INSERT operations: Include all columns\n SELECT \n 'INSERT' AS __op__,\n ${columns\n .map(\n ({ column_name }) =>\n `curr.\"${column_name}\" AS \"${column_name}\"`,\n )\n .join(',\\n')},\n ARRAY[]::text[] AS __changed_columns__\n FROM curr\n LEFT JOIN prev ON curr.${key} = prev.${key}\n WHERE prev.${key} IS NULL\n UNION ALL\n -- DELETE operations: Include only the primary key\n SELECT \n 'DELETE' AS __op__,\n ${columns\n .map(({ column_name, data_type, udt_name }) => {\n if (column_name === key) {\n return `prev.\"${column_name}\" AS \"${column_name}\"`\n } else {\n return `NULL${data_type === 'USER-DEFINED' ? `::${udt_name}` : ``} AS \"${column_name}\"`\n }\n })\n .join(',\\n')},\n ARRAY[]::text[] AS __changed_columns__\n FROM prev\n LEFT JOIN curr ON prev.${key} = curr.${key}\n WHERE curr.${key} IS NULL\n UNION ALL\n -- UPDATE operations: Include only changed columns\n SELECT \n 'UPDATE' AS __op__,\n ${columns\n .map(({ column_name, data_type, udt_name }) =>\n column_name === key\n ? `curr.\"${column_name}\" AS \"${column_name}\"`\n : `CASE \n WHEN curr.\"${column_name}\" IS DISTINCT FROM prev.\"${column_name}\" \n THEN curr.\"${column_name}\"\n ELSE NULL${data_type === 'USER-DEFINED' ? `::${udt_name}` : ``}\n END AS \"${column_name}\"`,\n )\n .join(',\\n')},\n ARRAY(SELECT unnest FROM unnest(ARRAY[${columns\n .filter(({ column_name }) => column_name !== key)\n .map(\n ({ column_name }) =>\n `CASE\n WHEN curr.\"${column_name}\" IS DISTINCT FROM prev.\"${column_name}\" \n THEN '${column_name}' \n ELSE NULL \n END`,\n )\n .join(\n ', ',\n )}]) WHERE unnest IS NOT NULL) AS __changed_columns__\n FROM curr\n INNER JOIN prev ON curr.${key} = prev.${key}\n WHERE NOT (curr IS NOT DISTINCT FROM prev)\n )\n SELECT * FROM data_diff;\n `)\n }\n\n // Setup the listeners\n unsubList = await Promise.all(\n tables!.map((table) =>\n tx.listen(\n `\"table_change__${table.schema_oid}__${table.table_oid}\"`,\n async () => {\n refresh()\n },\n ),\n ),\n )\n })\n }\n\n await init()\n\n const refresh = debounceMutex(async () => {\n if (callbacks.length === 0 && changes) {\n return\n }\n let reset = false\n for (let i = 0; i < 5; i++) {\n try {\n await pg.transaction(async (tx) => {\n // Populate the state table\n await tx.exec(`\n INSERT INTO live_query_${id}_state${stateSwitch} \n SELECT * FROM live_query_${id}_view;\n `)\n\n // Get the changes\n changes = await tx.query<any>(\n `EXECUTE live_query_${id}_diff${stateSwitch};`,\n )\n\n // Switch state\n stateSwitch = stateSwitch === 1 ? 2 : 1\n\n // Truncate the old state table\n await tx.exec(`\n TRUNCATE live_query_${id}_state${stateSwitch};\n `)\n })\n break\n } catch (e) {\n const msg = (e as Error).message\n if (\n msg ===\n `relation \"live_query_${id}_state${stateSwitch}\" does not exist`\n ) {\n // If the state table does not exist, reset and try again\n // This can happen if using the multi-tab worker\n reset = true\n await init()\n continue\n } else {\n throw e\n }\n }\n }\n\n runChangeCallbacks(callbacks, [\n ...(reset\n ? [\n {\n __op__: 'RESET' as const,\n },\n ]\n : []),\n ...changes!.rows,\n ])\n })\n\n // Function to subscribe to the query\n const subscribe = (callback: (changes: Array<Change<T>>) => void) => {\n if (dead) {\n throw new Error(\n 'Live query is no longer active and cannot be subscribed to',\n )\n }\n callbacks.push(callback)\n }\n\n // Function to unsubscribe from the query\n const unsubscribe = async (\n callback?: (changes: Array<Change<T>>) => void,\n ) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0 && !dead) {\n dead = true\n await pg.transaction(async (tx) => {\n await Promise.all(unsubList.map((unsub) => unsub(tx)))\n await tx.exec(`\n DROP VIEW IF EXISTS live_query_${id}_view;\n DROP TABLE IF EXISTS live_query_${id}_state1;\n DROP TABLE IF EXISTS live_query_${id}_state2;\n DEALLOCATE live_query_${id}_diff1;\n DEALLOCATE live_query_${id}_diff2;\n `)\n })\n }\n }\n\n // If the signal has already been aborted, unsubscribe\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n // Add an event listener to unsubscribe if the signal is aborted\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n // Run the callback with the initial changes\n await refresh()\n\n // Fields\n const fields = changes!.fields.filter(\n (field) =>\n !['__after__', '__op__', '__changed_columns__'].includes(field.name),\n )\n\n // Return the initial results\n return {\n fields,\n initialChanges: changes!.rows,\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveChanges<T>\n },\n\n async incrementalQuery<T>(\n query: string | LiveIncrementalQueryOptions<T>,\n params?: any[] | null,\n key?: string,\n callback?: (results: Results<T>) => void,\n ) {\n let signal: AbortSignal | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n key = query.key\n callback = query.callback\n query = query.query\n }\n if (!key) {\n throw new Error('key is required for incremental queries')\n }\n let callbacks: Array<(results: Results<T>) => void> = callback\n ? [callback]\n : []\n const rowsMap: Map<any, any> = new Map()\n const afterMap: Map<any, any> = new Map()\n let lastRows: T[] = []\n let firstRun = true\n\n const {\n fields,\n unsubscribe: unsubscribeChanges,\n refresh,\n } = await namespaceObj.changes<T>(query, params, key, (changes) => {\n // Process the changes\n for (const change of changes) {\n const {\n __op__: op,\n __changed_columns__: changedColumns,\n ...obj\n } = change as typeof change & { [key: string]: any }\n switch (op) {\n case 'RESET':\n rowsMap.clear()\n afterMap.clear()\n break\n case 'INSERT':\n rowsMap.set(obj[key], obj)\n afterMap.set(obj.__after__, obj[key])\n break\n case 'DELETE': {\n const oldObj = rowsMap.get(obj[key])\n rowsMap.delete(obj[key])\n // null is the starting point, we don't delete it as another insert\n // may have happened thats replacing it\n if (oldObj.__after__ !== null) {\n afterMap.delete(oldObj.__after__)\n }\n break\n }\n case 'UPDATE': {\n const newObj = { ...(rowsMap.get(obj[key]) ?? {}) }\n for (const columnName of changedColumns) {\n newObj[columnName] = obj[columnName]\n if (columnName === '__after__') {\n afterMap.set(obj.__after__, obj[key])\n }\n }\n rowsMap.set(obj[key], newObj)\n break\n }\n }\n }\n\n // Get the rows in order\n const rows: T[] = []\n let lastKey: any = null\n for (let i = 0; i < rowsMap.size; i++) {\n const nextKey = afterMap.get(lastKey)\n const obj = rowsMap.get(nextKey)\n if (!obj) {\n break\n }\n // Remove the __after__ key from the exposed row\n const cleanObj = { ...obj }\n delete cleanObj.__after__\n rows.push(cleanObj)\n lastKey = nextKey\n }\n lastRows = rows\n\n // Run the callbacks\n if (!firstRun) {\n runResultCallbacks(callbacks, {\n rows,\n fields,\n })\n }\n })\n\n firstRun = false\n runResultCallbacks(callbacks, {\n rows: lastRows,\n fields,\n })\n\n const subscribe = (callback: (results: Results<T>) => void) => {\n callbacks.push(callback)\n }\n\n const unsubscribe = async (callback?: (results: Results<T>) => void) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0) {\n await unsubscribeChanges()\n }\n }\n\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n return {\n initialResults: {\n rows: lastRows,\n fields,\n },\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveQuery<T>\n },\n }\n\n return {\n namespaceObj,\n }\n}\n\nexport const live = {\n name: 'Live Queries',\n setup,\n} satisfies Extension\n\nexport type PGliteWithLive = PGliteInterface & {\n live: LiveNamespace\n}\n\n/**\n * Get a list of all the tables used in a view, recursively\n * @param tx a transaction or PGlite instance\n * @param viewName the name of the view\n * @returns list of tables used in the view\n */\nasync function getTablesForView(\n tx: Transaction | PGliteInterface,\n viewName: string,\n): Promise<\n {\n table_name: string\n schema_name: string\n table_oid: number\n schema_oid: number\n }[]\n> {\n const result = await tx.query<{\n table_name: string\n schema_name: string\n table_oid: number\n schema_oid: number\n }>(\n `\n WITH RECURSIVE view_dependencies AS (\n -- Base case: Get the initial view's dependencies\n SELECT DISTINCT\n cl.relname AS dependent_name,\n n.nspname AS schema_name,\n cl.oid AS dependent_oid,\n n.oid AS schema_oid,\n cl.relkind = 'v' AS is_view\n FROM pg_rewrite r\n JOIN pg_depend d ON r.oid = d.objid\n JOIN pg_class cl ON d.refobjid = cl.oid\n JOIN pg_namespace n ON cl.relnamespace = n.oid\n WHERE\n r.ev_class = (\n SELECT oid FROM pg_class WHERE relname = $1 AND relkind = 'v'\n )\n AND d.deptype = 'n'\n\n UNION ALL\n\n -- Recursive case: Traverse dependencies for views\n SELECT DISTINCT\n cl.relname AS dependent_name,\n n.nspname AS schema_name,\n cl.oid AS dependent_oid,\n n.oid AS schema_oid,\n cl.relkind = 'v' AS is_view\n FROM view_dependencies vd\n JOIN pg_rewrite r ON vd.dependent_name = (\n SELECT relname FROM pg_class WHERE oid = r.ev_class AND relkind = 'v'\n )\n JOIN pg_depend d ON r.oid = d.objid\n JOIN pg_class cl ON d.refobjid = cl.oid\n JOIN pg_namespace n ON cl.relnamespace = n.oid\n WHERE d.deptype = 'n'\n )\n SELECT DISTINCT\n dependent_name AS table_name,\n schema_name,\n dependent_oid AS table_oid,\n schema_oid\n FROM view_dependencies\n WHERE NOT is_view; -- Exclude intermediate views\n `,\n [viewName],\n )\n\n return result.rows.map((row) => ({\n table_name: row.table_name,\n schema_name: row.schema_name,\n table_oid: row.table_oid,\n schema_oid: row.schema_oid,\n }))\n}\n\n/**\n * Add triggers to tables to notify when they change\n * @param tx a transaction or PGlite instance\n * @param tables list of tables to add triggers to\n */\nasync function addNotifyTriggersToTables(\n tx: Transaction | PGliteInterface,\n tables: {\n table_name: string\n table_oid: number\n schema_name: string\n schema_oid: number\n }[],\n tableNotifyTriggersAdded: Set<string>,\n) {\n const triggers = tables\n .filter(\n (table) =>\n !tableNotifyTriggersAdded.has(`${table.schema_oid}_${table.table_oid}`),\n )\n .map((table) => {\n return `\n CREATE OR REPLACE FUNCTION \"_notify_${table.schema_oid}_${table.table_oid}\"() RETURNS TRIGGER AS $$\n BEGIN\n PERFORM pg_notify('table_change__${table.schema_oid}__${table.table_oid}', '');\n RETURN NULL;\n END;\n $$ LANGUAGE plpgsql;\n CREATE OR REPLACE TRIGGER \"_notify_trigger_${table.schema_oid}_${table.table_oid}\"\n AFTER INSERT OR UPDATE OR DELETE ON \"${table.schema_name}\".\"${table.table_name}\"\n FOR EACH STATEMENT EXECUTE FUNCTION \"_notify_${table.schema_oid}_${table.table_oid}\"();\n `\n })\n .join('\\n')\n if (triggers.trim() !== '') {\n await tx.exec(triggers)\n }\n tables.map((table) =>\n tableNotifyTriggersAdded.add(`${table.schema_oid}_${table.table_oid}`),\n )\n}\n\nconst runResultCallbacks = <T>(\n callbacks: Array<(results: Results<T>) => void>,\n results: Results<T>,\n) => {\n for (const callback of callbacks) {\n callback(results)\n }\n}\n\nconst runChangeCallbacks = <T>(\n callbacks: Array<(changes: Array<Change<T>>) => void>,\n changes: Array<Change<T>>,\n) => {\n for (const callback of callbacks) {\n callback(changes)\n }\n}\n"],"mappings":"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","names":["init_esm_shims","MAX_RETRIES","setup","pg","_emscriptenOpts","tableNotifyTriggersAdded","namespaceObj","query","params","callback","signal","offset","limit","isWindowed","totalCount","callbacks","id","f","dead","results","unsubList","init","tx","formattedQuery","formatQuery","tables","getTablesForView","addNotifyTriggersToTables","table","refresh","debounceMutex","newOffset","newLimit","run","count","e","msg","runResultCallbacks","newTotalCount","subscribe","unsubscribe","unsub","key","stateSwitch","changes","columns","curr","prev","column_name","data_type","udt_name","reset","runChangeCallbacks","field","rowsMap","afterMap","lastRows","firstRun","fields","unsubscribeChanges","change","op","changedColumns","obj","oldObj","newObj","columnName","rows","lastKey","i","nextKey","cleanObj","live","viewName","row","triggers"]} | ||
| {"version":3,"sources":["../../src/live/index.ts"],"sourcesContent":["import type {\n Extension,\n PGliteInterface,\n Results,\n Transaction,\n} from '../interface'\nimport type {\n LiveQueryOptions,\n LiveIncrementalQueryOptions,\n LiveChangesOptions,\n LiveNamespace,\n LiveQuery,\n LiveChanges,\n Change,\n LiveQueryResults,\n} from './interface'\nimport { formatQuery, debounceMutex } from '../utils.js'\nimport { pglUtils } from '@electric-sql/pglite-utils'\n\nexport type {\n LiveNamespace,\n LiveQuery,\n LiveChanges,\n Change,\n LiveQueryResults,\n} from './interface.js'\n\nconst MAX_RETRIES = 5\n\nconst setup = async (pg: PGliteInterface, _emscriptenOpts: any) => {\n // The notify triggers are only ever added and never removed\n // Keep track of which triggers have been added to avoid adding them multiple times\n const tableNotifyTriggersAdded = new Set<string>()\n\n const namespaceObj: LiveNamespace = {\n async query<T>(\n query: string | LiveQueryOptions<T>,\n params?: any[] | null,\n callback?: (results: Results<T>) => void,\n ) {\n let signal: AbortSignal | undefined\n let offset: number | undefined\n let limit: number | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n callback = query.callback\n offset = query.offset\n limit = query.limit\n query = query.query\n }\n\n // Offset and limit must be provided together\n if ((offset === undefined) !== (limit === undefined)) {\n throw new Error('offset and limit must be provided together')\n }\n\n const isWindowed = offset !== undefined && limit !== undefined\n let totalCount: number | undefined = undefined\n\n if (\n isWindowed &&\n (typeof offset !== 'number' ||\n isNaN(offset) ||\n typeof limit !== 'number' ||\n isNaN(limit))\n ) {\n throw new Error('offset and limit must be numbers')\n }\n\n let callbacks: Array<(results: Results<T>) => void> = callback\n ? [callback]\n : []\n const id = pglUtils.uuid().replace(/-/g, '')\n let dead = false\n\n let results: LiveQueryResults<T>\n\n let unsubList: Array<(tx?: Transaction) => Promise<void>>\n const init = async () => {\n await pg.transaction(async (tx) => {\n // Create a temporary view with the query\n const formattedQuery =\n params && params.length > 0\n ? await formatQuery(pg, query, params, tx)\n : query\n await tx.exec(\n `CREATE OR REPLACE TEMP VIEW live_query_${id}_view AS ${formattedQuery}`,\n )\n\n // Get the tables used in the view and add triggers to notify when they change\n const tables = await getTablesForView(tx, `live_query_${id}_view`)\n await addNotifyTriggersToTables(tx, tables, tableNotifyTriggersAdded)\n\n if (isWindowed) {\n await tx.exec(`\n PREPARE live_query_${id}_get(int, int) AS\n SELECT * FROM live_query_${id}_view\n LIMIT $1 OFFSET $2;\n `)\n await tx.exec(`\n PREPARE live_query_${id}_get_total_count AS\n SELECT COUNT(*) FROM live_query_${id}_view;\n `)\n totalCount = (\n await tx.query<{ count: number }>(\n `EXECUTE live_query_${id}_get_total_count;`,\n )\n ).rows[0].count\n results = {\n ...(await tx.query<T>(\n `EXECUTE live_query_${id}_get(${limit}, ${offset});`,\n )),\n offset,\n limit,\n totalCount,\n }\n } else {\n await tx.exec(`\n PREPARE live_query_${id}_get AS\n SELECT * FROM live_query_${id}_view;\n `)\n results = await tx.query<T>(`EXECUTE live_query_${id}_get;`)\n }\n // Setup the listeners\n unsubList = await Promise.all(\n tables!.map((table) =>\n tx.listen(\n `\"table_change__${table.schema_oid}__${table.table_oid}\"`,\n async () => {\n refresh()\n },\n ),\n ),\n )\n })\n }\n await init()\n\n // Function to refresh the query\n const refresh = debounceMutex(\n async ({\n offset: newOffset,\n limit: newLimit,\n }: {\n offset?: number\n limit?: number\n } = {}) => {\n // We can optionally provide new offset and limit values to refresh with\n if (\n !isWindowed &&\n (newOffset !== undefined || newLimit !== undefined)\n ) {\n throw new Error(\n 'offset and limit cannot be provided for non-windowed queries',\n )\n }\n if (\n (newOffset &&\n (typeof newOffset !== 'number' || isNaN(newOffset))) ||\n (newLimit && (typeof newLimit !== 'number' || isNaN(newLimit)))\n ) {\n throw new Error('offset and limit must be numbers')\n }\n offset = newOffset ?? offset\n limit = newLimit ?? limit\n\n const run = async (count = 0) => {\n if (callbacks.length === 0) {\n return\n }\n try {\n if (isWindowed) {\n // For a windowed query we defer the refresh of the total count until\n // after we have returned the results with the old total count. This\n // is due to a count(*) being a fairly slow query and we want to update\n // the rows on screen as quickly as possible.\n results = {\n ...(await pg.query<T>(\n `EXECUTE live_query_${id}_get(${limit}, ${offset});`,\n )),\n offset,\n limit,\n totalCount, // This is the old total count\n }\n } else {\n results = await pg.query<T>(`EXECUTE live_query_${id}_get;`)\n }\n } catch (e) {\n const msg = (e as Error).message\n if (\n msg.startsWith(`prepared statement \"live_query_${id}`) &&\n msg.endsWith('does not exist')\n ) {\n // If the prepared statement does not exist, reset and try again\n // This can happen if using the multi-tab worker\n if (count > MAX_RETRIES) {\n throw e\n }\n await init()\n run(count + 1)\n } else {\n throw e\n }\n }\n\n runResultCallbacks(callbacks, results)\n\n // Update the total count\n // If the total count has changed, refresh the query\n if (isWindowed) {\n const newTotalCount = (\n await pg.query<{ count: number }>(\n `EXECUTE live_query_${id}_get_total_count;`,\n )\n ).rows[0].count\n if (newTotalCount !== totalCount) {\n // The total count has changed, refresh the query\n totalCount = newTotalCount\n refresh()\n }\n }\n }\n await run()\n },\n )\n\n // Function to subscribe to the query\n const subscribe = (callback: (results: Results<T>) => void) => {\n if (dead) {\n throw new Error(\n 'Live query is no longer active and cannot be subscribed to',\n )\n }\n callbacks.push(callback)\n }\n\n // Function to unsubscribe from the query\n // If no function is provided, unsubscribe all callbacks\n // If there are no callbacks, unsubscribe from the notify triggers\n const unsubscribe = async (callback?: (results: Results<T>) => void) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0 && !dead) {\n dead = true\n await pg.transaction(async (tx) => {\n await Promise.all(unsubList.map((unsub) => unsub(tx)))\n await tx.exec(`\n DROP VIEW IF EXISTS live_query_${id}_view;\n DEALLOCATE live_query_${id}_get;\n `)\n })\n }\n }\n\n // If the signal has already been aborted, unsubscribe\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n // Add an event listener to unsubscribe if the signal is aborted\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n // Run the callback with the initial results\n runResultCallbacks(callbacks, results!)\n\n // Return the initial results\n return {\n initialResults: results!,\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveQuery<T>\n },\n\n async changes<T>(\n query: string | LiveChangesOptions<T>,\n params?: any[] | null,\n key?: string,\n callback?: (changes: Array<Change<T>>) => void,\n ) {\n let signal: AbortSignal | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n key = query.key\n callback = query.callback\n query = query.query\n }\n if (!key) {\n throw new Error('key is required for changes queries')\n }\n let callbacks: Array<(changes: Array<Change<T>>) => void> = callback\n ? [callback]\n : []\n const id = pglUtils.uuid().replace(/-/g, '')\n let dead = false\n\n let stateSwitch: 1 | 2 = 1\n let changes: Results<Change<T>>\n\n let unsubList: Array<(tx?: Transaction) => Promise<void>>\n\n const init = async () => {\n await pg.transaction(async (tx) => {\n // Create a temporary view with the query\n const formattedQuery = await formatQuery(pg, query, params, tx)\n await tx.query(\n `CREATE OR REPLACE TEMP VIEW live_query_${id}_view AS ${formattedQuery}`,\n )\n\n // Get the tables used in the view and add triggers to notify when they change\n const tables = await getTablesForView(tx, `live_query_${id}_view`)\n await addNotifyTriggersToTables(tx, tables, tableNotifyTriggersAdded)\n\n // Get the columns of the view\n const columns = [\n ...(\n await tx.query<any>(`\n SELECT column_name, data_type, udt_name\n FROM information_schema.columns \n WHERE table_name = 'live_query_${id}_view'\n `)\n ).rows,\n { column_name: '__after__', data_type: 'integer' },\n ]\n\n // Init state tables as empty temp table\n await tx.exec(`\n CREATE TEMP TABLE live_query_${id}_state1 (LIKE live_query_${id}_view INCLUDING ALL);\n CREATE TEMP TABLE live_query_${id}_state2 (LIKE live_query_${id}_view INCLUDING ALL);\n `)\n\n // Create Diff views and prepared statements\n for (const curr of [1, 2]) {\n const prev = curr === 1 ? 2 : 1\n await tx.exec(`\n PREPARE live_query_${id}_diff${curr} AS\n WITH\n prev AS (SELECT LAG(\"${key}\") OVER () as __after__, * FROM live_query_${id}_state${prev}),\n curr AS (SELECT LAG(\"${key}\") OVER () as __after__, * FROM live_query_${id}_state${curr}),\n data_diff AS (\n -- INSERT operations: Include all columns\n SELECT \n 'INSERT' AS __op__,\n ${columns\n .map(\n ({ column_name }) =>\n `curr.\"${column_name}\" AS \"${column_name}\"`,\n )\n .join(',\\n')},\n ARRAY[]::text[] AS __changed_columns__\n FROM curr\n LEFT JOIN prev ON curr.${key} = prev.${key}\n WHERE prev.${key} IS NULL\n UNION ALL\n -- DELETE operations: Include only the primary key\n SELECT \n 'DELETE' AS __op__,\n ${columns\n .map(({ column_name, data_type, udt_name }) => {\n if (column_name === key) {\n return `prev.\"${column_name}\" AS \"${column_name}\"`\n } else {\n return `NULL${data_type === 'USER-DEFINED' ? `::${udt_name}` : ``} AS \"${column_name}\"`\n }\n })\n .join(',\\n')},\n ARRAY[]::text[] AS __changed_columns__\n FROM prev\n LEFT JOIN curr ON prev.${key} = curr.${key}\n WHERE curr.${key} IS NULL\n UNION ALL\n -- UPDATE operations: Include only changed columns\n SELECT \n 'UPDATE' AS __op__,\n ${columns\n .map(({ column_name, data_type, udt_name }) =>\n column_name === key\n ? `curr.\"${column_name}\" AS \"${column_name}\"`\n : `CASE \n WHEN curr.\"${column_name}\" IS DISTINCT FROM prev.\"${column_name}\" \n THEN curr.\"${column_name}\"\n ELSE NULL${data_type === 'USER-DEFINED' ? `::${udt_name}` : ``}\n END AS \"${column_name}\"`,\n )\n .join(',\\n')},\n ARRAY(SELECT unnest FROM unnest(ARRAY[${columns\n .filter(({ column_name }) => column_name !== key)\n .map(\n ({ column_name }) =>\n `CASE\n WHEN curr.\"${column_name}\" IS DISTINCT FROM prev.\"${column_name}\" \n THEN '${column_name}' \n ELSE NULL \n END`,\n )\n .join(\n ', ',\n )}]) WHERE unnest IS NOT NULL) AS __changed_columns__\n FROM curr\n INNER JOIN prev ON curr.${key} = prev.${key}\n WHERE NOT (curr IS NOT DISTINCT FROM prev)\n )\n SELECT * FROM data_diff;\n `)\n }\n\n // Setup the listeners\n unsubList = await Promise.all(\n tables!.map((table) =>\n tx.listen(\n `\"table_change__${table.schema_oid}__${table.table_oid}\"`,\n async () => {\n refresh()\n },\n ),\n ),\n )\n })\n }\n\n await init()\n\n const refresh = debounceMutex(async () => {\n if (callbacks.length === 0 && changes) {\n return\n }\n let reset = false\n for (let i = 0; i < 5; i++) {\n try {\n await pg.transaction(async (tx) => {\n // Populate the state table\n await tx.exec(`\n INSERT INTO live_query_${id}_state${stateSwitch} \n SELECT * FROM live_query_${id}_view;\n `)\n\n // Get the changes\n changes = await tx.query<any>(\n `EXECUTE live_query_${id}_diff${stateSwitch};`,\n )\n\n // Switch state\n stateSwitch = stateSwitch === 1 ? 2 : 1\n\n // Truncate the old state table\n await tx.exec(`\n TRUNCATE live_query_${id}_state${stateSwitch};\n `)\n })\n break\n } catch (e) {\n const msg = (e as Error).message\n if (\n msg ===\n `relation \"live_query_${id}_state${stateSwitch}\" does not exist`\n ) {\n // If the state table does not exist, reset and try again\n // This can happen if using the multi-tab worker\n reset = true\n await init()\n continue\n } else {\n throw e\n }\n }\n }\n\n runChangeCallbacks(callbacks, [\n ...(reset\n ? [\n {\n __op__: 'RESET' as const,\n },\n ]\n : []),\n ...changes!.rows,\n ])\n })\n\n // Function to subscribe to the query\n const subscribe = (callback: (changes: Array<Change<T>>) => void) => {\n if (dead) {\n throw new Error(\n 'Live query is no longer active and cannot be subscribed to',\n )\n }\n callbacks.push(callback)\n }\n\n // Function to unsubscribe from the query\n const unsubscribe = async (\n callback?: (changes: Array<Change<T>>) => void,\n ) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0 && !dead) {\n dead = true\n await pg.transaction(async (tx) => {\n await Promise.all(unsubList.map((unsub) => unsub(tx)))\n await tx.exec(`\n DROP VIEW IF EXISTS live_query_${id}_view;\n DROP TABLE IF EXISTS live_query_${id}_state1;\n DROP TABLE IF EXISTS live_query_${id}_state2;\n DEALLOCATE live_query_${id}_diff1;\n DEALLOCATE live_query_${id}_diff2;\n `)\n })\n }\n }\n\n // If the signal has already been aborted, unsubscribe\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n // Add an event listener to unsubscribe if the signal is aborted\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n // Run the callback with the initial changes\n await refresh()\n\n // Fields\n const fields = changes!.fields.filter(\n (field) =>\n !['__after__', '__op__', '__changed_columns__'].includes(field.name),\n )\n\n // Return the initial results\n return {\n fields,\n initialChanges: changes!.rows,\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveChanges<T>\n },\n\n async incrementalQuery<T>(\n query: string | LiveIncrementalQueryOptions<T>,\n params?: any[] | null,\n key?: string,\n callback?: (results: Results<T>) => void,\n ) {\n let signal: AbortSignal | undefined\n if (typeof query !== 'string') {\n signal = query.signal\n params = query.params\n key = query.key\n callback = query.callback\n query = query.query\n }\n if (!key) {\n throw new Error('key is required for incremental queries')\n }\n let callbacks: Array<(results: Results<T>) => void> = callback\n ? [callback]\n : []\n const rowsMap: Map<any, any> = new Map()\n const afterMap: Map<any, any> = new Map()\n let lastRows: T[] = []\n let firstRun = true\n\n const {\n fields,\n unsubscribe: unsubscribeChanges,\n refresh,\n } = await namespaceObj.changes<T>(query, params, key, (changes) => {\n // Process the changes\n for (const change of changes) {\n const {\n __op__: op,\n __changed_columns__: changedColumns,\n ...obj\n } = change as typeof change & { [key: string]: any }\n switch (op) {\n case 'RESET':\n rowsMap.clear()\n afterMap.clear()\n break\n case 'INSERT':\n rowsMap.set(obj[key], obj)\n afterMap.set(obj.__after__, obj[key])\n break\n case 'DELETE': {\n const oldObj = rowsMap.get(obj[key])\n rowsMap.delete(obj[key])\n // null is the starting point, we don't delete it as another insert\n // may have happened thats replacing it\n if (oldObj.__after__ !== null) {\n afterMap.delete(oldObj.__after__)\n }\n break\n }\n case 'UPDATE': {\n const newObj = { ...(rowsMap.get(obj[key]) ?? {}) }\n for (const columnName of changedColumns) {\n newObj[columnName] = obj[columnName]\n if (columnName === '__after__') {\n afterMap.set(obj.__after__, obj[key])\n }\n }\n rowsMap.set(obj[key], newObj)\n break\n }\n }\n }\n\n // Get the rows in order\n const rows: T[] = []\n let lastKey: any = null\n for (let i = 0; i < rowsMap.size; i++) {\n const nextKey = afterMap.get(lastKey)\n const obj = rowsMap.get(nextKey)\n if (!obj) {\n break\n }\n // Remove the __after__ key from the exposed row\n const cleanObj = { ...obj }\n delete cleanObj.__after__\n rows.push(cleanObj)\n lastKey = nextKey\n }\n lastRows = rows\n\n // Run the callbacks\n if (!firstRun) {\n runResultCallbacks(callbacks, {\n rows,\n fields,\n })\n }\n })\n\n firstRun = false\n runResultCallbacks(callbacks, {\n rows: lastRows,\n fields,\n })\n\n const subscribe = (callback: (results: Results<T>) => void) => {\n callbacks.push(callback)\n }\n\n const unsubscribe = async (callback?: (results: Results<T>) => void) => {\n if (callback) {\n callbacks = callbacks.filter((callback) => callback !== callback)\n } else {\n callbacks = []\n }\n if (callbacks.length === 0) {\n await unsubscribeChanges()\n }\n }\n\n if (signal?.aborted) {\n await unsubscribe()\n } else {\n signal?.addEventListener(\n 'abort',\n () => {\n unsubscribe()\n },\n { once: true },\n )\n }\n\n return {\n initialResults: {\n rows: lastRows,\n fields,\n },\n subscribe,\n unsubscribe,\n refresh,\n } satisfies LiveQuery<T>\n },\n }\n\n return {\n namespaceObj,\n }\n}\n\nexport const live = {\n name: 'Live Queries',\n setup,\n} satisfies Extension\n\nexport type PGliteWithLive = PGliteInterface & {\n live: LiveNamespace\n}\n\n/**\n * Get a list of all the tables used in a view, recursively\n * @param tx a transaction or PGlite instance\n * @param viewName the name of the view\n * @returns list of tables used in the view\n */\nasync function getTablesForView(\n tx: Transaction | PGliteInterface,\n viewName: string,\n): Promise<\n {\n table_name: string\n schema_name: string\n table_oid: number\n schema_oid: number\n }[]\n> {\n const result = await tx.query<{\n table_name: string\n schema_name: string\n table_oid: number\n schema_oid: number\n }>(\n `\n WITH RECURSIVE view_dependencies AS (\n -- Base case: Get the initial view's dependencies\n SELECT DISTINCT\n cl.relname AS dependent_name,\n n.nspname AS schema_name,\n cl.oid AS dependent_oid,\n n.oid AS schema_oid,\n cl.relkind = 'v' AS is_view\n FROM pg_rewrite r\n JOIN pg_depend d ON r.oid = d.objid\n JOIN pg_class cl ON d.refobjid = cl.oid\n JOIN pg_namespace n ON cl.relnamespace = n.oid\n WHERE\n r.ev_class = (\n SELECT oid FROM pg_class WHERE relname = $1 AND relkind = 'v'\n )\n AND d.deptype = 'n'\n\n UNION ALL\n\n -- Recursive case: Traverse dependencies for views\n SELECT DISTINCT\n cl.relname AS dependent_name,\n n.nspname AS schema_name,\n cl.oid AS dependent_oid,\n n.oid AS schema_oid,\n cl.relkind = 'v' AS is_view\n FROM view_dependencies vd\n JOIN pg_rewrite r ON vd.dependent_name = (\n SELECT relname FROM pg_class WHERE oid = r.ev_class AND relkind = 'v'\n )\n JOIN pg_depend d ON r.oid = d.objid\n JOIN pg_class cl ON d.refobjid = cl.oid\n JOIN pg_namespace n ON cl.relnamespace = n.oid\n WHERE d.deptype = 'n'\n )\n SELECT DISTINCT\n dependent_name AS table_name,\n schema_name,\n dependent_oid AS table_oid,\n schema_oid\n FROM view_dependencies\n WHERE NOT is_view; -- Exclude intermediate views\n `,\n [viewName],\n )\n\n return result.rows.map((row) => ({\n table_name: row.table_name,\n schema_name: row.schema_name,\n table_oid: row.table_oid,\n schema_oid: row.schema_oid,\n }))\n}\n\n/**\n * Add triggers to tables to notify when they change\n * @param tx a transaction or PGlite instance\n * @param tables list of tables to add triggers to\n */\nasync function addNotifyTriggersToTables(\n tx: Transaction | PGliteInterface,\n tables: {\n table_name: string\n table_oid: number\n schema_name: string\n schema_oid: number\n }[],\n tableNotifyTriggersAdded: Set<string>,\n) {\n const triggers = tables\n .filter(\n (table) =>\n !tableNotifyTriggersAdded.has(`${table.schema_oid}_${table.table_oid}`),\n )\n .map((table) => {\n return `\n CREATE OR REPLACE FUNCTION \"_notify_${table.schema_oid}_${table.table_oid}\"() RETURNS TRIGGER AS $$\n BEGIN\n PERFORM pg_notify('table_change__${table.schema_oid}__${table.table_oid}', '');\n RETURN NULL;\n END;\n $$ LANGUAGE plpgsql;\n CREATE OR REPLACE TRIGGER \"_notify_trigger_${table.schema_oid}_${table.table_oid}\"\n AFTER INSERT OR UPDATE OR DELETE ON \"${table.schema_name}\".\"${table.table_name}\"\n FOR EACH STATEMENT EXECUTE FUNCTION \"_notify_${table.schema_oid}_${table.table_oid}\"();\n `\n })\n .join('\\n')\n if (triggers.trim() !== '') {\n await tx.exec(triggers)\n }\n tables.map((table) =>\n tableNotifyTriggersAdded.add(`${table.schema_oid}_${table.table_oid}`),\n )\n}\n\nconst runResultCallbacks = <T>(\n callbacks: Array<(results: Results<T>) => void>,\n results: Results<T>,\n) => {\n for (const callback of callbacks) {\n callback(results)\n }\n}\n\nconst runChangeCallbacks = <T>(\n callbacks: Array<(changes: Array<Change<T>>) => void>,\n changes: Array<Change<T>>,\n) => {\n for (const callback of callbacks) {\n callback(changes)\n }\n}\n"],"mappings":"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","names":["init_esm_shims","MAX_RETRIES","setup","pg","_emscriptenOpts","tableNotifyTriggersAdded","namespaceObj","query","params","callback","signal","offset","limit","isWindowed","totalCount","callbacks","id","l","dead","results","unsubList","init","tx","formattedQuery","formatQuery","tables","getTablesForView","addNotifyTriggersToTables","table","refresh","debounceMutex","newOffset","newLimit","run","count","e","msg","runResultCallbacks","newTotalCount","subscribe","unsubscribe","unsub","key","stateSwitch","changes","columns","curr","prev","column_name","data_type","udt_name","reset","runChangeCallbacks","field","rowsMap","afterMap","lastRows","firstRun","fields","unsubscribeChanges","change","op","changedColumns","obj","oldObj","newObj","columnName","rows","lastKey","i","nextKey","cleanObj","live","viewName","row","triggers"]} |
@@ -1,2 +0,2 @@ | ||
| "use strict";var He=Object.create;var ne=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Ke=Object.getOwnPropertyNames;var Je=Object.getPrototypeOf,Xe=Object.prototype.hasOwnProperty;var ke=e=>{throw TypeError(e)};var Ze=(e,t)=>{for(var r in t)ne(e,r,{get:t[r],enumerable:!0})},Ie=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ke(t))!Xe.call(e,a)&&a!==r&&ne(e,a,{get:()=>t[a],enumerable:!(n=Ye(t,a))||n.enumerable});return e};var Le=(e,t,r)=>(r=e!=null?He(Je(e)):{},Ie(t||!e||!e.__esModule?ne(r,"default",{value:e,enumerable:!0}):r,e)),et=e=>Ie(ne({},"__esModule",{value:!0}),e);var fe=(e,t,r)=>t.has(e)||ke("Cannot "+r);var i=(e,t,r)=>(fe(e,t,"read from private field"),r?r.call(e):t.get(e)),p=(e,t,r)=>t.has(e)?ke("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),d=(e,t,r,n)=>(fe(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),c=(e,t,r)=>(fe(e,t,"access private method"),r);var ge=(e,t,r,n)=>({set _(a){d(e,t,a,r)},get _(){return i(e,t,n)}});var nr={};Ze(nr,{LeaderChangedError:()=>me,PGliteWorker:()=>Se,worker:()=>er});module.exports=et(nr);var tt=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,P=tt();var Ce={part:"part",container:"container"};function se(e,t,...r){let n=e.length-1,a=r.length-1;if(a!==-1){if(a===0){e[n]=e[n]+r[0]+t;return}e[n]=e[n]+r[0],e.push(...r.slice(1,a)),e.push(r[a]+t)}}function rt(e,...t){let r=[e[0]];r.raw=[e.raw[0]];let n=[];for(let a=0;a<t.length;a++){let s=t[a],o=a+1;if(s?._templateType===Ce.part){se(r,e[o],s.str),se(r.raw,e.raw[o],s.str);continue}if(s?._templateType===Ce.container){se(r,e[o],...s.strings),se(r.raw,e.raw[o],...s.strings.raw),n.push(...s.values);continue}r.push(e[o]),r.raw.push(e.raw[o]),n.push(s)}return{_templateType:"container",strings:r,values:n}}function be(e,...t){let{strings:r,values:n}=rt(e,...t);return{query:[r[0],...n.flatMap((a,s)=>[`$${s+1}`,r[s+1]])].join(""),params:n}}var nt=globalThis.JSON.parse,st=globalThis.JSON.stringify,Oe=16,ve=17;var Ue=20,at=21,it=23;var Ne=25,ot=26;var _e=114;var ct=700,lt=701;var ut=1042,pt=1043,dt=1082;var yt=1114,We=1184;var mt=3802;var ht={string:{to:Ne,from:[Ne,pt,ut],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return e.toString();throw new Error("Invalid input for string type")},parse:e=>e},number:{to:0,from:[at,it,ot,ct,lt],serialize:e=>e.toString(),parse:e=>+e},bigint:{to:Ue,from:[Ue],serialize:e=>e.toString(),parse:e=>{let t=BigInt(e);return t<Number.MIN_SAFE_INTEGER||t>Number.MAX_SAFE_INTEGER?t:Number(t)}},json:{to:_e,from:[_e,mt],serialize:e=>typeof e=="string"?e:st(e),parse:e=>nt(e)},boolean:{to:Oe,from:[Oe],serialize:e=>{if(typeof e!="boolean")throw new Error("Invalid input for boolean type");return e?"t":"f"},parse:e=>e==="t"},date:{to:We,from:[dt,yt,We],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return new Date(e).toISOString();if(e instanceof Date)return e.toISOString();throw new Error("Invalid input for date type")},parse:e=>new Date(e)},bytea:{to:ve,from:[ve],serialize:e=>{if(!(e instanceof Uint8Array))throw new Error("Invalid input for bytea type");return"\\x"+Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")},parse:e=>{let t=e.slice(2);return Uint8Array.from({length:t.length/2},(r,n)=>parseInt(t.substring(n*2,(n+1)*2),16))}}},Pe=ft(ht),Ge=Pe.parsers,Fe=Pe.serializers;function xe(e,t,r){if(e===null)return null;let n=r?.[t]??Pe.parsers[t];return n?n(e,t):e}function ft(e){return Object.keys(e).reduce(({parsers:t,serializers:r},n)=>{let{to:a,from:s,serialize:o,parse:u}=e[n];return r[a]=o,r[n]=o,t[n]=u,Array.isArray(s)?s.forEach(l=>{t[l]=u,r[l]=o}):(t[s]=u,r[s]=o),{parsers:t,serializers:r}},{parsers:{},serializers:{}})}var gt=/\\/g,bt=/"/g;function wt(e){return e.replace(gt,"\\\\").replace(bt,'\\"')}function Te(e,t,r){if(Array.isArray(e)===!1)return e;if(!e.length)return"{}";let n=e[0],a=r===1020?";":",";return Array.isArray(n)?`{${e.map(s=>Te(s,t,r)).join(a)}}`:`{${e.map(s=>(s===void 0&&(s=null),s===null?"null":'"'+wt(t?t(s):s.toString())+'"')).join(a)}}`}var we={i:0,char:null,str:"",quoted:!1,last:0,p:null};function Ve(e,t,r){return we.i=we.last=0,Qe(we,e,t,r)[0]}function Qe(e,t,r,n){let a=[],s=n===1020?";":",";for(;e.i<t.length;e.i++){if(e.char=t[e.i],e.quoted)e.char==="\\"?e.str+=t[++e.i]:e.char==='"'?(a.push(r?r(e.str):e.str),e.str="",e.quoted=t[e.i+1]==='"',e.last=e.i+2):e.str+=e.char;else if(e.char==='"')e.quoted=!0;else if(e.char==="{")e.last=++e.i,a.push(Qe(e,t,r,n));else if(e.char==="}"){e.quoted=!1,e.last<e.i&&a.push(r?r(t.slice(e.last,e.i)):t.slice(e.last,e.i)),e.last=e.i+1;break}else e.char===s&&e.p!=="}"&&e.p!=='"'&&(a.push(r?r(t.slice(e.last,e.i)):t.slice(e.last,e.i)),e.last=e.i+1);e.p=e.char}return e.last<e.i&&a.push(r?r(t.slice(e.last,e.i+1)):t.slice(e.last,e.i+1)),a}function Ae(e,t,r,n){let a=[],s={rows:[],fields:[]},o=0,u={...t,...r?.parsers};return e.forEach(l=>{switch(l.name){case"rowDescription":{let m=l;s.fields=m.fields.map(y=>({name:y.name,dataTypeID:y.dataTypeID}));break}case"dataRow":{if(!s)break;let m=l;r?.rowMode==="array"?s.rows.push(m.fields.map((y,T)=>xe(y,s.fields[T].dataTypeID,u))):s.rows.push(Object.fromEntries(m.fields.map((y,T)=>[s.fields[T].name,xe(y,s.fields[T].dataTypeID,u)])));break}case"commandComplete":{o+=Pt(l),a.push({...s,affectedRows:o,...n?{blob:n}:{}}),s={rows:[],fields:[]};break}}}),a.length===0&&a.push({affectedRows:0,rows:[],fields:[]}),a}function Pt(e){let t=e.text.split(" ");switch(t[0]){case"INSERT":return parseInt(t[2],10);case"UPDATE":case"DELETE":case"COPY":case"MERGE":return parseInt(t[1],10);default:return 0}}function qe(e){let t=e.find(r=>r.name==="parameterDescription");return t?t.dataTypeIDs:[]}function W(e){let t=e.length;for(let r=e.length-1;r>=0;r--){let n=e.charCodeAt(r);n>127&&n<=2047?t++:n>2047&&n<=65535&&(t+=2),n>=56320&&n<=57343&&r--}return t}var b,w,F,ie,V,A,ae,G,ze,L=class{constructor(t=256){this.size=t;p(this,A);p(this,b);p(this,w,5);p(this,F,!1);p(this,ie,new TextEncoder);p(this,V,0);d(this,b,c(this,A,ae).call(this,t))}addInt32(t){return c(this,A,G).call(this,4),i(this,b).setInt32(i(this,w),t,i(this,F)),d(this,w,i(this,w)+4),this}addInt16(t){return c(this,A,G).call(this,2),i(this,b).setInt16(i(this,w),t,i(this,F)),d(this,w,i(this,w)+2),this}addCString(t){return t&&this.addString(t),c(this,A,G).call(this,1),i(this,b).setUint8(i(this,w),0),ge(this,w)._++,this}addString(t=""){let r=W(t);return c(this,A,G).call(this,r),i(this,ie).encodeInto(t,new Uint8Array(i(this,b).buffer,i(this,w))),d(this,w,i(this,w)+r),this}add(t){return c(this,A,G).call(this,t.byteLength),new Uint8Array(i(this,b).buffer).set(new Uint8Array(t),i(this,w)),d(this,w,i(this,w)+t.byteLength),this}flush(t){let r=c(this,A,ze).call(this,t);return d(this,w,5),d(this,b,c(this,A,ae).call(this,this.size)),new Uint8Array(r)}};b=new WeakMap,w=new WeakMap,F=new WeakMap,ie=new WeakMap,V=new WeakMap,A=new WeakSet,ae=function(t){return new DataView(new ArrayBuffer(t))},G=function(t){if(i(this,b).byteLength-i(this,w)<t){let n=i(this,b).buffer,a=n.byteLength+(n.byteLength>>1)+t;d(this,b,c(this,A,ae).call(this,a)),new Uint8Array(i(this,b).buffer).set(new Uint8Array(n))}},ze=function(t){if(t){i(this,b).setUint8(i(this,V),t);let r=i(this,w)-(i(this,V)+1);i(this,b).setInt32(i(this,V)+1,r,i(this,F))}return i(this,b).buffer.slice(t?0:5,i(this,w))};var g=new L,xt=e=>{g.addInt16(3).addInt16(0);for(let n of Object.keys(e))g.addCString(n).addCString(e[n]);g.addCString("client_encoding").addCString("UTF8");let t=g.addCString("").flush(),r=t.byteLength+4;return new L().addInt32(r).add(t).flush()},Tt=()=>{let e=new DataView(new ArrayBuffer(8));return e.setInt32(0,8,!1),e.setInt32(4,80877103,!1),new Uint8Array(e.buffer)},At=e=>g.addCString(e).flush(112),Et=(e,t)=>(g.addCString(e).addInt32(W(t)).addString(t),g.flush(112)),Rt=e=>g.addString(e).flush(112),St=e=>g.addCString(e).flush(81),Bt=[],Dt=e=>{let t=e.name??"";t.length>63&&(console.error("Warning! Postgres only supports 63 characters for query names."),console.error("You supplied %s (%s)",t,t.length),console.error("This can cause conflicts and silent errors executing queries"));let r=g.addCString(t).addCString(e.text).addInt16(e.types?.length??0);return e.types?.forEach(n=>r.addInt32(n)),g.flush(80)},Q=new L;var Mt=(e,t)=>{for(let r=0;r<e.length;r++){let n=t?t(e[r],r):e[r];if(n===null)g.addInt16(0),Q.addInt32(-1);else if(n instanceof ArrayBuffer||ArrayBuffer.isView(n)){let a=ArrayBuffer.isView(n)?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):n;g.addInt16(1),Q.addInt32(a.byteLength),Q.add(a)}else g.addInt16(0),Q.addInt32(W(n)),Q.addString(n)}},kt=(e={})=>{let t=e.portal??"",r=e.statement??"",n=e.binary??!1,a=e.values??Bt,s=a.length;return g.addCString(t).addCString(r),g.addInt16(s),Mt(a,e.valueMapper),g.addInt16(s),g.add(Q.flush()),g.addInt16(n?1:0),g.flush(66)},It=new Uint8Array([69,0,0,0,9,0,0,0,0,0]),Lt=e=>{if(!e||!e.portal&&!e.rows)return It;let t=e.portal??"",r=e.rows??0,n=W(t),a=4+n+1+4,s=new DataView(new ArrayBuffer(1+a));return s.setUint8(0,69),s.setInt32(1,a,!1),new TextEncoder().encodeInto(t,new Uint8Array(s.buffer,5)),s.setUint8(n+5,0),s.setUint32(s.byteLength-4,r,!1),new Uint8Array(s.buffer)},Ct=(e,t)=>{let r=new DataView(new ArrayBuffer(16));return r.setInt32(0,16,!1),r.setInt16(4,1234,!1),r.setInt16(6,5678,!1),r.setInt32(8,e,!1),r.setInt32(12,t,!1),new Uint8Array(r.buffer)},Ee=(e,t)=>{let r=new L;return r.addCString(t),r.flush(e)},Ot=g.addCString("P").flush(68),vt=g.addCString("S").flush(68),Ut=e=>e.name?Ee(68,`${e.type}${e.name??""}`):e.type==="P"?Ot:vt,Nt=e=>{let t=`${e.type}${e.name??""}`;return Ee(67,t)},_t=e=>g.add(e).flush(100),Wt=e=>Ee(102,e),oe=e=>new Uint8Array([e,0,0,0,4]),Gt=oe(72),Ft=oe(83),Vt=oe(88),Qt=oe(99),R={startup:xt,password:At,requestSsl:Tt,sendSASLInitialResponseMessage:Et,sendSCRAMClientFinalMessage:Rt,query:St,parse:Dt,bind:kt,execute:Lt,describe:Ut,close:Nt,flush:()=>Gt,sync:()=>Ft,end:()=>Vt,copyData:_t,copyDone:()=>Qt,copyFail:Wt,cancel:Ct};var C=class extends Error{constructor(r,n,a){super(r);this.length=n;this.name=a}};var Sr=new ArrayBuffer(0);var zt=1,jt=4,dn=zt+jt,yn=new ArrayBuffer(0);function ce(e){let t=e.e;return t.query=e.query,t.params=e.params,t.queryOptions=e.options,t}var j,I,h,S,le,O,Re,ue=class{constructor(){p(this,h);this.serializers={...Fe};this.parsers={...Ge};p(this,j,!1);p(this,I,!1)}async _initArrayTypes({force:t=!1}={}){if(i(this,j)&&!t)return;d(this,j,!0);let r=await this.query(` | ||
| "use strict";var Ye=Object.create;var ne=Object.defineProperty;var Ke=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ze=Object.prototype.hasOwnProperty;var Ie=e=>{throw TypeError(e)};var et=(e,t)=>{for(var r in t)ne(e,r,{get:t[r],enumerable:!0})},Le=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Je(t))!Ze.call(e,a)&&a!==r&&ne(e,a,{get:()=>t[a],enumerable:!(n=Ke(t,a))||n.enumerable});return e};var Ce=(e,t,r)=>(r=e!=null?Ye(Xe(e)):{},Le(t||!e||!e.__esModule?ne(r,"default",{value:e,enumerable:!0}):r,e)),tt=e=>Le(ne({},"__esModule",{value:!0}),e);var fe=(e,t,r)=>t.has(e)||Ie("Cannot "+r);var i=(e,t,r)=>(fe(e,t,"read from private field"),r?r.call(e):t.get(e)),p=(e,t,r)=>t.has(e)?Ie("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),d=(e,t,r,n)=>(fe(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),c=(e,t,r)=>(fe(e,t,"access private method"),r);var ge=(e,t,r,n)=>({set _(a){d(e,t,a,r)},get _(){return i(e,t,n)}});var nr={};et(nr,{LeaderChangedError:()=>me,PGliteWorker:()=>Be,worker:()=>er});module.exports=tt(nr);var rt=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,P=rt();var Oe={part:"part",container:"container"};function se(e,t,...r){let n=e.length-1,a=r.length-1;if(a!==-1){if(a===0){e[n]=e[n]+r[0]+t;return}e[n]=e[n]+r[0],e.push(...r.slice(1,a)),e.push(r[a]+t)}}function nt(e,...t){let r=[e[0]];r.raw=[e.raw[0]];let n=[];for(let a=0;a<t.length;a++){let s=t[a],o=a+1;if(s?._templateType===Oe.part){se(r,e[o],s.str),se(r.raw,e.raw[o],s.str);continue}if(s?._templateType===Oe.container){se(r,e[o],...s.strings),se(r.raw,e.raw[o],...s.strings.raw),n.push(...s.values);continue}r.push(e[o]),r.raw.push(e.raw[o]),n.push(s)}return{_templateType:"container",strings:r,values:n}}function be(e,...t){let{strings:r,values:n}=nt(e,...t);return{query:[r[0],...n.flatMap((a,s)=>[`$${s+1}`,r[s+1]])].join(""),params:n}}var st=globalThis.JSON.parse,at=globalThis.JSON.stringify,ve=16,Ue=17;var Ne=20,it=21,ot=23;var _e=25,ct=26;var We=114;var lt=700,ut=701;var pt=1042,dt=1043,yt=1082;var mt=1114,Ge=1184;var ht=3802;var ft={string:{to:_e,from:[_e,dt,pt],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return e.toString();throw new Error("Invalid input for string type")},parse:e=>e},number:{to:0,from:[it,ot,ct,lt,ut],serialize:e=>e.toString(),parse:e=>+e},bigint:{to:Ne,from:[Ne],serialize:e=>e.toString(),parse:e=>{let t=BigInt(e);return t<Number.MIN_SAFE_INTEGER||t>Number.MAX_SAFE_INTEGER?t:Number(t)}},json:{to:We,from:[We,ht],serialize:e=>typeof e=="string"?e:at(e),parse:e=>st(e)},boolean:{to:ve,from:[ve],serialize:e=>{if(typeof e!="boolean")throw new Error("Invalid input for boolean type");return e?"t":"f"},parse:e=>e==="t"},date:{to:Ge,from:[yt,mt,Ge],serialize:e=>{if(typeof e=="string")return e;if(typeof e=="number")return new Date(e).toISOString();if(e instanceof Date)return e.toISOString();throw new Error("Invalid input for date type")},parse:e=>new Date(e)},bytea:{to:Ue,from:[Ue],serialize:e=>{if(!(e instanceof Uint8Array))throw new Error("Invalid input for bytea type");return"\\x"+Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")},parse:e=>{let t=e.slice(2);return Uint8Array.from({length:t.length/2},(r,n)=>parseInt(t.substring(n*2,(n+1)*2),16))}}},Pe=gt(ft),Fe=Pe.parsers,Ve=Pe.serializers;function xe(e,t,r){if(e===null)return null;let n=r?.[t]??Pe.parsers[t];return n?n(e,t):e}function gt(e){return Object.keys(e).reduce(({parsers:t,serializers:r},n)=>{let{to:a,from:s,serialize:o,parse:u}=e[n];return r[a]=o,r[n]=o,t[n]=u,Array.isArray(s)?s.forEach(l=>{t[l]=u,r[l]=o}):(t[s]=u,r[s]=o),{parsers:t,serializers:r}},{parsers:{},serializers:{}})}var bt=/\\/g,wt=/"/g;function Pt(e){return e.replace(bt,"\\\\").replace(wt,'\\"')}function Te(e,t,r){if(Array.isArray(e)===!1)return e;if(!e.length)return"{}";let n=e[0],a=r===1020?";":",";return Array.isArray(n)?`{${e.map(s=>Te(s,t,r)).join(a)}}`:`{${e.map(s=>(s===void 0&&(s=null),s===null?"null":'"'+Pt(t?t(s):s.toString())+'"')).join(a)}}`}var we={i:0,char:null,str:"",quoted:!1,last:0,p:null};function Qe(e,t,r){return we.i=we.last=0,qe(we,e,t,r)[0]}function qe(e,t,r,n){let a=[],s=n===1020?";":",";for(;e.i<t.length;e.i++){if(e.char=t[e.i],e.quoted)e.char==="\\"?e.str+=t[++e.i]:e.char==='"'?(a.push(r?r(e.str):e.str),e.str="",e.quoted=t[e.i+1]==='"',e.last=e.i+2):e.str+=e.char;else if(e.char==='"')e.quoted=!0;else if(e.char==="{")e.last=++e.i,a.push(qe(e,t,r,n));else if(e.char==="}"){e.quoted=!1,e.last<e.i&&a.push(r?r(t.slice(e.last,e.i)):t.slice(e.last,e.i)),e.last=e.i+1;break}else e.char===s&&e.p!=="}"&&e.p!=='"'&&(a.push(r?r(t.slice(e.last,e.i)):t.slice(e.last,e.i)),e.last=e.i+1);e.p=e.char}return e.last<e.i&&a.push(r?r(t.slice(e.last,e.i+1)):t.slice(e.last,e.i+1)),a}function Ae(e,t,r,n){let a=[],s={rows:[],fields:[]},o=0,u={...t,...r?.parsers};return e.forEach(l=>{switch(l.name){case"rowDescription":{let m=l;s.fields=m.fields.map(y=>({name:y.name,dataTypeID:y.dataTypeID}));break}case"dataRow":{if(!s)break;let m=l;r?.rowMode==="array"?s.rows.push(m.fields.map((y,T)=>xe(y,s.fields[T].dataTypeID,u))):s.rows.push(Object.fromEntries(m.fields.map((y,T)=>[s.fields[T].name,xe(y,s.fields[T].dataTypeID,u)])));break}case"commandComplete":{o+=xt(l),a.push({...s,affectedRows:o,...n?{blob:n}:{}}),s={rows:[],fields:[]};break}}}),a.length===0&&a.push({affectedRows:0,rows:[],fields:[]}),a}function xt(e){let t=e.text.split(" ");switch(t[0]){case"INSERT":return parseInt(t[2],10);case"UPDATE":case"DELETE":case"COPY":case"MERGE":return parseInt(t[1],10);default:return 0}}function ze(e){let t=e.find(r=>r.name==="parameterDescription");return t?t.dataTypeIDs:[]}function W(e){let t=e.length;for(let r=e.length-1;r>=0;r--){let n=e.charCodeAt(r);n>127&&n<=2047?t++:n>2047&&n<=65535&&(t+=2),n>=56320&&n<=57343&&r--}return t}var b,w,F,ie,V,A,ae,G,je,L=class{constructor(t=256){this.size=t;p(this,A);p(this,b);p(this,w,5);p(this,F,!1);p(this,ie,new TextEncoder);p(this,V,0);d(this,b,c(this,A,ae).call(this,t))}addInt32(t){return c(this,A,G).call(this,4),i(this,b).setInt32(i(this,w),t,i(this,F)),d(this,w,i(this,w)+4),this}addInt16(t){return c(this,A,G).call(this,2),i(this,b).setInt16(i(this,w),t,i(this,F)),d(this,w,i(this,w)+2),this}addCString(t){return t&&this.addString(t),c(this,A,G).call(this,1),i(this,b).setUint8(i(this,w),0),ge(this,w)._++,this}addString(t=""){let r=W(t);return c(this,A,G).call(this,r),i(this,ie).encodeInto(t,new Uint8Array(i(this,b).buffer,i(this,w))),d(this,w,i(this,w)+r),this}add(t){return c(this,A,G).call(this,t.byteLength),new Uint8Array(i(this,b).buffer).set(new Uint8Array(t),i(this,w)),d(this,w,i(this,w)+t.byteLength),this}flush(t){let r=c(this,A,je).call(this,t);return d(this,w,5),d(this,b,c(this,A,ae).call(this,this.size)),new Uint8Array(r)}};b=new WeakMap,w=new WeakMap,F=new WeakMap,ie=new WeakMap,V=new WeakMap,A=new WeakSet,ae=function(t){return new DataView(new ArrayBuffer(t))},G=function(t){if(i(this,b).byteLength-i(this,w)<t){let n=i(this,b).buffer,a=n.byteLength+(n.byteLength>>1)+t;d(this,b,c(this,A,ae).call(this,a)),new Uint8Array(i(this,b).buffer).set(new Uint8Array(n))}},je=function(t){if(t){i(this,b).setUint8(i(this,V),t);let r=i(this,w)-(i(this,V)+1);i(this,b).setInt32(i(this,V)+1,r,i(this,F))}return i(this,b).buffer.slice(t?0:5,i(this,w))};var g=new L,Tt=e=>{g.addInt16(3).addInt16(0);for(let n of Object.keys(e))g.addCString(n).addCString(e[n]);g.addCString("client_encoding").addCString("UTF8");let t=g.addCString("").flush(),r=t.byteLength+4;return new L().addInt32(r).add(t).flush()},At=()=>{let e=new DataView(new ArrayBuffer(8));return e.setInt32(0,8,!1),e.setInt32(4,80877103,!1),new Uint8Array(e.buffer)},Et=e=>g.addCString(e).flush(112),Rt=(e,t)=>(g.addCString(e).addInt32(W(t)).addString(t),g.flush(112)),St=e=>g.addString(e).flush(112),Bt=e=>g.addCString(e).flush(81),Dt=[],Mt=e=>{let t=e.name??"";t.length>63&&(console.error("Warning! Postgres only supports 63 characters for query names."),console.error("You supplied %s (%s)",t,t.length),console.error("This can cause conflicts and silent errors executing queries"));let r=g.addCString(t).addCString(e.text).addInt16(e.types?.length??0);return e.types?.forEach(n=>r.addInt32(n)),g.flush(80)},Q=new L;var kt=(e,t)=>{for(let r=0;r<e.length;r++){let n=t?t(e[r],r):e[r];if(n===null)g.addInt16(0),Q.addInt32(-1);else if(n instanceof ArrayBuffer||ArrayBuffer.isView(n)){let a=ArrayBuffer.isView(n)?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):n;g.addInt16(1),Q.addInt32(a.byteLength),Q.add(a)}else g.addInt16(0),Q.addInt32(W(n)),Q.addString(n)}},It=(e={})=>{let t=e.portal??"",r=e.statement??"",n=e.binary??!1,a=e.values??Dt,s=a.length;return g.addCString(t).addCString(r),g.addInt16(s),kt(a,e.valueMapper),g.addInt16(s),g.add(Q.flush()),g.addInt16(n?1:0),g.flush(66)},Lt=new Uint8Array([69,0,0,0,9,0,0,0,0,0]),Ct=e=>{if(!e||!e.portal&&!e.rows)return Lt;let t=e.portal??"",r=e.rows??0,n=W(t),a=4+n+1+4,s=new DataView(new ArrayBuffer(1+a));return s.setUint8(0,69),s.setInt32(1,a,!1),new TextEncoder().encodeInto(t,new Uint8Array(s.buffer,5)),s.setUint8(n+5,0),s.setUint32(s.byteLength-4,r,!1),new Uint8Array(s.buffer)},Ot=(e,t)=>{let r=new DataView(new ArrayBuffer(16));return r.setInt32(0,16,!1),r.setInt16(4,1234,!1),r.setInt16(6,5678,!1),r.setInt32(8,e,!1),r.setInt32(12,t,!1),new Uint8Array(r.buffer)},Ee=(e,t)=>{let r=new L;return r.addCString(t),r.flush(e)},vt=g.addCString("P").flush(68),Ut=g.addCString("S").flush(68),Nt=e=>e.name?Ee(68,`${e.type}${e.name??""}`):e.type==="P"?vt:Ut,_t=e=>{let t=`${e.type}${e.name??""}`;return Ee(67,t)},Wt=e=>g.add(e).flush(100),Gt=e=>Ee(102,e),oe=e=>new Uint8Array([e,0,0,0,4]),Ft=oe(72),Vt=oe(83),Qt=oe(88),qt=oe(99),R={startup:Tt,password:Et,requestSsl:At,sendSASLInitialResponseMessage:Rt,sendSCRAMClientFinalMessage:St,query:Bt,parse:Mt,bind:It,execute:Ct,describe:Nt,close:_t,flush:()=>Ft,sync:()=>Vt,end:()=>Qt,copyData:Wt,copyDone:()=>qt,copyFail:Gt,cancel:Ot};var C=class extends Error{constructor(r,n,a){super(r);this.length=n;this.name=a}};var Sr=new ArrayBuffer(0);var jt=1,$t=4,dn=jt+$t,yn=new ArrayBuffer(0);function ce(e){let t=e.e;return t.query=e.query,t.params=e.params,t.queryOptions=e.options,t}var j,I,h,S,le,O,Re,ue=class{constructor(){p(this,h);this.serializers={...Ve};this.parsers={...Fe};p(this,j,!1);p(this,I,!1)}async _initArrayTypes({force:t=!1}={}){if(i(this,j)&&!t)return;d(this,j,!0);let r=await this.query(` | ||
| SELECT b.oid, b.typarray | ||
@@ -8,3 +8,3 @@ FROM pg_catalog.pg_type a | ||
| ORDER BY b.oid | ||
| `);for(let n of r.rows)this.serializers[n.typarray]=a=>Te(a,this.serializers[n.oid],n.typarray),this.parsers[n.typarray]=a=>Ve(a,this.parsers[n.oid],n.typarray)}async refreshArrayTypes(){await this._initArrayTypes({force:!0})}async query(t,r,n){return await this._checkReady(),await this._runExclusiveTransaction(async()=>await c(this,h,le).call(this,t,r,n))}async sql(t,...r){let{query:n,params:a}=be(t,...r);return await this.query(n,a)}async exec(t,r){return await this._checkReady(),await this._runExclusiveTransaction(async()=>await c(this,h,O).call(this,t,r))}async describeQuery(t,r){let n=[];try{await c(this,h,S).call(this,R.parse({text:t,types:r?.paramTypes}),r),n=await c(this,h,S).call(this,R.describe({type:"S"}),r)}catch(l){throw l instanceof C?ce({e:l,options:r,params:void 0,query:t}):l}finally{n.push(...await c(this,h,S).call(this,R.sync(),r))}let a=n.find(l=>l.name==="parameterDescription"),s=n.find(l=>l.name==="rowDescription"),o=a?.dataTypeIDs.map(l=>({dataTypeID:l,serializer:this.serializers[l]}))??[],u=s?.fields.map(l=>({name:l.name,dataTypeID:l.dataTypeID,parser:this.parsers[l.dataTypeID]}))??[];return{queryParams:o,resultFields:u}}async transaction(t){return await this._checkReady(),await this._runExclusiveTransaction(async()=>{await c(this,h,O).call(this,"BEGIN"),d(this,I,!0);let r=!1,n=()=>{if(r)throw new Error("Transaction is closed")},a={query:async(s,o,u)=>(n(),await c(this,h,le).call(this,s,o,u)),sql:async(s,...o)=>{let{query:u,params:l}=be(s,...o);return await c(this,h,le).call(this,u,l)},exec:async(s,o)=>(n(),await c(this,h,O).call(this,s,o)),rollback:async()=>{n(),await c(this,h,O).call(this,"ROLLBACK"),r=!0},listen:async(s,o)=>(n(),await this.listen(s,o,a)),get closed(){return r}};try{let s=await t(a);return r||(r=!0,await c(this,h,O).call(this,"COMMIT")),d(this,I,!1),s}catch(s){throw r||await c(this,h,O).call(this,"ROLLBACK"),d(this,I,!1),s}})}async runExclusive(t){return await this._runExclusiveQuery(t)}};j=new WeakMap,I=new WeakMap,h=new WeakSet,S=async function(t,r={}){return await this.execProtocolStream(t,{...r,syncToFs:!1})},le=async function(t,r=[],n){return await this._runExclusiveQuery(async()=>{c(this,h,Re).call(this,"runQuery",t,r,n),await this._handleBlob(n?.blob);let a=[];try{let o=await c(this,h,S).call(this,R.parse({text:t,types:n?.paramTypes}),n),u=qe(await c(this,h,S).call(this,R.describe({type:"S"}),n)),l=r.map((m,y)=>{let T=u[y];if(m==null)return null;let E=n?.serializers?.[T]??this.serializers[T];return E?E(m):m.toString()});a=[...o,...await c(this,h,S).call(this,R.bind({values:l}),n),...await c(this,h,S).call(this,R.describe({type:"P"}),n),...await c(this,h,S).call(this,R.execute({}),n)]}catch(o){throw o instanceof C?ce({e:o,options:n,params:r,query:t}):o}finally{a.push(...await c(this,h,S).call(this,R.sync(),n))}await this._cleanupBlob(),i(this,I)||await this.syncToFs();let s=await this._getWrittenBlob();return Ae(a,this.parsers,n,s)[0]})},O=async function(t,r){return await this._runExclusiveQuery(async()=>{c(this,h,Re).call(this,"runExec",t,r),await this._handleBlob(r?.blob);let n=[];try{n=await c(this,h,S).call(this,R.query(t),r)}catch(s){throw s instanceof C?ce({e:s,options:r,params:void 0,query:t}):s}finally{n.push(...await c(this,h,S).call(this,R.sync(),r))}this._cleanupBlob(),i(this,I)||await this.syncToFs();let a=await this._getWrittenBlob();return Ae(n,this.parsers,r,a)})},Re=function(...t){this.debug>0&&console.log(...t)};var $t=Object.defineProperty,Ht=(e,t)=>{for(var r in t)$t(e,r,{get:t[r],enumerable:!0})},H={};Ht(H,{IN_NODE:()=>de,getFsBundle:()=>Jt,instantiateWasm:()=>Kt,startWasmDownload:()=>Yt,toPostgresName:()=>Zt,uuid:()=>Xt});var de=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",$=new Map;async function Yt(e){de||$.has(e)||$.set(e,fetch(e))}var pe=new Map;async function Kt(e,t,r){if(r||pe.has(t)){let n=r||pe.get(t);return{instance:await WebAssembly.instantiate(n,e),module:n}}if(de){let n=await(await import("fs/promises")).readFile(t),{module:a,instance:s}=await WebAssembly.instantiate(n,e);return pe.set(t,a),{instance:s,module:a}}else{$.has(t)||$.set(t,fetch(t));let n=await $.get(t),{module:a,instance:s}=await WebAssembly.instantiateStreaming(n,e);return pe.set(t,a),{instance:s,module:a}}}async function Jt(e){return de?(await(await import("fs/promises")).readFile(e)).buffer:(await fetch(e)).arrayBuffer()}var Xt=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let e=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(e);else for(let r=0;r<e.length;r++)e[r]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[];return e.forEach(r=>{t.push(r.toString(16).padStart(2,"0"))}),t.slice(0,4).join("")+"-"+t.slice(4,6).join("")+"-"+t.slice(6,8).join("")+"-"+t.slice(8,10).join("")+"-"+t.slice(10).join("")};function Zt(e){let t;return e.startsWith('"')&&e.endsWith('"')?t=e.substring(1,e.length-1):t=e.toLowerCase(),t}var q,Y,K,z,J,B,v,U,D,X,Z,ee,N,k,te,M,_,re,he,f,je,ye,x,$e,De=class De extends ue{constructor(r,n){super();p(this,f);p(this,q);p(this,Y,0);p(this,K,!1);p(this,z,!1);p(this,J,!1);p(this,B,new EventTarget);p(this,v);p(this,U,!1);p(this,D);p(this,X);p(this,Z);p(this,ee);p(this,N);p(this,k);p(this,te);p(this,M,new Map);p(this,_,new Set);p(this,re);p(this,he,[]);d(this,D,r),d(this,v,H.uuid()),d(this,re,n?.extensions??{}),d(this,Z,new Promise(a=>{i(this,D).addEventListener("message",s=>{if(s.data.type==="here")a();else throw new Error("Invalid message")},{once:!0})})),d(this,ee,new Promise(a=>{let s=o=>{o.data.type==="ready"&&(d(this,X,o.data.id),i(this,D).removeEventListener("message",s),a())};i(this,D).addEventListener("message",s)})),d(this,q,c(this,f,je).call(this,n))}static async create(r,n){let a=new De(r,n);return await i(a,q),a}get waitReady(){return new Promise(r=>{i(this,q).then(()=>{i(this,U)?r():r(new Promise(n=>{i(this,B).addEventListener("connected",()=>{n()})}))})})}get debug(){return i(this,Y)}get ready(){return i(this,K)}get closed(){return i(this,z)}get isLeader(){return i(this,J)}async close(){var r;i(this,z)||(d(this,z,!0),i(this,N)?.close(),i(this,k)?.close(),(r=i(this,te))==null||r.call(this),i(this,D).terminate())}async[Symbol.asyncDispose](){await this.close()}async execProtocolRaw(r){return await c(this,f,x).call(this,"execProtocolRaw",r)}async execProtocol(r){return await c(this,f,x).call(this,"execProtocol",r)}async execProtocolStream(r){return await c(this,f,x).call(this,"execProtocolStream",r)}async execProtocolRawStream(r,n){await c(this,f,x).call(this,"execProtocolRawStream",r,n)}async syncToFs(){await c(this,f,x).call(this,"syncToFs")}async listen(r,n,a){let s=H.toPostgresName(r),o=a??this;return i(this,M).has(s)||i(this,M).set(s,new Set),i(this,M).get(s).add(n),await o.exec(`LISTEN ${r}`),async u=>{await this.unlisten(s,n,u)}}async unlisten(r,n,a){await this.waitReady;let s=a??this;n?i(this,M).get(r)?.delete(n):i(this,M).delete(r),i(this,M).get(r)?.size===0&&await s.exec(`UNLISTEN ${r}`)}onNotification(r){return i(this,_).add(r),()=>{i(this,_).delete(r)}}offNotification(r){i(this,_).delete(r)}async dumpDataDir(r){return await c(this,f,x).call(this,"dumpDataDir",r)}onLeaderChange(r){return i(this,B).addEventListener("leader-change",r),()=>{i(this,B).removeEventListener("leader-change",r)}}offLeaderChange(r){i(this,B).removeEventListener("leader-change",r)}async _handleBlob(r){await c(this,f,x).call(this,"_handleBlob",r)}async _getWrittenBlob(){return await c(this,f,x).call(this,"_getWrittenBlob")}async _cleanupBlob(){await c(this,f,x).call(this,"_cleanupBlob")}async _checkReady(){await this.waitReady}async _runExclusiveQuery(r){await c(this,f,x).call(this,"_acquireQueryLock");try{return await r()}finally{await c(this,f,x).call(this,"_releaseQueryLock")}}async _runExclusiveTransaction(r){await c(this,f,x).call(this,"_acquireTransactionLock");try{return await r()}finally{await c(this,f,x).call(this,"_releaseTransactionLock")}}};q=new WeakMap,Y=new WeakMap,K=new WeakMap,z=new WeakMap,J=new WeakMap,B=new WeakMap,v=new WeakMap,U=new WeakMap,D=new WeakMap,X=new WeakMap,Z=new WeakMap,ee=new WeakMap,N=new WeakMap,k=new WeakMap,te=new WeakMap,M=new WeakMap,_=new WeakMap,re=new WeakMap,he=new WeakMap,f=new WeakSet,je=async function(r={}){for(let[l,m]of Object.entries(i(this,re))){if(m instanceof URL)throw new Error("URL extensions are not supported on the client side of a worker");{let y=await m.setup(this,{},!0);if(y.emscriptenOpts&&console.warn(`PGlite extension ${l} returned emscriptenOpts, these are not supported on the client side of a worker`),y.namespaceObj){let T=this;T[l]=y.namespaceObj}y.bundlePath&&console.warn(`PGlite extension ${l} returned bundlePath, this is not supported on the client side of a worker`),y.init&&await y.init(),y.close&&i(this,he).push(y.close)}}await i(this,Z);let{extensions:n,...a}=r;i(this,D).postMessage({type:"init",options:a}),await i(this,ee);let s=`pglite-tab-close:${i(this,v)}`;d(this,te,await Be(s));let o=`pglite-broadcast:${i(this,X)}`;d(this,N,new BroadcastChannel(o));let u=`pglite-tab:${i(this,v)}`;d(this,k,new BroadcastChannel(u)),i(this,N).addEventListener("message",async l=>{l.data.type==="leader-here"?(d(this,U,!1),i(this,B).dispatchEvent(new Event("leader-change")),c(this,f,ye).call(this)):l.data.type==="notify"&&c(this,f,$e).call(this,l.data.channel,l.data.payload)}),i(this,k).addEventListener("message",async l=>{l.data.type==="connected"&&(d(this,U,!0),i(this,B).dispatchEvent(new Event("connected")),d(this,Y,await c(this,f,x).call(this,"getDebugLevel")),d(this,K,!0))}),i(this,D).addEventListener("message",async l=>{l.data.type==="leader-now"&&(d(this,J,!0),i(this,B).dispatchEvent(new Event("leader-change")))}),c(this,f,ye).call(this),this._initArrayTypes()},ye=async function(){i(this,U)||(i(this,N).postMessage({type:"tab-here",id:i(this,v)}),setTimeout(()=>c(this,f,ye).call(this),16))},x=async function(r,...n){let a=H.uuid(),s={type:"rpc-call",callId:a,method:r,args:n};return i(this,k).postMessage(s),await new Promise((o,u)=>{let l=T=>{if(T.data.callId!==a)return;y();let E=T.data;if(E.type==="rpc-return")o(E.result);else if(E.type==="rpc-error"){let Me=new Error(E.error.message);Object.assign(Me,E.error),u(Me)}else u(new Error("Invalid message"))},m=()=>{y(),u(new me)},y=()=>{i(this,k).removeEventListener("message",l),i(this,B).removeEventListener("leader-change",m)};i(this,B).addEventListener("leader-change",m),i(this,k).addEventListener("message",l)})},$e=function(r,n){let a=i(this,M).get(r);if(a)for(let s of a)queueMicrotask(()=>s(n));for(let s of i(this,_))queueMicrotask(()=>s(r,n))};var Se=De;async function er({init:e}){postMessage({type:"here"});let t=await new Promise(m=>{addEventListener("message",y=>{y.data.type==="init"&&m(y.data.options)},{once:!0})}),r=t.id??`${P}:${t.dataDir??""}`;postMessage({type:"ready",id:r});let n=`pglite-election-lock:${r}`,a=`pglite-broadcast:${r}`,s=new BroadcastChannel(a),o=new Set;await Be(n);let u=e(t);s.onmessage=async m=>{let y=m.data;switch(y.type){case"tab-here":tr(y.id,await u,o);break}},s.postMessage({type:"leader-here",id:r}),postMessage({type:"leader-now"}),(await u).onNotification((m,y)=>{s.postMessage({type:"notify",channel:m,payload:y})})}function tr(e,t,r){if(r.has(e))return;r.add(e);let n=`pglite-tab:${e}`,a=`pglite-tab-close:${e}`,s=new BroadcastChannel(n);navigator.locks.request(a,()=>new Promise(u=>{s.close(),r.delete(e),u()}));let o=rr(e,t);s.addEventListener("message",async u=>{let l=u.data;switch(l.type){case"rpc-call":{await t.waitReady;let{callId:m,method:y,args:T}=l;try{let E=await o[y](...T);s.postMessage({type:"rpc-return",callId:m,result:E})}catch(E){console.error(E),s.postMessage({type:"rpc-error",callId:m,error:{message:E.message}})}break}}}),s.postMessage({type:"connected"})}function rr(e,t){let r=null,n=null,a=`pglite-tab-close:${e}`;return Be(a).then(()=>{n&&t.exec("ROLLBACK"),r?.(),n?.()}),{async getDebugLevel(){return t.debug},async close(){await t.close()},async execProtocol(s){let{messages:o,data:u}=await t.execProtocol(s);if(u.byteLength!==u.buffer.byteLength){let l=new ArrayBuffer(u.byteLength),m=new Uint8Array(l);return m.set(u),{messages:o,data:m}}else return{messages:o,data:u}},async execProtocolStream(s){return await t.execProtocolStream(s)},async execProtocolRawStream(s,o){return await t.execProtocolRawStream(s,o)},async execProtocolRaw(s){let o=await t.execProtocolRaw(s);if(o.byteLength!==o.buffer.byteLength){let u=new ArrayBuffer(o.byteLength),l=new Uint8Array(u);return l.set(o),l}else return o},async dumpDataDir(s){return await t.dumpDataDir(s)},async syncToFs(){return await t.syncToFs()},async _handleBlob(s){return await t._handleBlob(s)},async _getWrittenBlob(){return await t._getWrittenBlob()},async _cleanupBlob(){return await t._cleanupBlob()},async _checkReady(){return await t._checkReady()},async _acquireQueryLock(){return new Promise(s=>{t._runExclusiveQuery(()=>new Promise(o=>{r=o,s()}))})},async _releaseQueryLock(){r?.(),r=null},async _acquireTransactionLock(){return new Promise(s=>{t._runExclusiveTransaction(()=>new Promise(o=>{n=o,s()}))})},async _releaseTransactionLock(){n?.(),n=null}}}var me=class extends Error{constructor(){super("Leader changed, pending operation in indeterminate state")}};async function Be(e){let t;return await new Promise(r=>{navigator.locks.request(e,()=>new Promise(n=>{t=n,r()}))}),t}0&&(module.exports={LeaderChangedError,PGliteWorker,worker}); | ||
| `);for(let n of r.rows)this.serializers[n.typarray]=a=>Te(a,this.serializers[n.oid],n.typarray),this.parsers[n.typarray]=a=>Qe(a,this.parsers[n.oid],n.typarray)}async refreshArrayTypes(){await this._initArrayTypes({force:!0})}async query(t,r,n){return await this._checkReady(),await this._runExclusiveTransaction(async()=>await c(this,h,le).call(this,t,r,n))}async sql(t,...r){let{query:n,params:a}=be(t,...r);return await this.query(n,a)}async exec(t,r){return await this._checkReady(),await this._runExclusiveTransaction(async()=>await c(this,h,O).call(this,t,r))}async describeQuery(t,r){let n=[];try{await c(this,h,S).call(this,R.parse({text:t,types:r?.paramTypes}),r),n=await c(this,h,S).call(this,R.describe({type:"S"}),r)}catch(l){throw l instanceof C?ce({e:l,options:r,params:void 0,query:t}):l}finally{n.push(...await c(this,h,S).call(this,R.sync(),r))}let a=n.find(l=>l.name==="parameterDescription"),s=n.find(l=>l.name==="rowDescription"),o=a?.dataTypeIDs.map(l=>({dataTypeID:l,serializer:this.serializers[l]}))??[],u=s?.fields.map(l=>({name:l.name,dataTypeID:l.dataTypeID,parser:this.parsers[l.dataTypeID]}))??[];return{queryParams:o,resultFields:u}}async transaction(t){return await this._checkReady(),await this._runExclusiveTransaction(async()=>{await c(this,h,O).call(this,"BEGIN"),d(this,I,!0);let r=!1,n=()=>{if(r)throw new Error("Transaction is closed")},a={query:async(s,o,u)=>(n(),await c(this,h,le).call(this,s,o,u)),sql:async(s,...o)=>{let{query:u,params:l}=be(s,...o);return await c(this,h,le).call(this,u,l)},exec:async(s,o)=>(n(),await c(this,h,O).call(this,s,o)),rollback:async()=>{n(),await c(this,h,O).call(this,"ROLLBACK"),r=!0},listen:async(s,o)=>(n(),await this.listen(s,o,a)),get closed(){return r}};try{let s=await t(a);return r||(r=!0,await c(this,h,O).call(this,"COMMIT")),d(this,I,!1),s}catch(s){throw r||await c(this,h,O).call(this,"ROLLBACK"),d(this,I,!1),s}})}async runExclusive(t){return await this._runExclusiveQuery(t)}};j=new WeakMap,I=new WeakMap,h=new WeakSet,S=async function(t,r={}){return await this.execProtocolStream(t,{...r,syncToFs:!1})},le=async function(t,r=[],n){return await this._runExclusiveQuery(async()=>{c(this,h,Re).call(this,"runQuery",t,r,n),await this._handleBlob(n?.blob);let a=[];try{let o=await c(this,h,S).call(this,R.parse({text:t,types:n?.paramTypes}),n),u=ze(await c(this,h,S).call(this,R.describe({type:"S"}),n)),l=r.map((m,y)=>{let T=u[y];if(m==null)return null;let E=n?.serializers?.[T]??this.serializers[T];return E?E(m):m.toString()});a=[...o,...await c(this,h,S).call(this,R.bind({values:l}),n),...await c(this,h,S).call(this,R.describe({type:"P"}),n),...await c(this,h,S).call(this,R.execute({}),n)]}catch(o){throw o instanceof C?ce({e:o,options:n,params:r,query:t}):o}finally{a.push(...await c(this,h,S).call(this,R.sync(),n))}await this._cleanupBlob(),i(this,I)||await this.syncToFs();let s=await this._getWrittenBlob();return Ae(a,this.parsers,n,s)[0]})},O=async function(t,r){return await this._runExclusiveQuery(async()=>{c(this,h,Re).call(this,"runExec",t,r),await this._handleBlob(r?.blob);let n=[];try{n=await c(this,h,S).call(this,R.query(t),r)}catch(s){throw s instanceof C?ce({e:s,options:r,params:void 0,query:t}):s}finally{n.push(...await c(this,h,S).call(this,R.sync(),r))}this._cleanupBlob(),i(this,I)||await this.syncToFs();let a=await this._getWrittenBlob();return Ae(n,this.parsers,r,a)})},Re=function(...t){this.debug>0&&console.log(...t)};var Ht=Object.defineProperty,Yt=(e,t)=>{for(var r in t)Ht(e,r,{get:t[r],enumerable:!0})},H={};Yt(H,{IN_NODE:()=>de,getFsBundle:()=>Jt,instantiateWasm:()=>Kt,startArtifactDownload:()=>Se,toPostgresName:()=>Zt,uuid:()=>Xt});var de=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",$=new Map;async function Se(e){de||$.has(e.toString())||$.set(e.toString(),fetch(e))}var pe=new Map;async function Kt(e,t,r){if(r||pe.has(t.toString())){let n=r||pe.get(t.toString());return{instance:await WebAssembly.instantiate(n,e),module:n}}if(de){let n=await(await import("fs/promises")).readFile(t),{module:a,instance:s}=await WebAssembly.instantiate(n,e);return pe.set(t.toString(),a),{instance:s,module:a}}else{$.has(t.toString())||Se(t);let n=await $.get(t.toString()),{module:a,instance:s}=await WebAssembly.instantiateStreaming(n.clone(),e);return pe.set(t.toString(),a),{instance:s,module:a}}}async function Jt(e){return de?(await(await import("fs/promises")).readFile(e)).buffer:(Se(e),(await $.get(e.toString())).clone().arrayBuffer())}var Xt=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let e=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(e);else for(let r=0;r<e.length;r++)e[r]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[];return e.forEach(r=>{t.push(r.toString(16).padStart(2,"0"))}),t.slice(0,4).join("")+"-"+t.slice(4,6).join("")+"-"+t.slice(6,8).join("")+"-"+t.slice(8,10).join("")+"-"+t.slice(10).join("")};function Zt(e){let t;return e.startsWith('"')&&e.endsWith('"')?t=e.substring(1,e.length-1):t=e.toLowerCase(),t}var q,Y,K,z,J,B,v,U,D,X,Z,ee,N,k,te,M,_,re,he,f,$e,ye,x,He,Me=class Me extends ue{constructor(r,n){super();p(this,f);p(this,q);p(this,Y,0);p(this,K,!1);p(this,z,!1);p(this,J,!1);p(this,B,new EventTarget);p(this,v);p(this,U,!1);p(this,D);p(this,X);p(this,Z);p(this,ee);p(this,N);p(this,k);p(this,te);p(this,M,new Map);p(this,_,new Set);p(this,re);p(this,he,[]);d(this,D,r),d(this,v,H.uuid()),d(this,re,n?.extensions??{}),d(this,Z,new Promise(a=>{i(this,D).addEventListener("message",s=>{if(s.data.type==="here")a();else throw new Error("Invalid message")},{once:!0})})),d(this,ee,new Promise(a=>{let s=o=>{o.data.type==="ready"&&(d(this,X,o.data.id),i(this,D).removeEventListener("message",s),a())};i(this,D).addEventListener("message",s)})),d(this,q,c(this,f,$e).call(this,n))}static async create(r,n){let a=new Me(r,n);return await i(a,q),a}get waitReady(){return new Promise(r=>{i(this,q).then(()=>{i(this,U)?r():r(new Promise(n=>{i(this,B).addEventListener("connected",()=>{n()})}))})})}get debug(){return i(this,Y)}get ready(){return i(this,K)}get closed(){return i(this,z)}get isLeader(){return i(this,J)}async close(){var r;i(this,z)||(d(this,z,!0),i(this,N)?.close(),i(this,k)?.close(),(r=i(this,te))==null||r.call(this),i(this,D).terminate())}async[Symbol.asyncDispose](){await this.close()}async execProtocolRaw(r){return await c(this,f,x).call(this,"execProtocolRaw",r)}async execProtocol(r){return await c(this,f,x).call(this,"execProtocol",r)}async execProtocolStream(r){return await c(this,f,x).call(this,"execProtocolStream",r)}async execProtocolRawStream(r,n){await c(this,f,x).call(this,"execProtocolRawStream",r,n)}async syncToFs(){await c(this,f,x).call(this,"syncToFs")}async listen(r,n,a){let s=H.toPostgresName(r),o=a??this;return i(this,M).has(s)||i(this,M).set(s,new Set),i(this,M).get(s).add(n),await o.exec(`LISTEN ${r}`),async u=>{await this.unlisten(s,n,u)}}async unlisten(r,n,a){await this.waitReady;let s=a??this;n?i(this,M).get(r)?.delete(n):i(this,M).delete(r),i(this,M).get(r)?.size===0&&await s.exec(`UNLISTEN ${r}`)}onNotification(r){return i(this,_).add(r),()=>{i(this,_).delete(r)}}offNotification(r){i(this,_).delete(r)}async dumpDataDir(r){return await c(this,f,x).call(this,"dumpDataDir",r)}onLeaderChange(r){return i(this,B).addEventListener("leader-change",r),()=>{i(this,B).removeEventListener("leader-change",r)}}offLeaderChange(r){i(this,B).removeEventListener("leader-change",r)}async _handleBlob(r){await c(this,f,x).call(this,"_handleBlob",r)}async _getWrittenBlob(){return await c(this,f,x).call(this,"_getWrittenBlob")}async _cleanupBlob(){await c(this,f,x).call(this,"_cleanupBlob")}async _checkReady(){await this.waitReady}async _runExclusiveQuery(r){await c(this,f,x).call(this,"_acquireQueryLock");try{return await r()}finally{await c(this,f,x).call(this,"_releaseQueryLock")}}async _runExclusiveTransaction(r){await c(this,f,x).call(this,"_acquireTransactionLock");try{return await r()}finally{await c(this,f,x).call(this,"_releaseTransactionLock")}}};q=new WeakMap,Y=new WeakMap,K=new WeakMap,z=new WeakMap,J=new WeakMap,B=new WeakMap,v=new WeakMap,U=new WeakMap,D=new WeakMap,X=new WeakMap,Z=new WeakMap,ee=new WeakMap,N=new WeakMap,k=new WeakMap,te=new WeakMap,M=new WeakMap,_=new WeakMap,re=new WeakMap,he=new WeakMap,f=new WeakSet,$e=async function(r={}){for(let[l,m]of Object.entries(i(this,re))){if(m instanceof URL)throw new Error("URL extensions are not supported on the client side of a worker");{let y=await m.setup(this,{},!0);if(y.emscriptenOpts&&console.warn(`PGlite extension ${l} returned emscriptenOpts, these are not supported on the client side of a worker`),y.namespaceObj){let T=this;T[l]=y.namespaceObj}y.bundlePath&&console.warn(`PGlite extension ${l} returned bundlePath, this is not supported on the client side of a worker`),y.init&&await y.init(),y.close&&i(this,he).push(y.close)}}await i(this,Z);let{extensions:n,...a}=r;i(this,D).postMessage({type:"init",options:a}),await i(this,ee);let s=`pglite-tab-close:${i(this,v)}`;d(this,te,await De(s));let o=`pglite-broadcast:${i(this,X)}`;d(this,N,new BroadcastChannel(o));let u=`pglite-tab:${i(this,v)}`;d(this,k,new BroadcastChannel(u)),i(this,N).addEventListener("message",async l=>{l.data.type==="leader-here"?(d(this,U,!1),i(this,B).dispatchEvent(new Event("leader-change")),c(this,f,ye).call(this)):l.data.type==="notify"&&c(this,f,He).call(this,l.data.channel,l.data.payload)}),i(this,k).addEventListener("message",async l=>{l.data.type==="connected"&&(d(this,U,!0),i(this,B).dispatchEvent(new Event("connected")),d(this,Y,await c(this,f,x).call(this,"getDebugLevel")),d(this,K,!0))}),i(this,D).addEventListener("message",async l=>{l.data.type==="leader-now"&&(d(this,J,!0),i(this,B).dispatchEvent(new Event("leader-change")))}),c(this,f,ye).call(this),this._initArrayTypes()},ye=async function(){i(this,U)||(i(this,N).postMessage({type:"tab-here",id:i(this,v)}),setTimeout(()=>c(this,f,ye).call(this),16))},x=async function(r,...n){let a=H.uuid(),s={type:"rpc-call",callId:a,method:r,args:n};return i(this,k).postMessage(s),await new Promise((o,u)=>{let l=T=>{if(T.data.callId!==a)return;y();let E=T.data;if(E.type==="rpc-return")o(E.result);else if(E.type==="rpc-error"){let ke=new Error(E.error.message);Object.assign(ke,E.error),u(ke)}else u(new Error("Invalid message"))},m=()=>{y(),u(new me)},y=()=>{i(this,k).removeEventListener("message",l),i(this,B).removeEventListener("leader-change",m)};i(this,B).addEventListener("leader-change",m),i(this,k).addEventListener("message",l)})},He=function(r,n){let a=i(this,M).get(r);if(a)for(let s of a)queueMicrotask(()=>s(n));for(let s of i(this,_))queueMicrotask(()=>s(r,n))};var Be=Me;async function er({init:e}){postMessage({type:"here"});let t=await new Promise(m=>{addEventListener("message",y=>{y.data.type==="init"&&m(y.data.options)},{once:!0})}),r=t.id??`${P}:${t.dataDir??""}`;postMessage({type:"ready",id:r});let n=`pglite-election-lock:${r}`,a=`pglite-broadcast:${r}`,s=new BroadcastChannel(a),o=new Set;await De(n);let u=e(t);s.onmessage=async m=>{let y=m.data;switch(y.type){case"tab-here":tr(y.id,await u,o);break}},s.postMessage({type:"leader-here",id:r}),postMessage({type:"leader-now"}),(await u).onNotification((m,y)=>{s.postMessage({type:"notify",channel:m,payload:y})})}function tr(e,t,r){if(r.has(e))return;r.add(e);let n=`pglite-tab:${e}`,a=`pglite-tab-close:${e}`,s=new BroadcastChannel(n);navigator.locks.request(a,()=>new Promise(u=>{s.close(),r.delete(e),u()}));let o=rr(e,t);s.addEventListener("message",async u=>{let l=u.data;switch(l.type){case"rpc-call":{await t.waitReady;let{callId:m,method:y,args:T}=l;try{let E=await o[y](...T);s.postMessage({type:"rpc-return",callId:m,result:E})}catch(E){console.error(E),s.postMessage({type:"rpc-error",callId:m,error:{message:E.message}})}break}}}),s.postMessage({type:"connected"})}function rr(e,t){let r=null,n=null,a=`pglite-tab-close:${e}`;return De(a).then(()=>{n&&t.exec("ROLLBACK"),r?.(),n?.()}),{async getDebugLevel(){return t.debug},async close(){await t.close()},async execProtocol(s){let{messages:o,data:u}=await t.execProtocol(s);if(u.byteLength!==u.buffer.byteLength){let l=new ArrayBuffer(u.byteLength),m=new Uint8Array(l);return m.set(u),{messages:o,data:m}}else return{messages:o,data:u}},async execProtocolStream(s){return await t.execProtocolStream(s)},async execProtocolRawStream(s,o){return await t.execProtocolRawStream(s,o)},async execProtocolRaw(s){let o=await t.execProtocolRaw(s);if(o.byteLength!==o.buffer.byteLength){let u=new ArrayBuffer(o.byteLength),l=new Uint8Array(u);return l.set(o),l}else return o},async dumpDataDir(s){return await t.dumpDataDir(s)},async syncToFs(){return await t.syncToFs()},async _handleBlob(s){return await t._handleBlob(s)},async _getWrittenBlob(){return await t._getWrittenBlob()},async _cleanupBlob(){return await t._cleanupBlob()},async _checkReady(){return await t._checkReady()},async _acquireQueryLock(){return new Promise(s=>{t._runExclusiveQuery(()=>new Promise(o=>{r=o,s()}))})},async _releaseQueryLock(){r?.(),r=null},async _acquireTransactionLock(){return new Promise(s=>{t._runExclusiveTransaction(()=>new Promise(o=>{n=o,s()}))})},async _releaseTransactionLock(){n?.(),n=null}}}var me=class extends Error{constructor(){super("Leader changed, pending operation in indeterminate state")}};async function De(e){let t;return await new Promise(r=>{navigator.locks.request(e,()=>new Promise(n=>{t=n,r()}))}),t}0&&(module.exports={LeaderChangedError,PGliteWorker,worker}); | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,2 +0,2 @@ | ||
| import{a as j}from"../chunk-HDIMFN25.js";import"../chunk-ACJ7KGEC.js";import{a as I}from"../chunk-3KNDAXZT.js";import"../chunk-F4GETNPB.js";import{e as t,f as p,g as u,h,j as Q}from"../chunk-QY3QWFKW.js";Q();var W,T,C,M,B,w,x,L,P,A,_,O,R,v,G,k,E,D,S,i,H,U,g,K,q=class q extends j{constructor(e,r){super();p(this,i);p(this,W);p(this,T,0);p(this,C,!1);p(this,M,!1);p(this,B,!1);p(this,w,new EventTarget);p(this,x);p(this,L,!1);p(this,P);p(this,A);p(this,_);p(this,O);p(this,R);p(this,v);p(this,G);p(this,k,new Map);p(this,E,new Set);p(this,D);p(this,S,[]);u(this,P,e),u(this,x,I.uuid()),u(this,D,r?.extensions??{}),u(this,_,new Promise(o=>{t(this,P).addEventListener("message",s=>{if(s.data.type==="here")o();else throw new Error("Invalid message")},{once:!0})})),u(this,O,new Promise(o=>{let s=a=>{a.data.type==="ready"&&(u(this,A,a.data.id),t(this,P).removeEventListener("message",s),o())};t(this,P).addEventListener("message",s)})),u(this,W,h(this,i,H).call(this,r))}static async create(e,r){let o=new q(e,r);return await t(o,W),o}get waitReady(){return new Promise(e=>{t(this,W).then(()=>{t(this,L)?e():e(new Promise(r=>{t(this,w).addEventListener("connected",()=>{r()})}))})})}get debug(){return t(this,T)}get ready(){return t(this,C)}get closed(){return t(this,M)}get isLeader(){return t(this,B)}async close(){var e;t(this,M)||(u(this,M,!0),t(this,R)?.close(),t(this,v)?.close(),(e=t(this,G))==null||e.call(this),t(this,P).terminate())}async[Symbol.asyncDispose](){await this.close()}async execProtocolRaw(e){return await h(this,i,g).call(this,"execProtocolRaw",e)}async execProtocol(e){return await h(this,i,g).call(this,"execProtocol",e)}async execProtocolStream(e){return await h(this,i,g).call(this,"execProtocolStream",e)}async execProtocolRawStream(e,r){await h(this,i,g).call(this,"execProtocolRawStream",e,r)}async syncToFs(){await h(this,i,g).call(this,"syncToFs")}async listen(e,r,o){let s=I.toPostgresName(e),a=o??this;return t(this,k).has(s)||t(this,k).set(s,new Set),t(this,k).get(s).add(r),await a.exec(`LISTEN ${e}`),async l=>{await this.unlisten(s,r,l)}}async unlisten(e,r,o){await this.waitReady;let s=o??this;r?t(this,k).get(e)?.delete(r):t(this,k).delete(e),t(this,k).get(e)?.size===0&&await s.exec(`UNLISTEN ${e}`)}onNotification(e){return t(this,E).add(e),()=>{t(this,E).delete(e)}}offNotification(e){t(this,E).delete(e)}async dumpDataDir(e){return await h(this,i,g).call(this,"dumpDataDir",e)}onLeaderChange(e){return t(this,w).addEventListener("leader-change",e),()=>{t(this,w).removeEventListener("leader-change",e)}}offLeaderChange(e){t(this,w).removeEventListener("leader-change",e)}async _handleBlob(e){await h(this,i,g).call(this,"_handleBlob",e)}async _getWrittenBlob(){return await h(this,i,g).call(this,"_getWrittenBlob")}async _cleanupBlob(){await h(this,i,g).call(this,"_cleanupBlob")}async _checkReady(){await this.waitReady}async _runExclusiveQuery(e){await h(this,i,g).call(this,"_acquireQueryLock");try{return await e()}finally{await h(this,i,g).call(this,"_releaseQueryLock")}}async _runExclusiveTransaction(e){await h(this,i,g).call(this,"_acquireTransactionLock");try{return await e()}finally{await h(this,i,g).call(this,"_releaseTransactionLock")}}};W=new WeakMap,T=new WeakMap,C=new WeakMap,M=new WeakMap,B=new WeakMap,w=new WeakMap,x=new WeakMap,L=new WeakMap,P=new WeakMap,A=new WeakMap,_=new WeakMap,O=new WeakMap,R=new WeakMap,v=new WeakMap,G=new WeakMap,k=new WeakMap,E=new WeakMap,D=new WeakMap,S=new WeakMap,i=new WeakSet,H=async function(e={}){for(let[c,y]of Object.entries(t(this,D))){if(y instanceof URL)throw new Error("URL extensions are not supported on the client side of a worker");{let d=await y.setup(this,{},!0);if(d.emscriptenOpts&&console.warn(`PGlite extension ${c} returned emscriptenOpts, these are not supported on the client side of a worker`),d.namespaceObj){let b=this;b[c]=d.namespaceObj}d.bundlePath&&console.warn(`PGlite extension ${c} returned bundlePath, this is not supported on the client side of a worker`),d.init&&await d.init(),d.close&&t(this,S).push(d.close)}}await t(this,_);let{extensions:r,...o}=e;t(this,P).postMessage({type:"init",options:o}),await t(this,O);let s=`pglite-tab-close:${t(this,x)}`;u(this,G,await N(s));let a=`pglite-broadcast:${t(this,A)}`;u(this,R,new BroadcastChannel(a));let l=`pglite-tab:${t(this,x)}`;u(this,v,new BroadcastChannel(l)),t(this,R).addEventListener("message",async c=>{c.data.type==="leader-here"?(u(this,L,!1),t(this,w).dispatchEvent(new Event("leader-change")),h(this,i,U).call(this)):c.data.type==="notify"&&h(this,i,K).call(this,c.data.channel,c.data.payload)}),t(this,v).addEventListener("message",async c=>{c.data.type==="connected"&&(u(this,L,!0),t(this,w).dispatchEvent(new Event("connected")),u(this,T,await h(this,i,g).call(this,"getDebugLevel")),u(this,C,!0))}),t(this,P).addEventListener("message",async c=>{c.data.type==="leader-now"&&(u(this,B,!0),t(this,w).dispatchEvent(new Event("leader-change")))}),h(this,i,U).call(this),this._initArrayTypes()},U=async function(){t(this,L)||(t(this,R).postMessage({type:"tab-here",id:t(this,x)}),setTimeout(()=>h(this,i,U).call(this),16))},g=async function(e,...r){let o=I.uuid(),s={type:"rpc-call",callId:o,method:e,args:r};return t(this,v).postMessage(s),await new Promise((a,l)=>{let c=b=>{if(b.data.callId!==o)return;d();let f=b.data;if(f.type==="rpc-return")a(f.result);else if(f.type==="rpc-error"){let F=new Error(f.error.message);Object.assign(F,f.error),l(F)}else l(new Error("Invalid message"))},y=()=>{d(),l(new $)},d=()=>{t(this,v).removeEventListener("message",c),t(this,w).removeEventListener("leader-change",y)};t(this,w).addEventListener("leader-change",y),t(this,v).addEventListener("message",c)})},K=function(e,r){let o=t(this,k).get(e);if(o)for(let s of o)queueMicrotask(()=>s(r));for(let s of t(this,E))queueMicrotask(()=>s(e,r))};var z=q;async function te({init:m}){postMessage({type:"here"});let n=await new Promise(y=>{addEventListener("message",d=>{d.data.type==="init"&&y(d.data.options)},{once:!0})}),e=n.id??`${import.meta.url}:${n.dataDir??""}`;postMessage({type:"ready",id:e});let r=`pglite-election-lock:${e}`,o=`pglite-broadcast:${e}`,s=new BroadcastChannel(o),a=new Set;await N(r);let l=m(n);s.onmessage=async y=>{let d=y.data;switch(d.type){case"tab-here":J(d.id,await l,a);break}},s.postMessage({type:"leader-here",id:e}),postMessage({type:"leader-now"}),(await l).onNotification((y,d)=>{s.postMessage({type:"notify",channel:y,payload:d})})}function J(m,n,e){if(e.has(m))return;e.add(m);let r=`pglite-tab:${m}`,o=`pglite-tab-close:${m}`,s=new BroadcastChannel(r);navigator.locks.request(o,()=>new Promise(l=>{s.close(),e.delete(m),l()}));let a=V(m,n);s.addEventListener("message",async l=>{let c=l.data;switch(c.type){case"rpc-call":{await n.waitReady;let{callId:y,method:d,args:b}=c;try{let f=await a[d](...b);s.postMessage({type:"rpc-return",callId:y,result:f})}catch(f){console.error(f),s.postMessage({type:"rpc-error",callId:y,error:{message:f.message}})}break}}}),s.postMessage({type:"connected"})}function V(m,n){let e=null,r=null,o=`pglite-tab-close:${m}`;return N(o).then(()=>{r&&n.exec("ROLLBACK"),e?.(),r?.()}),{async getDebugLevel(){return n.debug},async close(){await n.close()},async execProtocol(s){let{messages:a,data:l}=await n.execProtocol(s);if(l.byteLength!==l.buffer.byteLength){let c=new ArrayBuffer(l.byteLength),y=new Uint8Array(c);return y.set(l),{messages:a,data:y}}else return{messages:a,data:l}},async execProtocolStream(s){return await n.execProtocolStream(s)},async execProtocolRawStream(s,a){return await n.execProtocolRawStream(s,a)},async execProtocolRaw(s){let a=await n.execProtocolRaw(s);if(a.byteLength!==a.buffer.byteLength){let l=new ArrayBuffer(a.byteLength),c=new Uint8Array(l);return c.set(a),c}else return a},async dumpDataDir(s){return await n.dumpDataDir(s)},async syncToFs(){return await n.syncToFs()},async _handleBlob(s){return await n._handleBlob(s)},async _getWrittenBlob(){return await n._getWrittenBlob()},async _cleanupBlob(){return await n._cleanupBlob()},async _checkReady(){return await n._checkReady()},async _acquireQueryLock(){return new Promise(s=>{n._runExclusiveQuery(()=>new Promise(a=>{e=a,s()}))})},async _releaseQueryLock(){e?.(),e=null},async _acquireTransactionLock(){return new Promise(s=>{n._runExclusiveTransaction(()=>new Promise(a=>{r=a,s()}))})},async _releaseTransactionLock(){r?.(),r=null}}}var $=class extends Error{constructor(){super("Leader changed, pending operation in indeterminate state")}};async function N(m){let n;return await new Promise(e=>{navigator.locks.request(m,()=>new Promise(r=>{n=r,e()}))}),n}export{$ as LeaderChangedError,z as PGliteWorker,te as worker}; | ||
| import{a as j}from"../chunk-HDIMFN25.js";import"../chunk-ACJ7KGEC.js";import{a as I}from"../chunk-XP4OYHYJ.js";import"../chunk-F4GETNPB.js";import{e as t,f as p,g as u,h,j as Q}from"../chunk-QY3QWFKW.js";Q();var W,T,C,M,B,w,x,L,P,A,_,O,R,v,G,k,E,D,S,i,H,U,g,K,q=class q extends j{constructor(e,r){super();p(this,i);p(this,W);p(this,T,0);p(this,C,!1);p(this,M,!1);p(this,B,!1);p(this,w,new EventTarget);p(this,x);p(this,L,!1);p(this,P);p(this,A);p(this,_);p(this,O);p(this,R);p(this,v);p(this,G);p(this,k,new Map);p(this,E,new Set);p(this,D);p(this,S,[]);u(this,P,e),u(this,x,I.uuid()),u(this,D,r?.extensions??{}),u(this,_,new Promise(o=>{t(this,P).addEventListener("message",s=>{if(s.data.type==="here")o();else throw new Error("Invalid message")},{once:!0})})),u(this,O,new Promise(o=>{let s=a=>{a.data.type==="ready"&&(u(this,A,a.data.id),t(this,P).removeEventListener("message",s),o())};t(this,P).addEventListener("message",s)})),u(this,W,h(this,i,H).call(this,r))}static async create(e,r){let o=new q(e,r);return await t(o,W),o}get waitReady(){return new Promise(e=>{t(this,W).then(()=>{t(this,L)?e():e(new Promise(r=>{t(this,w).addEventListener("connected",()=>{r()})}))})})}get debug(){return t(this,T)}get ready(){return t(this,C)}get closed(){return t(this,M)}get isLeader(){return t(this,B)}async close(){var e;t(this,M)||(u(this,M,!0),t(this,R)?.close(),t(this,v)?.close(),(e=t(this,G))==null||e.call(this),t(this,P).terminate())}async[Symbol.asyncDispose](){await this.close()}async execProtocolRaw(e){return await h(this,i,g).call(this,"execProtocolRaw",e)}async execProtocol(e){return await h(this,i,g).call(this,"execProtocol",e)}async execProtocolStream(e){return await h(this,i,g).call(this,"execProtocolStream",e)}async execProtocolRawStream(e,r){await h(this,i,g).call(this,"execProtocolRawStream",e,r)}async syncToFs(){await h(this,i,g).call(this,"syncToFs")}async listen(e,r,o){let s=I.toPostgresName(e),a=o??this;return t(this,k).has(s)||t(this,k).set(s,new Set),t(this,k).get(s).add(r),await a.exec(`LISTEN ${e}`),async l=>{await this.unlisten(s,r,l)}}async unlisten(e,r,o){await this.waitReady;let s=o??this;r?t(this,k).get(e)?.delete(r):t(this,k).delete(e),t(this,k).get(e)?.size===0&&await s.exec(`UNLISTEN ${e}`)}onNotification(e){return t(this,E).add(e),()=>{t(this,E).delete(e)}}offNotification(e){t(this,E).delete(e)}async dumpDataDir(e){return await h(this,i,g).call(this,"dumpDataDir",e)}onLeaderChange(e){return t(this,w).addEventListener("leader-change",e),()=>{t(this,w).removeEventListener("leader-change",e)}}offLeaderChange(e){t(this,w).removeEventListener("leader-change",e)}async _handleBlob(e){await h(this,i,g).call(this,"_handleBlob",e)}async _getWrittenBlob(){return await h(this,i,g).call(this,"_getWrittenBlob")}async _cleanupBlob(){await h(this,i,g).call(this,"_cleanupBlob")}async _checkReady(){await this.waitReady}async _runExclusiveQuery(e){await h(this,i,g).call(this,"_acquireQueryLock");try{return await e()}finally{await h(this,i,g).call(this,"_releaseQueryLock")}}async _runExclusiveTransaction(e){await h(this,i,g).call(this,"_acquireTransactionLock");try{return await e()}finally{await h(this,i,g).call(this,"_releaseTransactionLock")}}};W=new WeakMap,T=new WeakMap,C=new WeakMap,M=new WeakMap,B=new WeakMap,w=new WeakMap,x=new WeakMap,L=new WeakMap,P=new WeakMap,A=new WeakMap,_=new WeakMap,O=new WeakMap,R=new WeakMap,v=new WeakMap,G=new WeakMap,k=new WeakMap,E=new WeakMap,D=new WeakMap,S=new WeakMap,i=new WeakSet,H=async function(e={}){for(let[c,y]of Object.entries(t(this,D))){if(y instanceof URL)throw new Error("URL extensions are not supported on the client side of a worker");{let d=await y.setup(this,{},!0);if(d.emscriptenOpts&&console.warn(`PGlite extension ${c} returned emscriptenOpts, these are not supported on the client side of a worker`),d.namespaceObj){let b=this;b[c]=d.namespaceObj}d.bundlePath&&console.warn(`PGlite extension ${c} returned bundlePath, this is not supported on the client side of a worker`),d.init&&await d.init(),d.close&&t(this,S).push(d.close)}}await t(this,_);let{extensions:r,...o}=e;t(this,P).postMessage({type:"init",options:o}),await t(this,O);let s=`pglite-tab-close:${t(this,x)}`;u(this,G,await N(s));let a=`pglite-broadcast:${t(this,A)}`;u(this,R,new BroadcastChannel(a));let l=`pglite-tab:${t(this,x)}`;u(this,v,new BroadcastChannel(l)),t(this,R).addEventListener("message",async c=>{c.data.type==="leader-here"?(u(this,L,!1),t(this,w).dispatchEvent(new Event("leader-change")),h(this,i,U).call(this)):c.data.type==="notify"&&h(this,i,K).call(this,c.data.channel,c.data.payload)}),t(this,v).addEventListener("message",async c=>{c.data.type==="connected"&&(u(this,L,!0),t(this,w).dispatchEvent(new Event("connected")),u(this,T,await h(this,i,g).call(this,"getDebugLevel")),u(this,C,!0))}),t(this,P).addEventListener("message",async c=>{c.data.type==="leader-now"&&(u(this,B,!0),t(this,w).dispatchEvent(new Event("leader-change")))}),h(this,i,U).call(this),this._initArrayTypes()},U=async function(){t(this,L)||(t(this,R).postMessage({type:"tab-here",id:t(this,x)}),setTimeout(()=>h(this,i,U).call(this),16))},g=async function(e,...r){let o=I.uuid(),s={type:"rpc-call",callId:o,method:e,args:r};return t(this,v).postMessage(s),await new Promise((a,l)=>{let c=b=>{if(b.data.callId!==o)return;d();let f=b.data;if(f.type==="rpc-return")a(f.result);else if(f.type==="rpc-error"){let F=new Error(f.error.message);Object.assign(F,f.error),l(F)}else l(new Error("Invalid message"))},y=()=>{d(),l(new $)},d=()=>{t(this,v).removeEventListener("message",c),t(this,w).removeEventListener("leader-change",y)};t(this,w).addEventListener("leader-change",y),t(this,v).addEventListener("message",c)})},K=function(e,r){let o=t(this,k).get(e);if(o)for(let s of o)queueMicrotask(()=>s(r));for(let s of t(this,E))queueMicrotask(()=>s(e,r))};var z=q;async function te({init:m}){postMessage({type:"here"});let n=await new Promise(y=>{addEventListener("message",d=>{d.data.type==="init"&&y(d.data.options)},{once:!0})}),e=n.id??`${import.meta.url}:${n.dataDir??""}`;postMessage({type:"ready",id:e});let r=`pglite-election-lock:${e}`,o=`pglite-broadcast:${e}`,s=new BroadcastChannel(o),a=new Set;await N(r);let l=m(n);s.onmessage=async y=>{let d=y.data;switch(d.type){case"tab-here":J(d.id,await l,a);break}},s.postMessage({type:"leader-here",id:e}),postMessage({type:"leader-now"}),(await l).onNotification((y,d)=>{s.postMessage({type:"notify",channel:y,payload:d})})}function J(m,n,e){if(e.has(m))return;e.add(m);let r=`pglite-tab:${m}`,o=`pglite-tab-close:${m}`,s=new BroadcastChannel(r);navigator.locks.request(o,()=>new Promise(l=>{s.close(),e.delete(m),l()}));let a=V(m,n);s.addEventListener("message",async l=>{let c=l.data;switch(c.type){case"rpc-call":{await n.waitReady;let{callId:y,method:d,args:b}=c;try{let f=await a[d](...b);s.postMessage({type:"rpc-return",callId:y,result:f})}catch(f){console.error(f),s.postMessage({type:"rpc-error",callId:y,error:{message:f.message}})}break}}}),s.postMessage({type:"connected"})}function V(m,n){let e=null,r=null,o=`pglite-tab-close:${m}`;return N(o).then(()=>{r&&n.exec("ROLLBACK"),e?.(),r?.()}),{async getDebugLevel(){return n.debug},async close(){await n.close()},async execProtocol(s){let{messages:a,data:l}=await n.execProtocol(s);if(l.byteLength!==l.buffer.byteLength){let c=new ArrayBuffer(l.byteLength),y=new Uint8Array(c);return y.set(l),{messages:a,data:y}}else return{messages:a,data:l}},async execProtocolStream(s){return await n.execProtocolStream(s)},async execProtocolRawStream(s,a){return await n.execProtocolRawStream(s,a)},async execProtocolRaw(s){let a=await n.execProtocolRaw(s);if(a.byteLength!==a.buffer.byteLength){let l=new ArrayBuffer(a.byteLength),c=new Uint8Array(l);return c.set(a),c}else return a},async dumpDataDir(s){return await n.dumpDataDir(s)},async syncToFs(){return await n.syncToFs()},async _handleBlob(s){return await n._handleBlob(s)},async _getWrittenBlob(){return await n._getWrittenBlob()},async _cleanupBlob(){return await n._cleanupBlob()},async _checkReady(){return await n._checkReady()},async _acquireQueryLock(){return new Promise(s=>{n._runExclusiveQuery(()=>new Promise(a=>{e=a,s()}))})},async _releaseQueryLock(){e?.(),e=null},async _acquireTransactionLock(){return new Promise(s=>{n._runExclusiveTransaction(()=>new Promise(a=>{r=a,s()}))})},async _releaseTransactionLock(){r?.(),r=null}}}var $=class extends Error{constructor(){super("Leader changed, pending operation in indeterminate state")}};async function N(m){let n;return await new Promise(e=>{navigator.locks.request(m,()=>new Promise(r=>{n=r,e()}))}),n}export{$ as LeaderChangedError,z as PGliteWorker,te as worker}; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/worker/index.ts"],"sourcesContent":["import type {\n DebugLevel,\n ExecProtocolResult,\n Extensions,\n PGliteInterface,\n PGliteInterfaceExtensions,\n PGliteOptions,\n Transaction,\n} from '../interface.js'\nimport type { PGlite } from '../pglite.js'\nimport { BasePGlite } from '../base.js'\nimport { DumpTarCompressionOptions } from '../fs/tarUtils.js'\nimport { BackendMessage } from '@electric-sql/pg-protocol/messages'\nimport { pglUtils } from '@electric-sql/pglite-utils'\n\nexport type PGliteWorkerOptions<E extends Extensions = Extensions> =\n PGliteOptions<E> & {\n meta?: any\n id?: string\n }\n\nexport class PGliteWorker\n extends BasePGlite\n implements PGliteInterface, AsyncDisposable\n{\n #initPromise: Promise<void>\n #debug: DebugLevel = 0\n\n #ready = false\n #closed = false\n #isLeader = false\n\n #eventTarget = new EventTarget()\n\n #tabId: string\n\n #connected = false\n\n #workerProcess: Worker\n #workerID?: string\n #workerHerePromise?: Promise<void>\n #workerReadyPromise?: Promise<void>\n\n #broadcastChannel?: BroadcastChannel\n #tabChannel?: BroadcastChannel\n #releaseTabCloseLock?: () => void\n\n #notifyListeners = new Map<string, Set<(payload: string) => void>>()\n #globalNotifyListeners = new Set<(channel: string, payload: string) => void>()\n\n #extensions: Extensions\n #extensionsClose: Array<() => Promise<void>> = []\n\n constructor(worker: Worker, options?: PGliteWorkerOptions) {\n super()\n this.#workerProcess = worker\n this.#tabId = pglUtils.uuid()\n this.#extensions = options?.extensions ?? {}\n\n this.#workerHerePromise = new Promise<void>((resolve) => {\n this.#workerProcess.addEventListener(\n 'message',\n (event) => {\n if (event.data.type === 'here') {\n resolve()\n } else {\n throw new Error('Invalid message')\n }\n },\n { once: true },\n )\n })\n\n this.#workerReadyPromise = new Promise<void>((resolve) => {\n const callback = (event: MessageEvent<any>) => {\n if (event.data.type === 'ready') {\n this.#workerID = event.data.id\n this.#workerProcess.removeEventListener('message', callback)\n resolve()\n }\n }\n this.#workerProcess.addEventListener('message', callback)\n })\n\n this.#initPromise = this.#init(options)\n }\n\n /**\n * Create a new PGlite instance with extensions on the Typescript interface\n * This also awaits the instance to be ready before resolving\n * (The main constructor does enable extensions, however due to the limitations\n * of Typescript, the extensions are not available on the instance interface)\n * @param worker The worker to use\n * @param options Optional options\n * @returns A promise that resolves to the PGlite instance when it's ready.\n */\n static async create<O extends PGliteWorkerOptions>(\n worker: Worker,\n options?: O,\n ): Promise<PGliteWorker & PGliteInterfaceExtensions<O['extensions']>> {\n const pg = new PGliteWorker(worker, options)\n await pg.#initPromise\n return pg as PGliteWorker & PGliteInterfaceExtensions<O['extensions']>\n }\n\n async #init(options: PGliteWorkerOptions = {}) {\n // Setup the extensions\n for (const [extName, ext] of Object.entries(this.#extensions)) {\n if (ext instanceof URL) {\n throw new Error(\n 'URL extensions are not supported on the client side of a worker',\n )\n } else {\n const extRet = await ext.setup(this, {}, true)\n if (extRet.emscriptenOpts) {\n console.warn(\n `PGlite extension ${extName} returned emscriptenOpts, these are not supported on the client side of a worker`,\n )\n }\n if (extRet.namespaceObj) {\n const instance = this as any\n instance[extName] = extRet.namespaceObj\n }\n if (extRet.bundlePath) {\n console.warn(\n `PGlite extension ${extName} returned bundlePath, this is not supported on the client side of a worker`,\n )\n }\n if (extRet.init) {\n await extRet.init()\n }\n if (extRet.close) {\n this.#extensionsClose.push(extRet.close)\n }\n }\n }\n\n // Wait for the worker let us know it's here\n await this.#workerHerePromise\n\n // Send the worker the options\n const { extensions: _, ...workerOptions } = options\n this.#workerProcess.postMessage({\n type: 'init',\n options: workerOptions,\n })\n\n // Wait for the worker let us know it's ready\n await this.#workerReadyPromise\n\n // Acquire the tab close lock, this is released then the tab, or this\n // PGliteWorker instance, is closed\n const tabCloseLockId = `pglite-tab-close:${this.#tabId}`\n this.#releaseTabCloseLock = await acquireLock(tabCloseLockId)\n\n // Start the broadcast channel used to communicate with tabs and leader election\n const broadcastChannelId = `pglite-broadcast:${this.#workerID}`\n this.#broadcastChannel = new BroadcastChannel(broadcastChannelId)\n\n // Start the tab channel used to communicate with the leader directly\n const tabChannelId = `pglite-tab:${this.#tabId}`\n this.#tabChannel = new BroadcastChannel(tabChannelId)\n\n this.#broadcastChannel.addEventListener('message', async (event) => {\n if (event.data.type === 'leader-here') {\n this.#connected = false\n this.#eventTarget.dispatchEvent(new Event('leader-change'))\n this.#leaderNotifyLoop()\n } else if (event.data.type === 'notify') {\n this.#receiveNotification(event.data.channel, event.data.payload)\n }\n })\n\n this.#tabChannel.addEventListener('message', async (event) => {\n if (event.data.type === 'connected') {\n this.#connected = true\n this.#eventTarget.dispatchEvent(new Event('connected'))\n this.#debug = await this.#rpc('getDebugLevel')\n this.#ready = true\n }\n })\n\n this.#workerProcess.addEventListener('message', async (event) => {\n if (event.data.type === 'leader-now') {\n this.#isLeader = true\n this.#eventTarget.dispatchEvent(new Event('leader-change'))\n }\n })\n\n this.#leaderNotifyLoop()\n\n // Init array types\n // We don't await this as it will result in a deadlock\n // It immediately takes out the transaction lock as so another query\n this._initArrayTypes()\n }\n\n async #leaderNotifyLoop() {\n if (!this.#connected) {\n this.#broadcastChannel!.postMessage({\n type: 'tab-here',\n id: this.#tabId,\n })\n setTimeout(() => this.#leaderNotifyLoop(), 16)\n }\n }\n\n async #rpc<Method extends WorkerRpcMethod>(\n method: Method,\n ...args: Parameters<WorkerApi[Method]>\n ): Promise<ReturnType<WorkerApi[Method]>> {\n const callId = pglUtils.uuid()\n const message: WorkerRpcCall<Method> = {\n type: 'rpc-call',\n callId,\n method,\n args,\n }\n this.#tabChannel!.postMessage(message)\n return await new Promise<ReturnType<WorkerApi[Method]>>(\n (resolve, reject) => {\n const listener = (event: MessageEvent) => {\n if (event.data.callId !== callId) return\n cleanup()\n const message: WorkerRpcResponse<Method> = event.data\n if (message.type === 'rpc-return') {\n resolve(message.result)\n } else if (message.type === 'rpc-error') {\n const error = new Error(message.error.message)\n Object.assign(error, message.error)\n reject(error)\n } else {\n reject(new Error('Invalid message'))\n }\n }\n const leaderChangeListener = () => {\n // If the leader changes, throw an error to reject the promise\n cleanup()\n reject(new LeaderChangedError())\n }\n const cleanup = () => {\n this.#tabChannel!.removeEventListener('message', listener)\n this.#eventTarget.removeEventListener(\n 'leader-change',\n leaderChangeListener,\n )\n }\n this.#eventTarget.addEventListener(\n 'leader-change',\n leaderChangeListener,\n )\n this.#tabChannel!.addEventListener('message', listener)\n },\n )\n }\n\n get waitReady() {\n return new Promise<void>((resolve) => {\n this.#initPromise.then(() => {\n if (!this.#connected) {\n resolve(\n new Promise<void>((resolve) => {\n this.#eventTarget.addEventListener('connected', () => {\n resolve()\n })\n }),\n )\n } else {\n resolve()\n }\n })\n })\n }\n\n get debug() {\n return this.#debug\n }\n\n /**\n * The ready state of the database\n */\n get ready() {\n return this.#ready\n }\n\n /**\n * The closed state of the database\n */\n get closed() {\n return this.#closed\n }\n\n /**\n * The leader state of this tab\n */\n get isLeader() {\n return this.#isLeader\n }\n\n /**\n * Close the database\n * @returns Promise that resolves when the connection to shared PGlite is closed\n */\n async close() {\n if (this.#closed) {\n return\n }\n this.#closed = true\n this.#broadcastChannel?.close()\n this.#tabChannel?.close()\n this.#releaseTabCloseLock?.()\n this.#workerProcess.terminate()\n }\n\n /**\n * Close the database when the object exits scope\n * Stage 3 ECMAScript Explicit Resource Management\n * https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management\n */\n async [Symbol.asyncDispose]() {\n await this.close()\n }\n\n /**\n * Execute a postgres wire protocol message directly without wrapping the response.\n * Only use if `execProtocol()` doesn't suite your needs.\n *\n * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n * don't intend to use the above features.\n *\n * @param message The postgres wire protocol message to execute\n * @returns The direct message data response produced by Postgres\n */\n async execProtocolRaw(message: Uint8Array): Promise<Uint8Array> {\n return (await this.#rpc('execProtocolRaw', message)) as Uint8Array\n }\n\n /**\n * Execute a postgres wire protocol message\n * @param message The postgres wire protocol message to execute\n * @returns The result of the query\n */\n async execProtocol(message: Uint8Array): Promise<ExecProtocolResult> {\n return await this.#rpc('execProtocol', message)\n }\n\n /**\n * Execute a postgres wire protocol message\n * @param message The postgres wire protocol message to execute\n * @returns The result of the query\n */\n async execProtocolStream(message: Uint8Array): Promise<BackendMessage[]> {\n return await this.#rpc('execProtocolStream', message)\n }\n\n /**\n * Execute a postgres wire protocol message directly without wrapping the response.\n * Only use if `execProtocol()` doesn't suite your needs.\n *\n * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n * don't intend to use the above features.\n *\n * @param message The postgres wire protocol message to execute\n * @returns The direct message data response produced by Postgres\n */\n async execProtocolRawStream(\n message: Uint8Array,\n options: { onRawData: (data: Uint8Array) => void },\n ): Promise<void> {\n await this.#rpc('execProtocolRawStream', message, options)\n }\n\n /**\n * Sync the database to the filesystem\n * @returns Promise that resolves when the database is synced to the filesystem\n */\n async syncToFs() {\n await this.#rpc('syncToFs')\n }\n\n /**\n * Listen for a notification\n * @param channel The channel to listen on\n * @param callback The callback to call when a notification is received\n */\n async listen(\n channel: string,\n callback: (payload: string) => void,\n tx?: Transaction,\n ): Promise<() => Promise<void>> {\n const pgChannel = pglUtils.toPostgresName(channel)\n const pg = tx ?? this\n if (!this.#notifyListeners.has(pgChannel)) {\n this.#notifyListeners.set(pgChannel, new Set())\n }\n this.#notifyListeners.get(pgChannel)!.add(callback)\n await pg.exec(`LISTEN ${channel}`)\n return async (tx?: Transaction) => {\n await this.unlisten(pgChannel, callback, tx)\n }\n }\n\n /**\n * Stop listening for a notification\n * @param channel The channel to stop listening on\n * @param callback The callback to remove\n */\n async unlisten(\n channel: string,\n callback?: (payload: string) => void,\n tx?: Transaction,\n ): Promise<void> {\n await this.waitReady\n const pg = tx ?? this\n if (callback) {\n this.#notifyListeners.get(channel)?.delete(callback)\n } else {\n this.#notifyListeners.delete(channel)\n }\n if (this.#notifyListeners.get(channel)?.size === 0) {\n // As we currently have a dedicated worker we can just unlisten\n await pg.exec(`UNLISTEN ${channel}`)\n }\n }\n\n /**\n * Listen to notifications\n * @param callback The callback to call when a notification is received\n */\n onNotification(callback: (channel: string, payload: string) => void) {\n this.#globalNotifyListeners.add(callback)\n return () => {\n this.#globalNotifyListeners.delete(callback)\n }\n }\n\n /**\n * Stop listening to notifications\n * @param callback The callback to remove\n */\n offNotification(callback: (channel: string, payload: string) => void) {\n this.#globalNotifyListeners.delete(callback)\n }\n\n #receiveNotification(channel: string, payload: string) {\n const listeners = this.#notifyListeners.get(channel)\n if (listeners) {\n for (const listener of listeners) {\n queueMicrotask(() => listener(payload))\n }\n }\n for (const listener of this.#globalNotifyListeners) {\n queueMicrotask(() => listener(channel, payload))\n }\n }\n\n async dumpDataDir(\n compression?: DumpTarCompressionOptions,\n ): Promise<File | Blob> {\n return (await this.#rpc('dumpDataDir', compression)) as File | Blob\n }\n\n onLeaderChange(callback: () => void) {\n this.#eventTarget.addEventListener('leader-change', callback)\n return () => {\n this.#eventTarget.removeEventListener('leader-change', callback)\n }\n }\n\n offLeaderChange(callback: () => void) {\n this.#eventTarget.removeEventListener('leader-change', callback)\n }\n\n async _handleBlob(blob?: File | Blob): Promise<void> {\n await this.#rpc('_handleBlob', blob)\n }\n\n async _getWrittenBlob(): Promise<File | Blob | undefined> {\n return await this.#rpc('_getWrittenBlob')\n }\n\n async _cleanupBlob(): Promise<void> {\n await this.#rpc('_cleanupBlob')\n }\n\n async _checkReady() {\n await this.waitReady\n }\n\n async _runExclusiveQuery<T>(fn: () => Promise<T>): Promise<T> {\n await this.#rpc('_acquireQueryLock')\n try {\n return await fn()\n } finally {\n await this.#rpc('_releaseQueryLock')\n }\n }\n\n async _runExclusiveTransaction<T>(fn: () => Promise<T>): Promise<T> {\n await this.#rpc('_acquireTransactionLock')\n try {\n return await fn()\n } finally {\n await this.#rpc('_releaseTransactionLock')\n }\n }\n}\n\nexport interface WorkerOptions {\n init: (options: Exclude<PGliteWorkerOptions, 'extensions'>) => Promise<PGlite>\n}\n\nexport async function worker({ init }: WorkerOptions) {\n // Send a message to the main thread to let it know we are here\n postMessage({ type: 'here' })\n\n // Await the main thread to send us the options\n const options = await new Promise<Exclude<PGliteWorkerOptions, 'extensions'>>(\n (resolve) => {\n addEventListener(\n 'message',\n (event) => {\n if (event.data.type === 'init') {\n resolve(event.data.options)\n }\n },\n { once: true },\n )\n },\n )\n\n // ID for this multi-tab worker - this is used to identify the group of workers\n // that are trying to elect a leader for a shared PGlite instance.\n // It defaults to the URL of the worker, and the dataDir if provided\n // but can be overridden by the options.\n const id = options.id ?? `${import.meta.url}:${options.dataDir ?? ''}`\n\n // Let the main thread know we are ready\n postMessage({ type: 'ready', id })\n\n const electionLockId = `pglite-election-lock:${id}`\n const broadcastChannelId = `pglite-broadcast:${id}`\n const broadcastChannel = new BroadcastChannel(broadcastChannelId)\n const connectedTabs = new Set<string>()\n\n // Await the main lock which is used to elect the leader\n // We don't release this lock, its automatically released when the worker or\n // tab is closed\n await acquireLock(electionLockId)\n\n // Now we are the leader, start the worker\n const dbPromise = init(options)\n\n // Start listening for messages from tabs\n broadcastChannel.onmessage = async (event) => {\n const msg = event.data\n switch (msg.type) {\n case 'tab-here':\n // A new tab has joined,\n connectTab(msg.id, await dbPromise, connectedTabs)\n break\n }\n }\n\n // Notify the other tabs that we are the leader\n broadcastChannel.postMessage({ type: 'leader-here', id })\n\n // Let the main thread know we are the leader\n postMessage({ type: 'leader-now' })\n\n const db = await dbPromise\n\n // Listen for notifications and broadcast them to all tabs\n db.onNotification((channel, payload) => {\n broadcastChannel.postMessage({ type: 'notify', channel, payload })\n })\n}\n\nfunction connectTab(tabId: string, pg: PGlite, connectedTabs: Set<string>) {\n if (connectedTabs.has(tabId)) {\n return\n }\n connectedTabs.add(tabId)\n const tabChannelId = `pglite-tab:${tabId}`\n const tabCloseLockId = `pglite-tab-close:${tabId}`\n const tabChannel = new BroadcastChannel(tabChannelId)\n\n // Use a tab close lock to unsubscribe the tab\n navigator.locks.request(tabCloseLockId, () => {\n return new Promise<void>((resolve) => {\n // The tab has been closed, unsubscribe the tab broadcast channel\n tabChannel.close()\n connectedTabs.delete(tabId)\n resolve()\n })\n })\n\n const api = makeWorkerApi(tabId, pg)\n\n tabChannel.addEventListener('message', async (event) => {\n const msg = event.data\n switch (msg.type) {\n case 'rpc-call': {\n await pg.waitReady\n const { callId, method, args } = msg as WorkerRpcCall<WorkerRpcMethod>\n try {\n // @ts-ignore no apparent reason why it fails\n const result = (await api[method](...args)) as WorkerRpcResult<\n typeof method\n >['result']\n tabChannel.postMessage({\n type: 'rpc-return',\n callId,\n result,\n } satisfies WorkerRpcResult<typeof method>)\n } catch (error) {\n console.error(error)\n tabChannel.postMessage({\n type: 'rpc-error',\n callId,\n error: { message: (error as Error).message },\n } satisfies WorkerRpcError)\n }\n break\n }\n }\n })\n\n // Send a message to the tab to let it know it's connected\n tabChannel.postMessage({ type: 'connected' })\n}\n\nfunction makeWorkerApi(tabId: string, db: PGlite) {\n let queryLockRelease: (() => void) | null = null\n let transactionLockRelease: (() => void) | null = null\n\n // If the tab is closed and it is holding a lock, release the the locks\n // and rollback any pending transactions\n const tabCloseLockId = `pglite-tab-close:${tabId}`\n acquireLock(tabCloseLockId).then(() => {\n if (transactionLockRelease) {\n // rollback any pending transactions\n db.exec('ROLLBACK')\n }\n queryLockRelease?.()\n transactionLockRelease?.()\n })\n\n return {\n async getDebugLevel() {\n return db.debug\n },\n async close() {\n await db.close()\n },\n async execProtocol(message: Uint8Array) {\n const { messages, data } = await db.execProtocol(message)\n if (data.byteLength !== data.buffer.byteLength) {\n const buffer = new ArrayBuffer(data.byteLength)\n const dataCopy = new Uint8Array(buffer)\n dataCopy.set(data)\n return { messages, data: dataCopy }\n } else {\n return { messages, data }\n }\n },\n async execProtocolStream(message: Uint8Array) {\n const messages = await db.execProtocolStream(message)\n return messages\n },\n async execProtocolRawStream(message: Uint8Array, options: any) {\n const messages = await db.execProtocolRawStream(message, options)\n return messages\n },\n async execProtocolRaw(message: Uint8Array) {\n const result = await db.execProtocolRaw(message)\n if (result.byteLength !== result.buffer.byteLength) {\n // The data is a slice of a larger buffer, this is potentially the whole\n // memory of the WASM module. We copy it to a new Uint8Array and return that.\n const buffer = new ArrayBuffer(result.byteLength)\n const resultCopy = new Uint8Array(buffer)\n resultCopy.set(result)\n return resultCopy\n } else {\n return result\n }\n },\n async dumpDataDir(compression?: DumpTarCompressionOptions) {\n return await db.dumpDataDir(compression)\n },\n async syncToFs() {\n return await db.syncToFs()\n },\n async _handleBlob(blob?: File | Blob) {\n return await db._handleBlob(blob)\n },\n async _getWrittenBlob() {\n return await db._getWrittenBlob()\n },\n async _cleanupBlob() {\n return await db._cleanupBlob()\n },\n async _checkReady() {\n return await db._checkReady()\n },\n async _acquireQueryLock() {\n return new Promise<void>((resolve) => {\n db._runExclusiveQuery(() => {\n return new Promise<void>((release) => {\n queryLockRelease = release\n resolve()\n })\n })\n })\n },\n async _releaseQueryLock() {\n queryLockRelease?.()\n queryLockRelease = null\n },\n async _acquireTransactionLock() {\n return new Promise<void>((resolve) => {\n db._runExclusiveTransaction(() => {\n return new Promise<void>((release) => {\n transactionLockRelease = release\n resolve()\n })\n })\n })\n },\n async _releaseTransactionLock() {\n transactionLockRelease?.()\n transactionLockRelease = null\n },\n }\n}\n\nexport class LeaderChangedError extends Error {\n constructor() {\n super('Leader changed, pending operation in indeterminate state')\n }\n}\n\nasync function acquireLock(lockId: string) {\n let release\n await new Promise<void>((resolve) => {\n navigator.locks.request(lockId, () => {\n return new Promise<void>((releaseCallback) => {\n release = releaseCallback\n resolve()\n })\n })\n })\n return release\n}\n\ntype WorkerApi = ReturnType<typeof makeWorkerApi>\n\ntype WorkerRpcMethod = keyof WorkerApi\n\ntype WorkerRpcCall<Method extends WorkerRpcMethod> = {\n type: 'rpc-call'\n callId: string\n method: Method\n args: Parameters<WorkerApi[Method]>\n}\n\ntype WorkerRpcResult<Method extends WorkerRpcMethod> = {\n type: 'rpc-return'\n callId: string\n result: ReturnType<WorkerApi[Method]>\n}\n\ntype WorkerRpcError = {\n type: 'rpc-error'\n callId: string\n error: any\n}\n\ntype WorkerRpcResponse<Method extends WorkerRpcMethod> =\n | WorkerRpcResult<Method>\n | WorkerRpcError\n"],"mappings":"4MAAAA,IAAA,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAqBaC,EAAN,MAAMA,UACHC,CAEV,CA6BE,YAAYC,EAAgBC,EAA+B,CACzD,MAAM,EAjCHC,EAAA,KAAAT,GAILS,EAAA,KAAA5B,GACA4B,EAAA,KAAA3B,EAAqB,GAErB2B,EAAA,KAAA1B,EAAS,IACT0B,EAAA,KAAAzB,EAAU,IACVyB,EAAA,KAAAxB,EAAY,IAEZwB,EAAA,KAAAvB,EAAe,IAAI,aAEnBuB,EAAA,KAAAtB,GAEAsB,EAAA,KAAArB,EAAa,IAEbqB,EAAA,KAAApB,GACAoB,EAAA,KAAAnB,GACAmB,EAAA,KAAAlB,GACAkB,EAAA,KAAAjB,GAEAiB,EAAA,KAAAhB,GACAgB,EAAA,KAAAf,GACAe,EAAA,KAAAd,GAEAc,EAAA,KAAAb,EAAmB,IAAI,KACvBa,EAAA,KAAAZ,EAAyB,IAAI,KAE7BY,EAAA,KAAAX,GACAW,EAAA,KAAAV,EAA+C,CAAC,GAI9CW,EAAA,KAAKrB,EAAiBkB,GACtBG,EAAA,KAAKvB,EAASwB,EAAS,KAAK,GAC5BD,EAAA,KAAKZ,EAAcU,GAAS,YAAc,CAAC,GAE3CE,EAAA,KAAKnB,EAAqB,IAAI,QAAeqB,GAAY,CACvDC,EAAA,KAAKxB,GAAe,iBAClB,UACCyB,GAAU,CACT,GAAIA,EAAM,KAAK,OAAS,OACtBF,EAAQ,MAER,OAAM,IAAI,MAAM,iBAAiB,CAErC,EACA,CAAE,KAAM,EAAK,CACf,CACF,CAAC,GAEDF,EAAA,KAAKlB,EAAsB,IAAI,QAAeoB,GAAY,CACxD,IAAMG,EAAYD,GAA6B,CACzCA,EAAM,KAAK,OAAS,UACtBJ,EAAA,KAAKpB,EAAYwB,EAAM,KAAK,IAC5BD,EAAA,KAAKxB,GAAe,oBAAoB,UAAW0B,CAAQ,EAC3DH,EAAQ,EAEZ,EACAC,EAAA,KAAKxB,GAAe,iBAAiB,UAAW0B,CAAQ,CAC1D,CAAC,GAEDL,EAAA,KAAK7B,EAAemC,EAAA,KAAKhB,EAAAC,GAAL,UAAWO,GACjC,CAWA,aAAa,OACXD,EACAC,EACoE,CACpE,IAAMS,EAAK,IAAIZ,EAAaE,EAAQC,CAAO,EAC3C,aAAMK,EAAAI,EAAGpC,GACFoC,CACT,CAyJA,IAAI,WAAY,CACd,OAAO,IAAI,QAAeL,GAAY,CACpCC,EAAA,KAAKhC,GAAa,KAAK,IAAM,CACtBgC,EAAA,KAAKzB,GASRwB,EAAQ,EARRA,EACE,IAAI,QAAeA,GAAY,CAC7BC,EAAA,KAAK3B,GAAa,iBAAiB,YAAa,IAAM,CACpD0B,EAAQ,CACV,CAAC,CACH,CAAC,CACH,CAIJ,CAAC,CACH,CAAC,CACH,CAEA,IAAI,OAAQ,CACV,OAAOC,EAAA,KAAK/B,EACd,CAKA,IAAI,OAAQ,CACV,OAAO+B,EAAA,KAAK9B,EACd,CAKA,IAAI,QAAS,CACX,OAAO8B,EAAA,KAAK7B,EACd,CAKA,IAAI,UAAW,CACb,OAAO6B,EAAA,KAAK5B,EACd,CAMA,MAAM,OAAQ,CA/ShB,IAAAiC,EAgTQL,EAAA,KAAK7B,KAGT0B,EAAA,KAAK1B,EAAU,IACf6B,EAAA,KAAKpB,IAAmB,MAAM,EAC9BoB,EAAA,KAAKnB,IAAa,MAAM,GACxBwB,EAAAL,EAAA,KAAKlB,KAAL,MAAAuB,EAAA,WACAL,EAAA,KAAKxB,GAAe,UAAU,EAChC,CAOA,MAAO,OAAO,YAAY,GAAI,CAC5B,MAAM,KAAK,MAAM,CACnB,CAaA,MAAM,gBAAgB8B,EAA0C,CAC9D,OAAQ,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBAAmBgB,EAC7C,CAOA,MAAM,aAAaA,EAAkD,CACnE,OAAO,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,eAAgBgB,EACzC,CAOA,MAAM,mBAAmBA,EAAgD,CACvE,OAAO,MAAMH,EAAA,KAAKhB,EAAAG,GAAL,UAAU,qBAAsBgB,EAC/C,CAaA,MAAM,sBACJA,EACAX,EACe,CACf,MAAMQ,EAAA,KAAKhB,EAAAG,GAAL,UAAU,wBAAyBgB,EAASX,EACpD,CAMA,MAAM,UAAW,CACf,MAAMQ,EAAA,KAAKhB,EAAAG,GAAL,UAAU,WAClB,CAOA,MAAM,OACJiB,EACAL,EACAM,EAC8B,CAC9B,IAAMC,EAAYX,EAAS,eAAeS,CAAO,EAC3CH,EAAKI,GAAM,KACjB,OAAKR,EAAA,KAAKjB,GAAiB,IAAI0B,CAAS,GACtCT,EAAA,KAAKjB,GAAiB,IAAI0B,EAAW,IAAI,GAAK,EAEhDT,EAAA,KAAKjB,GAAiB,IAAI0B,CAAS,EAAG,IAAIP,CAAQ,EAClD,MAAME,EAAG,KAAK,UAAUG,CAAO,EAAE,EAC1B,MAAOC,GAAqB,CACjC,MAAM,KAAK,SAASC,EAAWP,EAAUM,CAAE,CAC7C,CACF,CAOA,MAAM,SACJD,EACAL,EACAM,EACe,CACf,MAAM,KAAK,UACX,IAAMJ,EAAKI,GAAM,KACbN,EACFF,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,GAAG,OAAOL,CAAQ,EAEnDF,EAAA,KAAKjB,GAAiB,OAAOwB,CAAO,EAElCP,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,GAAG,OAAS,GAE/C,MAAMH,EAAG,KAAK,YAAYG,CAAO,EAAE,CAEvC,CAMA,eAAeL,EAAsD,CACnE,OAAAF,EAAA,KAAKhB,GAAuB,IAAIkB,CAAQ,EACjC,IAAM,CACXF,EAAA,KAAKhB,GAAuB,OAAOkB,CAAQ,CAC7C,CACF,CAMA,gBAAgBA,EAAsD,CACpEF,EAAA,KAAKhB,GAAuB,OAAOkB,CAAQ,CAC7C,CAcA,MAAM,YACJQ,EACsB,CACtB,OAAQ,MAAMP,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAAeoB,EACzC,CAEA,eAAeR,EAAsB,CACnC,OAAAF,EAAA,KAAK3B,GAAa,iBAAiB,gBAAiB6B,CAAQ,EACrD,IAAM,CACXF,EAAA,KAAK3B,GAAa,oBAAoB,gBAAiB6B,CAAQ,CACjE,CACF,CAEA,gBAAgBA,EAAsB,CACpCF,EAAA,KAAK3B,GAAa,oBAAoB,gBAAiB6B,CAAQ,CACjE,CAEA,MAAM,YAAYS,EAAmC,CACnD,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,cAAeqB,EACjC,CAEA,MAAM,iBAAoD,CACxD,OAAO,MAAMR,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBACzB,CAEA,MAAM,cAA8B,CAClC,MAAMa,EAAA,KAAKhB,EAAAG,GAAL,UAAU,eAClB,CAEA,MAAM,aAAc,CAClB,MAAM,KAAK,SACb,CAEA,MAAM,mBAAsBsB,EAAkC,CAC5D,MAAMT,EAAA,KAAKhB,EAAAG,GAAL,UAAU,qBAChB,GAAI,CACF,OAAO,MAAMsB,EAAG,CAClB,QAAE,CACA,MAAMT,EAAA,KAAKhB,EAAAG,GAAL,UAAU,oBAClB,CACF,CAEA,MAAM,yBAA4BsB,EAAkC,CAClE,MAAMT,EAAA,KAAKhB,EAAAG,GAAL,UAAU,2BAChB,GAAI,CACF,OAAO,MAAMsB,EAAG,CAClB,QAAE,CACA,MAAMT,EAAA,KAAKhB,EAAAG,GAAL,UAAU,0BAClB,CACF,CACF,EAneEtB,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YAEAC,EAAA,YACAC,EAAA,YA9BKC,EAAA,YAoFCC,EAAK,eAACO,EAA+B,CAAC,EAAG,CAE7C,OAAW,CAACkB,EAASC,CAAG,IAAK,OAAO,QAAQd,EAAA,KAAKf,EAAW,EAAG,CAC7D,GAAI6B,aAAe,IACjB,MAAM,IAAI,MACR,iEACF,EACK,CACL,IAAMC,EAAS,MAAMD,EAAI,MAAM,KAAM,CAAC,EAAG,EAAI,EAM7C,GALIC,EAAO,gBACT,QAAQ,KACN,oBAAoBF,CAAO,kFAC7B,EAEEE,EAAO,aAAc,CACvB,IAAMC,EAAW,KACjBA,EAASH,CAAO,EAAIE,EAAO,YAC7B,CACIA,EAAO,YACT,QAAQ,KACN,oBAAoBF,CAAO,4EAC7B,EAEEE,EAAO,MACT,MAAMA,EAAO,KAAK,EAEhBA,EAAO,OACTf,EAAA,KAAKd,GAAiB,KAAK6B,EAAO,KAAK,CAE3C,CACF,CAGA,MAAMf,EAAA,KAAKtB,GAGX,GAAM,CAAE,WAAYuC,EAAG,GAAGC,CAAc,EAAIvB,EAC5CK,EAAA,KAAKxB,GAAe,YAAY,CAC9B,KAAM,OACN,QAAS0C,CACX,CAAC,EAGD,MAAMlB,EAAA,KAAKrB,GAIX,IAAMwC,EAAiB,oBAAoBnB,EAAA,KAAK1B,EAAM,GACtDuB,EAAA,KAAKf,EAAuB,MAAMsC,EAAYD,CAAc,GAG5D,IAAME,EAAqB,oBAAoBrB,EAAA,KAAKvB,EAAS,GAC7DoB,EAAA,KAAKjB,EAAoB,IAAI,iBAAiByC,CAAkB,GAGhE,IAAMC,EAAe,cAActB,EAAA,KAAK1B,EAAM,GAC9CuB,EAAA,KAAKhB,EAAc,IAAI,iBAAiByC,CAAY,GAEpDtB,EAAA,KAAKpB,GAAkB,iBAAiB,UAAW,MAAOqB,GAAU,CAC9DA,EAAM,KAAK,OAAS,eACtBJ,EAAA,KAAKtB,EAAa,IAClByB,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,eAAe,CAAC,EAC1D8B,EAAA,KAAKhB,EAAAE,GAAL,YACSY,EAAM,KAAK,OAAS,UAC7BE,EAAA,KAAKhB,EAAAI,GAAL,UAA0BU,EAAM,KAAK,QAASA,EAAM,KAAK,QAE7D,CAAC,EAEDD,EAAA,KAAKnB,GAAY,iBAAiB,UAAW,MAAOoB,GAAU,CACxDA,EAAM,KAAK,OAAS,cACtBJ,EAAA,KAAKtB,EAAa,IAClByB,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,WAAW,CAAC,EACtDwB,EAAA,KAAK5B,EAAS,MAAMkC,EAAA,KAAKhB,EAAAG,GAAL,UAAU,kBAC9BO,EAAA,KAAK3B,EAAS,IAElB,CAAC,EAED8B,EAAA,KAAKxB,GAAe,iBAAiB,UAAW,MAAOyB,GAAU,CAC3DA,EAAM,KAAK,OAAS,eACtBJ,EAAA,KAAKzB,EAAY,IACjB4B,EAAA,KAAK3B,GAAa,cAAc,IAAI,MAAM,eAAe,CAAC,EAE9D,CAAC,EAED8B,EAAA,KAAKhB,EAAAE,GAAL,WAKA,KAAK,gBAAgB,CACvB,EAEMA,EAAiB,gBAAG,CACnBW,EAAA,KAAKzB,KACRyB,EAAA,KAAKpB,GAAmB,YAAY,CAClC,KAAM,WACN,GAAIoB,EAAA,KAAK1B,EACX,CAAC,EACD,WAAW,IAAM6B,EAAA,KAAKhB,EAAAE,GAAL,WAA0B,EAAE,EAEjD,EAEMC,EAAoC,eACxCiC,KACGC,EACqC,CACxC,IAAMC,EAAS3B,EAAS,KAAK,EACvBQ,EAAiC,CACrC,KAAM,WACN,OAAAmB,EACA,OAAAF,EACA,KAAAC,CACF,EACA,OAAAxB,EAAA,KAAKnB,GAAa,YAAYyB,CAAO,EAC9B,MAAM,IAAI,QACf,CAACP,EAAS2B,IAAW,CACnB,IAAMC,EAAY1B,GAAwB,CACxC,GAAIA,EAAM,KAAK,SAAWwB,EAAQ,OAClCG,EAAQ,EACR,IAAMtB,EAAqCL,EAAM,KACjD,GAAIK,EAAQ,OAAS,aACnBP,EAAQO,EAAQ,MAAM,UACbA,EAAQ,OAAS,YAAa,CACvC,IAAMuB,EAAQ,IAAI,MAAMvB,EAAQ,MAAM,OAAO,EAC7C,OAAO,OAAOuB,EAAOvB,EAAQ,KAAK,EAClCoB,EAAOG,CAAK,CACd,MACEH,EAAO,IAAI,MAAM,iBAAiB,CAAC,CAEvC,EACMI,EAAuB,IAAM,CAEjCF,EAAQ,EACRF,EAAO,IAAIK,CAAoB,CACjC,EACMH,EAAU,IAAM,CACpB5B,EAAA,KAAKnB,GAAa,oBAAoB,UAAW8C,CAAQ,EACzD3B,EAAA,KAAK3B,GAAa,oBAChB,gBACAyD,CACF,CACF,EACA9B,EAAA,KAAK3B,GAAa,iBAChB,gBACAyD,CACF,EACA9B,EAAA,KAAKnB,GAAa,iBAAiB,UAAW8C,CAAQ,CACxD,CACF,CACF,EAgMApC,EAAoB,SAACgB,EAAiByB,EAAiB,CACrD,IAAMC,EAAYjC,EAAA,KAAKjB,GAAiB,IAAIwB,CAAO,EACnD,GAAI0B,EACF,QAAWN,KAAYM,EACrB,eAAe,IAAMN,EAASK,CAAO,CAAC,EAG1C,QAAWL,KAAY3B,EAAA,KAAKhB,GAC1B,eAAe,IAAM2C,EAASpB,EAASyB,CAAO,CAAC,CAEnD,EAnbK,IAAME,EAAN1C,EA6eP,eAAsBE,GAAO,CAAE,KAAAyC,CAAK,EAAkB,CAEpD,YAAY,CAAE,KAAM,MAAO,CAAC,EAG5B,IAAMxC,EAAU,MAAM,IAAI,QACvBI,GAAY,CACX,iBACE,UACCE,GAAU,CACLA,EAAM,KAAK,OAAS,QACtBF,EAAQE,EAAM,KAAK,OAAO,CAE9B,EACA,CAAE,KAAM,EAAK,CACf,CACF,CACF,EAMMmC,EAAKzC,EAAQ,IAAM,GAAG,YAAY,GAAG,IAAIA,EAAQ,SAAW,EAAE,GAGpE,YAAY,CAAE,KAAM,QAAS,GAAAyC,CAAG,CAAC,EAEjC,IAAMC,EAAiB,wBAAwBD,CAAE,GAC3Cf,EAAqB,oBAAoBe,CAAE,GAC3CE,EAAmB,IAAI,iBAAiBjB,CAAkB,EAC1DkB,EAAgB,IAAI,IAK1B,MAAMnB,EAAYiB,CAAc,EAGhC,IAAMG,EAAYL,EAAKxC,CAAO,EAG9B2C,EAAiB,UAAY,MAAOrC,GAAU,CAC5C,IAAMwC,EAAMxC,EAAM,KAClB,OAAQwC,EAAI,KAAM,CAChB,IAAK,WAEHC,EAAWD,EAAI,GAAI,MAAMD,EAAWD,CAAa,EACjD,KACJ,CACF,EAGAD,EAAiB,YAAY,CAAE,KAAM,cAAe,GAAAF,CAAG,CAAC,EAGxD,YAAY,CAAE,KAAM,YAAa,CAAC,GAEvB,MAAMI,GAGd,eAAe,CAACjC,EAASyB,IAAY,CACtCM,EAAiB,YAAY,CAAE,KAAM,SAAU,QAAA/B,EAAS,QAAAyB,CAAQ,CAAC,CACnE,CAAC,CACH,CAEA,SAASU,EAAWC,EAAevC,EAAYmC,EAA4B,CACzE,GAAIA,EAAc,IAAII,CAAK,EACzB,OAEFJ,EAAc,IAAII,CAAK,EACvB,IAAMrB,EAAe,cAAcqB,CAAK,GAClCxB,EAAiB,oBAAoBwB,CAAK,GAC1CC,EAAa,IAAI,iBAAiBtB,CAAY,EAGpD,UAAU,MAAM,QAAQH,EAAgB,IAC/B,IAAI,QAAepB,GAAY,CAEpC6C,EAAW,MAAM,EACjBL,EAAc,OAAOI,CAAK,EAC1B5C,EAAQ,CACV,CAAC,CACF,EAED,IAAM8C,EAAMC,EAAcH,EAAOvC,CAAE,EAEnCwC,EAAW,iBAAiB,UAAW,MAAO3C,GAAU,CACtD,IAAMwC,EAAMxC,EAAM,KAClB,OAAQwC,EAAI,KAAM,CAChB,IAAK,WAAY,CACf,MAAMrC,EAAG,UACT,GAAM,CAAE,OAAAqB,EAAQ,OAAAF,EAAQ,KAAAC,CAAK,EAAIiB,EACjC,GAAI,CAEF,IAAMM,EAAU,MAAMF,EAAItB,CAAM,EAAE,GAAGC,CAAI,EAGzCoB,EAAW,YAAY,CACrB,KAAM,aACN,OAAAnB,EACA,OAAAsB,CACF,CAA0C,CAC5C,OAASlB,EAAO,CACd,QAAQ,MAAMA,CAAK,EACnBe,EAAW,YAAY,CACrB,KAAM,YACN,OAAAnB,EACA,MAAO,CAAE,QAAUI,EAAgB,OAAQ,CAC7C,CAA0B,CAC5B,CACA,KACF,CACF,CACF,CAAC,EAGDe,EAAW,YAAY,CAAE,KAAM,WAAY,CAAC,CAC9C,CAEA,SAASE,EAAcH,EAAeK,EAAY,CAChD,IAAIC,EAAwC,KACxCC,EAA8C,KAI5C/B,EAAiB,oBAAoBwB,CAAK,GAChD,OAAAvB,EAAYD,CAAc,EAAE,KAAK,IAAM,CACjC+B,GAEFF,EAAG,KAAK,UAAU,EAEpBC,IAAmB,EACnBC,IAAyB,CAC3B,CAAC,EAEM,CACL,MAAM,eAAgB,CACpB,OAAOF,EAAG,KACZ,EACA,MAAM,OAAQ,CACZ,MAAMA,EAAG,MAAM,CACjB,EACA,MAAM,aAAa1C,EAAqB,CACtC,GAAM,CAAE,SAAA6C,EAAU,KAAAC,CAAK,EAAI,MAAMJ,EAAG,aAAa1C,CAAO,EACxD,GAAI8C,EAAK,aAAeA,EAAK,OAAO,WAAY,CAC9C,IAAMC,EAAS,IAAI,YAAYD,EAAK,UAAU,EACxCE,EAAW,IAAI,WAAWD,CAAM,EACtC,OAAAC,EAAS,IAAIF,CAAI,EACV,CAAE,SAAAD,EAAU,KAAMG,CAAS,CACpC,KACE,OAAO,CAAE,SAAAH,EAAU,KAAAC,CAAK,CAE5B,EACA,MAAM,mBAAmB9C,EAAqB,CAE5C,OADiB,MAAM0C,EAAG,mBAAmB1C,CAAO,CAEtD,EACA,MAAM,sBAAsBA,EAAqBX,EAAc,CAE7D,OADiB,MAAMqD,EAAG,sBAAsB1C,EAASX,CAAO,CAElE,EACA,MAAM,gBAAgBW,EAAqB,CACzC,IAAMyC,EAAS,MAAMC,EAAG,gBAAgB1C,CAAO,EAC/C,GAAIyC,EAAO,aAAeA,EAAO,OAAO,WAAY,CAGlD,IAAMM,EAAS,IAAI,YAAYN,EAAO,UAAU,EAC1CQ,EAAa,IAAI,WAAWF,CAAM,EACxC,OAAAE,EAAW,IAAIR,CAAM,EACdQ,CACT,KACE,QAAOR,CAEX,EACA,MAAM,YAAYrC,EAAyC,CACzD,OAAO,MAAMsC,EAAG,YAAYtC,CAAW,CACzC,EACA,MAAM,UAAW,CACf,OAAO,MAAMsC,EAAG,SAAS,CAC3B,EACA,MAAM,YAAYrC,EAAoB,CACpC,OAAO,MAAMqC,EAAG,YAAYrC,CAAI,CAClC,EACA,MAAM,iBAAkB,CACtB,OAAO,MAAMqC,EAAG,gBAAgB,CAClC,EACA,MAAM,cAAe,CACnB,OAAO,MAAMA,EAAG,aAAa,CAC/B,EACA,MAAM,aAAc,CAClB,OAAO,MAAMA,EAAG,YAAY,CAC9B,EACA,MAAM,mBAAoB,CACxB,OAAO,IAAI,QAAejD,GAAY,CACpCiD,EAAG,mBAAmB,IACb,IAAI,QAAeQ,GAAY,CACpCP,EAAmBO,EACnBzD,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,mBAAoB,CACxBkD,IAAmB,EACnBA,EAAmB,IACrB,EACA,MAAM,yBAA0B,CAC9B,OAAO,IAAI,QAAelD,GAAY,CACpCiD,EAAG,yBAAyB,IACnB,IAAI,QAAeQ,GAAY,CACpCN,EAAyBM,EACzBzD,EAAQ,CACV,CAAC,CACF,CACH,CAAC,CACH,EACA,MAAM,yBAA0B,CAC9BmD,IAAyB,EACzBA,EAAyB,IAC3B,CACF,CACF,CAEO,IAAMnB,EAAN,cAAiC,KAAM,CAC5C,aAAc,CACZ,MAAM,0DAA0D,CAClE,CACF,EAEA,eAAeX,EAAYqC,EAAgB,CACzC,IAAID,EACJ,aAAM,IAAI,QAAezD,GAAY,CACnC,UAAU,MAAM,QAAQ0D,EAAQ,IACvB,IAAI,QAAeC,GAAoB,CAC5CF,EAAUE,EACV3D,EAAQ,CACV,CAAC,CACF,CACH,CAAC,EACMyD,CACT","names":["init_esm_shims","_initPromise","_debug","_ready","_closed","_isLeader","_eventTarget","_tabId","_connected","_workerProcess","_workerID","_workerHerePromise","_workerReadyPromise","_broadcastChannel","_tabChannel","_releaseTabCloseLock","_notifyListeners","_globalNotifyListeners","_extensions","_extensionsClose","_PGliteWorker_instances","init_fn","leaderNotifyLoop_fn","rpc_fn","receiveNotification_fn","_PGliteWorker","BasePGlite","worker","options","__privateAdd","__privateSet","f","resolve","__privateGet","event","callback","__privateMethod","pg","_a","message","channel","tx","pgChannel","compression","blob","fn","extName","ext","extRet","instance","_","workerOptions","tabCloseLockId","acquireLock","broadcastChannelId","tabChannelId","method","args","callId","reject","listener","cleanup","error","leaderChangeListener","LeaderChangedError","payload","listeners","PGliteWorker","init","id","electionLockId","broadcastChannel","connectedTabs","dbPromise","msg","connectTab","tabId","tabChannel","api","makeWorkerApi","result","db","queryLockRelease","transactionLockRelease","messages","data","buffer","dataCopy","resultCopy","release","lockId","releaseCallback"]} | ||
| {"version":3,"sources":["../../src/worker/index.ts"],"sourcesContent":["import type {\n DebugLevel,\n ExecProtocolResult,\n Extensions,\n PGliteInterface,\n PGliteInterfaceExtensions,\n PGliteOptions,\n Transaction,\n} from '../interface.js'\nimport type { PGlite } from '../pglite.js'\nimport { BasePGlite } from '../base.js'\nimport { DumpTarCompressionOptions } from '../fs/tarUtils.js'\nimport { BackendMessage } from '@electric-sql/pg-protocol/messages'\nimport { pglUtils } from '@electric-sql/pglite-utils'\n\nexport type PGliteWorkerOptions<E extends Extensions = Extensions> =\n PGliteOptions<E> & {\n meta?: any\n id?: string\n }\n\nexport class PGliteWorker\n extends BasePGlite\n implements PGliteInterface, AsyncDisposable\n{\n #initPromise: Promise<void>\n #debug: DebugLevel = 0\n\n #ready = false\n #closed = false\n #isLeader = false\n\n #eventTarget = new EventTarget()\n\n #tabId: string\n\n #connected = false\n\n #workerProcess: Worker\n #workerID?: string\n #workerHerePromise?: Promise<void>\n #workerReadyPromise?: Promise<void>\n\n #broadcastChannel?: BroadcastChannel\n #tabChannel?: BroadcastChannel\n #releaseTabCloseLock?: () => void\n\n #notifyListeners = new Map<string, Set<(payload: string) => void>>()\n #globalNotifyListeners = new Set<(channel: string, payload: string) => void>()\n\n #extensions: Extensions\n #extensionsClose: Array<() => Promise<void>> = []\n\n constructor(worker: Worker, options?: PGliteWorkerOptions) {\n super()\n this.#workerProcess = worker\n this.#tabId = pglUtils.uuid()\n this.#extensions = options?.extensions ?? {}\n\n this.#workerHerePromise = new Promise<void>((resolve) => {\n this.#workerProcess.addEventListener(\n 'message',\n (event) => {\n if (event.data.type === 'here') {\n resolve()\n } else {\n throw new Error('Invalid message')\n }\n },\n { once: true },\n )\n })\n\n this.#workerReadyPromise = new Promise<void>((resolve) => {\n const callback = (event: MessageEvent<any>) => {\n if (event.data.type === 'ready') {\n this.#workerID = event.data.id\n this.#workerProcess.removeEventListener('message', callback)\n resolve()\n }\n }\n this.#workerProcess.addEventListener('message', callback)\n })\n\n this.#initPromise = this.#init(options)\n }\n\n /**\n * Create a new PGlite instance with extensions on the Typescript interface\n * This also awaits the instance to be ready before resolving\n * (The main constructor does enable extensions, however due to the limitations\n * of Typescript, the extensions are not available on the instance interface)\n * @param worker The worker to use\n * @param options Optional options\n * @returns A promise that resolves to the PGlite instance when it's ready.\n */\n static async create<O extends PGliteWorkerOptions>(\n worker: Worker,\n options?: O,\n ): Promise<PGliteWorker & PGliteInterfaceExtensions<O['extensions']>> {\n const pg = new PGliteWorker(worker, options)\n await pg.#initPromise\n return pg as PGliteWorker & PGliteInterfaceExtensions<O['extensions']>\n }\n\n async #init(options: PGliteWorkerOptions = {}) {\n // Setup the extensions\n for (const [extName, ext] of Object.entries(this.#extensions)) {\n if (ext instanceof URL) {\n throw new Error(\n 'URL extensions are not supported on the client side of a worker',\n )\n } else {\n const extRet = await ext.setup(this, {}, true)\n if (extRet.emscriptenOpts) {\n console.warn(\n `PGlite extension ${extName} returned emscriptenOpts, these are not supported on the client side of a worker`,\n )\n }\n if (extRet.namespaceObj) {\n const instance = this as any\n instance[extName] = extRet.namespaceObj\n }\n if (extRet.bundlePath) {\n console.warn(\n `PGlite extension ${extName} returned bundlePath, this is not supported on the client side of a worker`,\n )\n }\n if (extRet.init) {\n await extRet.init()\n }\n if (extRet.close) {\n this.#extensionsClose.push(extRet.close)\n }\n }\n }\n\n // Wait for the worker let us know it's here\n await this.#workerHerePromise\n\n // Send the worker the options\n const { extensions: _, ...workerOptions } = options\n this.#workerProcess.postMessage({\n type: 'init',\n options: workerOptions,\n })\n\n // Wait for the worker let us know it's ready\n await this.#workerReadyPromise\n\n // Acquire the tab close lock, this is released then the tab, or this\n // PGliteWorker instance, is closed\n const tabCloseLockId = `pglite-tab-close:${this.#tabId}`\n this.#releaseTabCloseLock = await acquireLock(tabCloseLockId)\n\n // Start the broadcast channel used to communicate with tabs and leader election\n const broadcastChannelId = `pglite-broadcast:${this.#workerID}`\n this.#broadcastChannel = new BroadcastChannel(broadcastChannelId)\n\n // Start the tab channel used to communicate with the leader directly\n const tabChannelId = `pglite-tab:${this.#tabId}`\n this.#tabChannel = new BroadcastChannel(tabChannelId)\n\n this.#broadcastChannel.addEventListener('message', async (event) => {\n if (event.data.type === 'leader-here') {\n this.#connected = false\n this.#eventTarget.dispatchEvent(new Event('leader-change'))\n this.#leaderNotifyLoop()\n } else if (event.data.type === 'notify') {\n this.#receiveNotification(event.data.channel, event.data.payload)\n }\n })\n\n this.#tabChannel.addEventListener('message', async (event) => {\n if (event.data.type === 'connected') {\n this.#connected = true\n this.#eventTarget.dispatchEvent(new Event('connected'))\n this.#debug = await this.#rpc('getDebugLevel')\n this.#ready = true\n }\n })\n\n this.#workerProcess.addEventListener('message', async (event) => {\n if (event.data.type === 'leader-now') {\n this.#isLeader = true\n this.#eventTarget.dispatchEvent(new Event('leader-change'))\n }\n })\n\n this.#leaderNotifyLoop()\n\n // Init array types\n // We don't await this as it will result in a deadlock\n // It immediately takes out the transaction lock as so another query\n this._initArrayTypes()\n }\n\n async #leaderNotifyLoop() {\n if (!this.#connected) {\n this.#broadcastChannel!.postMessage({\n type: 'tab-here',\n id: this.#tabId,\n })\n setTimeout(() => this.#leaderNotifyLoop(), 16)\n }\n }\n\n async #rpc<Method extends WorkerRpcMethod>(\n method: Method,\n ...args: Parameters<WorkerApi[Method]>\n ): Promise<ReturnType<WorkerApi[Method]>> {\n const callId = pglUtils.uuid()\n const message: WorkerRpcCall<Method> = {\n type: 'rpc-call',\n callId,\n method,\n args,\n }\n this.#tabChannel!.postMessage(message)\n return await new Promise<ReturnType<WorkerApi[Method]>>(\n (resolve, reject) => {\n const listener = (event: MessageEvent) => {\n if (event.data.callId !== callId) return\n cleanup()\n const message: WorkerRpcResponse<Method> = event.data\n if (message.type === 'rpc-return') {\n resolve(message.result)\n } else if (message.type === 'rpc-error') {\n const error = new Error(message.error.message)\n Object.assign(error, message.error)\n reject(error)\n } else {\n reject(new Error('Invalid message'))\n }\n }\n const leaderChangeListener = () => {\n // If the leader changes, throw an error to reject the promise\n cleanup()\n reject(new LeaderChangedError())\n }\n const cleanup = () => {\n this.#tabChannel!.removeEventListener('message', listener)\n this.#eventTarget.removeEventListener(\n 'leader-change',\n leaderChangeListener,\n )\n }\n this.#eventTarget.addEventListener(\n 'leader-change',\n leaderChangeListener,\n )\n this.#tabChannel!.addEventListener('message', listener)\n },\n )\n }\n\n get waitReady() {\n return new Promise<void>((resolve) => {\n this.#initPromise.then(() => {\n if (!this.#connected) {\n resolve(\n new Promise<void>((resolve) => {\n this.#eventTarget.addEventListener('connected', () => {\n resolve()\n })\n }),\n )\n } else {\n resolve()\n }\n })\n })\n }\n\n get debug() {\n return this.#debug\n }\n\n /**\n * The ready state of the database\n */\n get ready() {\n return this.#ready\n }\n\n /**\n * The closed state of the database\n */\n get closed() {\n return this.#closed\n }\n\n /**\n * The leader state of this tab\n */\n get isLeader() {\n return this.#isLeader\n }\n\n /**\n * Close the database\n * @returns Promise that resolves when the connection to shared PGlite is closed\n */\n async close() {\n if (this.#closed) {\n return\n }\n this.#closed = true\n this.#broadcastChannel?.close()\n this.#tabChannel?.close()\n this.#releaseTabCloseLock?.()\n this.#workerProcess.terminate()\n }\n\n /**\n * Close the database when the object exits scope\n * Stage 3 ECMAScript Explicit Resource Management\n * https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management\n */\n async [Symbol.asyncDispose]() {\n await this.close()\n }\n\n /**\n * Execute a postgres wire protocol message directly without wrapping the response.\n * Only use if `execProtocol()` doesn't suite your needs.\n *\n * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n * don't intend to use the above features.\n *\n * @param message The postgres wire protocol message to execute\n * @returns The direct message data response produced by Postgres\n */\n async execProtocolRaw(message: Uint8Array): Promise<Uint8Array> {\n return (await this.#rpc('execProtocolRaw', message)) as Uint8Array\n }\n\n /**\n * Execute a postgres wire protocol message\n * @param message The postgres wire protocol message to execute\n * @returns The result of the query\n */\n async execProtocol(message: Uint8Array): Promise<ExecProtocolResult> {\n return await this.#rpc('execProtocol', message)\n }\n\n /**\n * Execute a postgres wire protocol message\n * @param message The postgres wire protocol message to execute\n * @returns The result of the query\n */\n async execProtocolStream(message: Uint8Array): Promise<BackendMessage[]> {\n return await this.#rpc('execProtocolStream', message)\n }\n\n /**\n * Execute a postgres wire protocol message directly without wrapping the response.\n * Only use if `execProtocol()` doesn't suite your needs.\n *\n * **Warning:** This bypasses PGlite's protocol wrappers that manage error/notice messages,\n * transactions, and notification listeners. Only use if you need to bypass these wrappers and\n * don't intend to use the above features.\n *\n * @param message The postgres wire protocol message to execute\n * @returns The direct message data response produced by Postgres\n */\n async execProtocolRawStream(\n message: Uint8Array,\n options: { onRawData: (data: Uint8Array) => void },\n ): Promise<void> {\n await this.#rpc('execProtocolRawStream', message, options)\n }\n\n /**\n * Sync the database to the filesystem\n * @returns Promise that resolves when the database is synced to the filesystem\n */\n async syncToFs() {\n await this.#rpc('syncToFs')\n }\n\n /**\n * Listen for a notification\n * @param channel The channel to listen on\n * @param callback The callback to call when a notification is received\n */\n async listen(\n channel: string,\n callback: (payload: string) => void,\n tx?: Transaction,\n ): Promise<() => Promise<void>> {\n const pgChannel = pglUtils.toPostgresName(channel)\n const pg = tx ?? this\n if (!this.#notifyListeners.has(pgChannel)) {\n this.#notifyListeners.set(pgChannel, new Set())\n }\n this.#notifyListeners.get(pgChannel)!.add(callback)\n await pg.exec(`LISTEN ${channel}`)\n return async (tx?: Transaction) => {\n await this.unlisten(pgChannel, callback, tx)\n }\n }\n\n /**\n * Stop listening for a notification\n * @param channel The channel to stop listening on\n * @param callback The callback to remove\n */\n async unlisten(\n channel: string,\n callback?: (payload: string) => void,\n tx?: Transaction,\n ): Promise<void> {\n await this.waitReady\n const pg = tx ?? this\n if (callback) {\n this.#notifyListeners.get(channel)?.delete(callback)\n } else {\n this.#notifyListeners.delete(channel)\n }\n if (this.#notifyListeners.get(channel)?.size === 0) {\n // As we currently have a dedicated worker we can just unlisten\n await pg.exec(`UNLISTEN ${channel}`)\n }\n }\n\n /**\n * Listen to notifications\n * @param callback The callback to call when a notification is received\n */\n onNotification(callback: (channel: string, payload: string) => void) {\n this.#globalNotifyListeners.add(callback)\n return () => {\n this.#globalNotifyListeners.delete(callback)\n }\n }\n\n /**\n * Stop listening to notifications\n * @param callback The callback to remove\n */\n offNotification(callback: (channel: string, payload: string) => void) {\n this.#globalNotifyListeners.delete(callback)\n }\n\n #receiveNotification(channel: string, payload: string) {\n const listeners = this.#notifyListeners.get(channel)\n if (listeners) {\n for (const listener of listeners) {\n queueMicrotask(() => listener(payload))\n }\n }\n for (const listener of this.#globalNotifyListeners) {\n queueMicrotask(() => listener(channel, payload))\n }\n }\n\n async dumpDataDir(\n compression?: DumpTarCompressionOptions,\n ): Promise<File | Blob> {\n return (await this.#rpc('dumpDataDir', compression)) as File | Blob\n }\n\n onLeaderChange(callback: () => void) {\n this.#eventTarget.addEventListener('leader-change', callback)\n return () => {\n this.#eventTarget.removeEventListener('leader-change', callback)\n }\n }\n\n offLeaderChange(callback: () => void) {\n this.#eventTarget.removeEventListener('leader-change', callback)\n }\n\n async _handleBlob(blob?: File | Blob): Promise<void> {\n await this.#rpc('_handleBlob', blob)\n }\n\n async _getWrittenBlob(): Promise<File | Blob | undefined> {\n return await this.#rpc('_getWrittenBlob')\n }\n\n async _cleanupBlob(): Promise<void> {\n await this.#rpc('_cleanupBlob')\n }\n\n async _checkReady() {\n await this.waitReady\n }\n\n async _runExclusiveQuery<T>(fn: () => Promise<T>): Promise<T> {\n await this.#rpc('_acquireQueryLock')\n try {\n return await fn()\n } finally {\n await this.#rpc('_releaseQueryLock')\n }\n }\n\n async _runExclusiveTransaction<T>(fn: () => Promise<T>): Promise<T> {\n await this.#rpc('_acquireTransactionLock')\n try {\n return await fn()\n } finally {\n await this.#rpc('_releaseTransactionLock')\n }\n }\n}\n\nexport interface WorkerOptions {\n init: (options: Exclude<PGliteWorkerOptions, 'extensions'>) => Promise<PGlite>\n}\n\nexport async function worker({ init }: WorkerOptions) {\n // Send a message to the main thread to let it know we are here\n postMessage({ type: 'here' })\n\n // Await the main thread to send us the options\n const options = await new Promise<Exclude<PGliteWorkerOptions, 'extensions'>>(\n (resolve) => {\n addEventListener(\n 'message',\n (event) => {\n if (event.data.type === 'init') {\n resolve(event.data.options)\n }\n },\n { once: true },\n )\n },\n )\n\n // ID for this multi-tab worker - this is used to identify the group of workers\n // that are trying to elect a leader for a shared PGlite instance.\n // It defaults to the URL of the worker, and the dataDir if provided\n // but can be overridden by the options.\n const id = options.id ?? `${import.meta.url}:${options.dataDir ?? ''}`\n\n // Let the main thread know we are ready\n postMessage({ type: 'ready', id })\n\n const electionLockId = `pglite-election-lock:${id}`\n const broadcastChannelId = `pglite-broadcast:${id}`\n const broadcastChannel = new BroadcastChannel(broadcastChannelId)\n const connectedTabs = new Set<string>()\n\n // Await the main lock which is used to elect the leader\n // We don't release this lock, its automatically released when the worker or\n // tab is closed\n await acquireLock(electionLockId)\n\n // Now we are the leader, start the worker\n const dbPromise = init(options)\n\n // Start listening for messages from tabs\n broadcastChannel.onmessage = async (event) => {\n const msg = event.data\n switch (msg.type) {\n case 'tab-here':\n // A new tab has joined,\n connectTab(msg.id, await dbPromise, connectedTabs)\n break\n }\n }\n\n // Notify the other tabs that we are the leader\n broadcastChannel.postMessage({ type: 'leader-here', id })\n\n // Let the main thread know we are the leader\n postMessage({ type: 'leader-now' })\n\n const db = await dbPromise\n\n // Listen for notifications and broadcast them to all tabs\n db.onNotification((channel, payload) => {\n broadcastChannel.postMessage({ type: 'notify', channel, payload })\n })\n}\n\nfunction connectTab(tabId: string, pg: PGlite, connectedTabs: Set<string>) {\n if (connectedTabs.has(tabId)) {\n return\n }\n connectedTabs.add(tabId)\n const tabChannelId = `pglite-tab:${tabId}`\n const tabCloseLockId = `pglite-tab-close:${tabId}`\n const tabChannel = new BroadcastChannel(tabChannelId)\n\n // Use a tab close lock to unsubscribe the tab\n navigator.locks.request(tabCloseLockId, () => {\n return new Promise<void>((resolve) => {\n // The tab has been closed, unsubscribe the tab broadcast channel\n tabChannel.close()\n connectedTabs.delete(tabId)\n resolve()\n })\n })\n\n const api = makeWorkerApi(tabId, pg)\n\n tabChannel.addEventListener('message', async (event) => {\n const msg = event.data\n switch (msg.type) {\n case 'rpc-call': {\n await pg.waitReady\n const { callId, method, args } = msg as WorkerRpcCall<WorkerRpcMethod>\n try {\n // @ts-ignore no apparent reason why it fails\n const result = (await api[method](...args)) as WorkerRpcResult<\n typeof method\n >['result']\n tabChannel.postMessage({\n type: 'rpc-return',\n callId,\n result,\n } satisfies WorkerRpcResult<typeof method>)\n } catch (error) {\n console.error(error)\n tabChannel.postMessage({\n type: 'rpc-error',\n callId,\n error: { message: (error as Error).message },\n } satisfies WorkerRpcError)\n }\n break\n }\n }\n })\n\n // Send a message to the tab to let it know it's connected\n tabChannel.postMessage({ type: 'connected' })\n}\n\nfunction makeWorkerApi(tabId: string, db: PGlite) {\n let queryLockRelease: (() => void) | null = null\n let transactionLockRelease: (() => void) | null = null\n\n // If the tab is closed and it is holding a lock, release the the locks\n // and rollback any pending transactions\n const tabCloseLockId = `pglite-tab-close:${tabId}`\n acquireLock(tabCloseLockId).then(() => {\n if (transactionLockRelease) {\n // rollback any pending transactions\n db.exec('ROLLBACK')\n }\n queryLockRelease?.()\n transactionLockRelease?.()\n })\n\n return {\n async getDebugLevel() {\n return db.debug\n },\n async close() {\n await db.close()\n },\n async execProtocol(message: Uint8Array) {\n const { messages, data } = await db.execProtocol(message)\n if (data.byteLength !== data.buffer.byteLength) {\n const buffer = new ArrayBuffer(data.byteLength)\n const dataCopy = new Uint8Array(buffer)\n dataCopy.set(data)\n return { messages, data: dataCopy }\n } else {\n return { messages, data }\n }\n },\n async execProtocolStream(message: Uint8Array) {\n const messages = await db.execProtocolStream(message)\n return messages\n },\n async execProtocolRawStream(message: Uint8Array, options: any) {\n const messages = await db.execProtocolRawStream(message, options)\n return messages\n },\n async execProtocolRaw(message: Uint8Array) {\n const result = await db.execProtocolRaw(message)\n if (result.byteLength !== result.buffer.byteLength) {\n // The data is a slice of a larger buffer, this is potentially the whole\n // memory of the WASM module. We copy it to a new Uint8Array and return that.\n const buffer = new ArrayBuffer(result.byteLength)\n const resultCopy = new Uint8Array(buffer)\n resultCopy.set(result)\n return resultCopy\n } else {\n return result\n }\n },\n async dumpDataDir(compression?: DumpTarCompressionOptions) {\n return await db.dumpDataDir(compression)\n },\n async syncToFs() {\n return await db.syncToFs()\n },\n async _handleBlob(blob?: File | Blob) {\n return await db._handleBlob(blob)\n },\n async _getWrittenBlob() {\n return await db._getWrittenBlob()\n },\n async _cleanupBlob() {\n return await db._cleanupBlob()\n },\n async _checkReady() {\n return await db._checkReady()\n },\n async _acquireQueryLock() {\n return new Promise<void>((resolve) => {\n db._runExclusiveQuery(() => {\n return new Promise<void>((release) => {\n queryLockRelease = release\n resolve()\n })\n })\n })\n },\n async _releaseQueryLock() {\n queryLockRelease?.()\n queryLockRelease = null\n },\n async _acquireTransactionLock() {\n return new Promise<void>((resolve) => {\n db._runExclusiveTransaction(() => {\n return new Promise<void>((release) => {\n transactionLockRelease = release\n resolve()\n })\n })\n })\n },\n async _releaseTransactionLock() {\n transactionLockRelease?.()\n transactionLockRelease = null\n },\n }\n}\n\nexport class LeaderChangedError extends Error {\n constructor() {\n super('Leader changed, pending operation in indeterminate state')\n }\n}\n\nasync function acquireLock(lockId: string) {\n let release\n await new Promise<void>((resolve) => {\n navigator.locks.request(lockId, () => {\n return new Promise<void>((releaseCallback) => {\n release = releaseCallback\n resolve()\n })\n })\n })\n return release\n}\n\ntype WorkerApi = ReturnType<typeof makeWorkerApi>\n\ntype WorkerRpcMethod = keyof WorkerApi\n\ntype WorkerRpcCall<Method extends WorkerRpcMethod> = {\n type: 'rpc-call'\n callId: string\n method: Method\n args: Parameters<WorkerApi[Method]>\n}\n\ntype WorkerRpcResult<Method extends WorkerRpcMethod> = {\n type: 'rpc-return'\n callId: string\n result: ReturnType<WorkerApi[Method]>\n}\n\ntype WorkerRpcError = {\n type: 'rpc-error'\n callId: string\n error: any\n}\n\ntype WorkerRpcResponse<Method extends WorkerRpcMethod> =\n | WorkerRpcResult<Method>\n | WorkerRpcError\n"],"mappings":"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","names":["init_esm_shims","_initPromise","_debug","_ready","_closed","_isLeader","_eventTarget","_tabId","_connected","_workerProcess","_workerID","_workerHerePromise","_workerReadyPromise","_broadcastChannel","_tabChannel","_releaseTabCloseLock","_notifyListeners","_globalNotifyListeners","_extensions","_extensionsClose","_PGliteWorker_instances","init_fn","leaderNotifyLoop_fn","rpc_fn","receiveNotification_fn","_PGliteWorker","BasePGlite","worker","options","__privateAdd","__privateSet","l","resolve","__privateGet","event","callback","__privateMethod","pg","_a","message","channel","tx","pgChannel","compression","blob","fn","extName","ext","extRet","instance","_","workerOptions","tabCloseLockId","acquireLock","broadcastChannelId","tabChannelId","method","args","callId","reject","listener","cleanup","error","leaderChangeListener","LeaderChangedError","payload","listeners","PGliteWorker","init","id","electionLockId","broadcastChannel","connectedTabs","dbPromise","msg","connectTab","tabId","tabChannel","api","makeWorkerApi","result","db","queryLockRelease","transactionLockRelease","messages","data","buffer","dataCopy","resultCopy","release","lockId","releaseCallback"]} |
+2
-2
| { | ||
| "name": "@electric-sql/pglite", | ||
| "version": "0.4.4", | ||
| "version": "0.4.5", | ||
| "private": false, | ||
@@ -209,3 +209,3 @@ "publishConfig": { | ||
| "@electric-sql/pg-protocol": "0.0.4", | ||
| "@electric-sql/pglite-utils": "0.0.1" | ||
| "@electric-sql/pglite-utils": "0.0.2" | ||
| }, | ||
@@ -212,0 +212,0 @@ "browser": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| import{j as c}from"./chunk-QY3QWFKW.js";c();var u=Object.defineProperty,f=(t,e)=>{for(var a in e)u(t,a,{get:e[a],enumerable:!0})},m={};f(m,{IN_NODE:()=>o,getFsBundle:()=>g,instantiateWasm:()=>d,startWasmDownload:()=>p,toPostgresName:()=>b,uuid:()=>h});var o=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string",r=new Map;async function p(t){o||r.has(t)||r.set(t,fetch(t))}var s=new Map;async function d(t,e,a){if(a||s.has(e)){let n=a||s.get(e);return{instance:await WebAssembly.instantiate(n,t),module:n}}if(o){let n=await(await import("fs/promises")).readFile(e),{module:i,instance:l}=await WebAssembly.instantiate(n,t);return s.set(e,i),{instance:l,module:i}}else{r.has(e)||r.set(e,fetch(e));let n=await r.get(e),{module:i,instance:l}=await WebAssembly.instantiateStreaming(n,t);return s.set(e,i),{instance:l,module:i}}}async function g(t){return o?(await(await import("fs/promises")).readFile(t)).buffer:(await fetch(t)).arrayBuffer()}var h=()=>{if(globalThis.crypto?.randomUUID)return globalThis.crypto.randomUUID();let t=new Uint8Array(16);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(t);else for(let a=0;a<t.length;a++)t[a]=Math.floor(Math.random()*256);t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=[];return t.forEach(a=>{e.push(a.toString(16).padStart(2,"0"))}),e.slice(0,4).join("")+"-"+e.slice(4,6).join("")+"-"+e.slice(6,8).join("")+"-"+e.slice(8,10).join("")+"-"+e.slice(10).join("")};function b(t){let e;return t.startsWith('"')&&t.endsWith('"')?e=t.substring(1,t.length-1):e=t.toLowerCase(),e}export{m as a}; | ||
| //# sourceMappingURL=chunk-3KNDAXZT.js.map |
| {"version":3,"sources":["../../pglite-utils/src/utils.ts"],"sourcesContent":["export const IN_NODE =\n typeof process === 'object' &&\n typeof process.versions === 'object' &&\n typeof process.versions.node === 'string'\n\nconst wasmDownloadPromises = new Map<URL, Promise<Response>>()\n\nexport async function startWasmDownload(url: URL) {\n if (IN_NODE || wasmDownloadPromises.has(url)) {\n return\n }\n wasmDownloadPromises.set(url, fetch(url))\n}\n\n// This is a global cache of the Wasm modules to avoid having to re-download or\n// compile them on subsequent calls.\nconst cachedWasmModules = new Map<URL, WebAssembly.Module>()\n\nexport async function instantiateWasm(\n imports: WebAssembly.Imports,\n moduleUrl: URL,\n module?: WebAssembly.Module,\n): Promise<{\n instance: WebAssembly.Instance\n module: WebAssembly.Module\n}> {\n if (module || cachedWasmModules.has(moduleUrl)) {\n const mod = module || cachedWasmModules.get(moduleUrl)!\n return {\n instance: await WebAssembly.instantiate(mod, imports),\n module: mod,\n }\n }\n if (IN_NODE) {\n const fs = await import('fs/promises')\n const buffer = await fs.readFile(moduleUrl)\n const { module: newModule, instance } = await WebAssembly.instantiate(\n buffer,\n imports,\n )\n cachedWasmModules.set(moduleUrl, newModule)\n return {\n instance,\n module: newModule,\n }\n } else {\n if (!wasmDownloadPromises.has(moduleUrl)) {\n wasmDownloadPromises.set(moduleUrl, fetch(moduleUrl))\n }\n const response = await wasmDownloadPromises.get(moduleUrl)\n const { module: newModule, instance } =\n await WebAssembly.instantiateStreaming(response!, imports)\n cachedWasmModules.set(moduleUrl, newModule)\n return {\n instance,\n module: newModule,\n }\n }\n}\n\nexport async function getFsBundle(fsBundleUrl: URL): Promise<ArrayBuffer> {\n if (IN_NODE) {\n const fs = await import('fs/promises')\n const fileData = await fs.readFile(fsBundleUrl)\n return fileData.buffer\n } else {\n const response = await fetch(fsBundleUrl)\n return response.arrayBuffer()\n }\n}\n\nexport const uuid = (): string => {\n // best case, `crypto.randomUUID` is available\n if (globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID()\n }\n\n const bytes = new Uint8Array(16)\n\n if (globalThis.crypto?.getRandomValues) {\n // `crypto.getRandomValues` is available even in non-secure contexts\n globalThis.crypto.getRandomValues(bytes)\n } else {\n // fallback to Math.random, if the Crypto API is completely missing\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256)\n }\n }\n\n bytes[6] = (bytes[6] & 0x0f) | 0x40 // Set the 4 most significant bits to 0100\n bytes[8] = (bytes[8] & 0x3f) | 0x80 // Set the 2 most significant bits to 10\n\n const hexValues: string[] = []\n bytes.forEach((byte) => {\n hexValues.push(byte.toString(16).padStart(2, '0'))\n })\n\n return (\n hexValues.slice(0, 4).join('') +\n '-' +\n hexValues.slice(4, 6).join('') +\n '-' +\n hexValues.slice(6, 8).join('') +\n '-' +\n hexValues.slice(8, 10).join('') +\n '-' +\n hexValues.slice(10).join('')\n )\n}\n\n/**\n * Postgresql handles quoted names as CaseSensitive and unquoted as lower case.\n * If input is quoted, returns an unquoted string (same casing)\n * If input is unquoted, returns a lower-case string\n */\nexport function toPostgresName(input: string): string {\n let output\n if (input.startsWith('\"') && input.endsWith('\"')) {\n // Postgres sensitive case\n output = input.substring(1, input.length - 1)\n } else {\n // Postgres case insensitive - all to lower\n output = input.toLowerCase()\n }\n return output\n}\n"],"mappings":"kIAAAA,EAAA,CAAA,EAAAC,EAAAD,EAAA,CAAA,QAAA,IAAAE,EAAA,YAAA,IAAAC,EAAA,gBAAA,IAAAC,EAAA,kBAAA,IAAAC,EAAA,eAAA,IAAAC,EAAA,KAAA,IAAAC,CAAAA,CAAAA,EAAO,IAAML,EACX,OAAO,SAAY,UACnB,OAAO,QAAQ,UAAa,UAC5B,OAAO,QAAQ,SAAS,MAAS,SAE7BM,EAAuB,IAAI,IAEjC,eAAsBH,EAAkBI,EAAU,CAC5CP,GAAWM,EAAqB,IAAIC,CAAG,GAG3CD,EAAqB,IAAIC,EAAK,MAAMA,CAAG,CAAC,CAC1C,CAIA,IAAMC,EAAoB,IAAI,IAE9B,eAAsBN,EACpBO,EACAC,EACAC,EAIC,CACD,GAAIA,GAAUH,EAAkB,IAAIE,CAAS,EAAG,CAC9C,IAAME,EAAMD,GAAUH,EAAkB,IAAIE,CAAS,EACrD,MAAO,CACL,SAAU,MAAM,YAAY,YAAYE,EAAKH,CAAO,EACpD,OAAQG,CACV,CACF,CACA,GAAIZ,EAAS,CAEX,IAAMa,EAAS,MADJ,KAAM,QAAO,aAAa,GACb,SAASH,CAAS,EACpC,CAAE,OAAQI,EAAW,SAAAC,CAAS,EAAI,MAAM,YAAY,YACxDF,EACAJ,CACF,EACA,OAAAD,EAAkB,IAAIE,EAAWI,CAAS,EACnC,CACL,SAAAC,EACA,OAAQD,CACV,CACF,KAAO,CACAR,EAAqB,IAAII,CAAS,GACrCJ,EAAqB,IAAII,EAAW,MAAMA,CAAS,CAAC,EAEtD,IAAMM,EAAW,MAAMV,EAAqB,IAAII,CAAS,EACnD,CAAE,OAAQI,EAAW,SAAAC,CAAS,EAClC,MAAM,YAAY,qBAAqBC,EAAWP,CAAO,EAC3D,OAAAD,EAAkB,IAAIE,EAAWI,CAAS,EACnC,CACL,SAAAC,EACA,OAAQD,CACV,CACF,CACF,CAEA,eAAsBb,EAAYgB,EAAwC,CACxE,OAAIjB,GAEe,MADN,KAAM,QAAO,aAAa,GACX,SAASiB,CAAW,GAC9B,QAEC,MAAM,MAAMA,CAAW,GACxB,YAAY,CAEhC,CAEO,IAAMZ,EAAO,IAAc,CAEhC,GAAI,WAAW,QAAQ,WACrB,OAAO,WAAW,OAAO,WAAW,EAGtC,IAAMa,EAAQ,IAAI,WAAW,EAAE,EAE/B,GAAI,WAAW,QAAQ,gBAErB,WAAW,OAAO,gBAAgBA,CAAK,MAGvC,SAASC,EAAI,EAAGA,EAAID,EAAM,OAAQC,IAChCD,EAAMC,CAAC,EAAI,KAAK,MAAM,KAAK,OAAO,EAAI,GAAG,EAI7CD,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,GAC/BA,EAAM,CAAC,EAAKA,EAAM,CAAC,EAAI,GAAQ,IAE/B,IAAME,EAAsB,CAAC,EAC7B,OAAAF,EAAM,QAASG,GAAS,CACtBD,EAAU,KAAKC,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,CACnD,CAAC,EAGCD,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7B,IACAA,EAAU,MAAM,EAAG,EAAE,EAAE,KAAK,EAAE,EAC9B,IACAA,EAAU,MAAM,EAAE,EAAE,KAAK,EAAE,CAE/B,EAOO,SAAShB,EAAekB,EAAuB,CACpD,IAAIC,EACJ,OAAID,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAS,GAAG,EAE7CC,EAASD,EAAM,UAAU,EAAGA,EAAM,OAAS,CAAC,EAG5CC,EAASD,EAAM,YAAY,EAEtBC,CACT","names":["utils_exports","__export","IN_NODE","getFsBundle","instantiateWasm","startWasmDownload","toPostgresName","uuid","wasmDownloadPromises","url","cachedWasmModules","imports","moduleUrl","module","mod","buffer","newModule","instance","response","fsBundleUrl","bytes","i","hexValues","byte","input","output"]} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
23264027
0.01%12714
0.03%73
-16.09%