@powersync/web 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +1 -1
  2. package/dist/index.react_native_web.js +12 -29
  3. package/dist/index.react_native_web.js.map +1 -1
  4. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +1 -1
  5. package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -1
  6. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +1 -1
  7. package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -1
  8. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +1 -1
  9. package/dist/worker/OPFSWriteAheadVFS-Rt5CGCZP.js.map +1 -1
  10. package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.wasm +0 -0
  11. package/dist/worker/assets/{mc-wa-sqlite-async-DYagSq56.wasm → mc-wa-sqlite-async-DdlQmAUV.wasm} +0 -0
  12. package/dist/worker/assets/wa-sqlite-CIxTmRHQ.wasm +0 -0
  13. package/dist/worker/assets/{wa-sqlite-async-DCIP8kAx.wasm → wa-sqlite-async-zc68fxQq.wasm} +0 -0
  14. package/dist/worker/{mc-wa-sqlite-DDFgWP93.js → mc-wa-sqlite-PubB6u8c.js} +2 -2
  15. package/dist/worker/{mc-wa-sqlite-DDFgWP93.js.map → mc-wa-sqlite-PubB6u8c.js.map} +1 -1
  16. package/dist/worker/{mc-wa-sqlite-async-lGclTjKJ.js → mc-wa-sqlite-async-DJG_ANKO.js} +2 -2
  17. package/dist/worker/{mc-wa-sqlite-async-lGclTjKJ.js.map → mc-wa-sqlite-async-DJG_ANKO.js.map} +1 -1
  18. package/dist/worker/{wa-sqlite-B0tZMM0j.js → wa-sqlite-D1_4mGs8.js} +2 -2
  19. package/dist/worker/{wa-sqlite-B0tZMM0j.js.map → wa-sqlite-D1_4mGs8.js.map} +1 -1
  20. package/dist/worker/{wa-sqlite-async-CM6BmfRh.js → wa-sqlite-async-BxkwNY-2.js} +2 -2
  21. package/dist/worker/{wa-sqlite-async-CM6BmfRh.js.map → wa-sqlite-async-BxkwNY-2.js.map} +1 -1
  22. package/dist/worker/worker.js +1 -1
  23. package/dist/worker/worker.js.map +1 -1
  24. package/lib/db/PowerSyncDatabase.d.ts +1 -2
  25. package/lib/db/PowerSyncDatabase.js +3 -13
  26. package/lib/db/PowerSyncDatabase.js.map +1 -1
  27. package/lib/db/sync/SSRWebStreamingSyncImplementation.d.ts +1 -8
  28. package/lib/db/sync/SSRWebStreamingSyncImplementation.js +3 -12
  29. package/lib/db/sync/SSRWebStreamingSyncImplementation.js.map +1 -1
  30. package/lib/db/sync/SharedWebStreamingSyncImplementation.d.ts +2 -1
  31. package/lib/db/sync/SharedWebStreamingSyncImplementation.js +6 -4
  32. package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
  33. package/lib/worker/sync/AbstractSharedSyncClientProvider.d.ts +1 -0
  34. package/lib/worker/sync/AbstractSharedSyncClientProvider.js.map +1 -1
  35. package/lib/worker/sync/SharedSyncImplementation.d.ts +3 -11
  36. package/lib/worker/sync/SharedSyncImplementation.js +32 -64
  37. package/lib/worker/sync/SharedSyncImplementation.js.map +1 -1
  38. package/lib/worker/sync/WorkerClient.d.ts +1 -1
  39. package/lib/worker/sync/WorkerClient.js +3 -3
  40. package/lib/worker/sync/WorkerClient.js.map +1 -1
  41. package/package.json +6 -6
  42. package/src/db/PowerSyncDatabase.ts +2 -13
  43. package/src/db/sync/SSRWebStreamingSyncImplementation.ts +4 -14
  44. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +8 -5
  45. package/src/worker/sync/AbstractSharedSyncClientProvider.ts +1 -0
  46. package/src/worker/sync/SharedSyncImplementation.ts +41 -76
  47. package/src/worker/sync/WorkerClient.ts +4 -4
  48. package/dist/worker/assets/mc-wa-sqlite-DoDpgFfE.wasm +0 -0
  49. package/dist/worker/assets/wa-sqlite-CagagB9I.wasm +0 -0
@@ -3,5 +3,5 @@
3
3
  * Copyright 2019 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- const t=Symbol("Comlink.proxy"),e=Symbol("Comlink.endpoint"),n=Symbol("Comlink.releaseProxy"),s=Symbol("Comlink.finalizer"),r=Symbol("Comlink.thrown"),i=t=>"object"==typeof t&&null!==t||"function"==typeof t,o=new Map([["proxy",{canHandle:e=>i(e)&&e[t],serialize(t){const{port1:e,port2:n}=new MessageChannel;return a(t,e),[n,[n]]},deserialize:t=>(t.start(),l(t))}],["throw",{canHandle:t=>i(t)&&r in t,serialize({value:t}){let e;return e=t instanceof Error?{isError:!0,value:{message:t.message,name:t.name,stack:t.stack}}:{isError:!1,value:t},[e,[]]},deserialize(t){if(t.isError)throw Object.assign(new Error(t.value.message),t.value);throw t.value}}]]);function a(t,e=globalThis,n=["*"]){e.addEventListener("message",function i(o){if(!o||!o.data)return;if(!function(t,e){for(const n of t){if(e===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(e))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:l,type:u,path:h}=Object.assign({path:[]},o.data),d=(o.data.argumentList||[]).map(S);let p;try{const e=h.slice(0,-1).reduce((t,e)=>t[e],t),n=h.reduce((t,e)=>t[e],t);switch(u){case"GET":p=n;break;case"SET":e[h.slice(-1)[0]]=S(o.data.value),p=!0;break;case"APPLY":p=n.apply(e,d);break;case"CONSTRUCT":p=y(new n(...d));break;case"ENDPOINT":{const{port1:e,port2:n}=new MessageChannel;a(t,n),p=w(e,[e])}break;case"RELEASE":p=void 0;break;default:return}}catch(t){p={value:t,[r]:0}}Promise.resolve(p).catch(t=>({value:t,[r]:0})).then(n=>{const[r,o]=b(n);e.postMessage(Object.assign(Object.assign({},r),{id:l}),o),"RELEASE"===u&&(e.removeEventListener("message",i),c(e),s in t&&"function"==typeof t[s]&&t[s]())}).catch(t=>{const[n,s]=b({value:new TypeError("Unserializable return value"),[r]:0});e.postMessage(Object.assign(Object.assign({},n),{id:l}),s)})}),e.start&&e.start()}function c(t){(function(t){return"MessagePort"===t.constructor.name})(t)&&t.close()}function l(t,e){const n=new Map;return t.addEventListener("message",function(t){const{data:e}=t;if(!e||!e.id)return;const s=n.get(e.id);if(s)try{s(e)}finally{n.delete(e.id)}}),g(t,n,[],e)}function u(t){if(t)throw new Error("Proxy has been released and is not useable")}function h(t){return v(t,new Map,{type:"RELEASE"}).then(()=>{c(t)})}const d=new WeakMap,p="FinalizationRegistry"in globalThis&&new FinalizationRegistry(t=>{const e=(d.get(t)||0)-1;d.set(t,e),0===e&&h(t)});function g(t,s,r=[],i=function(){}){let o=!1;const a=new Proxy(i,{get(e,i){if(u(o),i===n)return()=>{!function(t){p&&p.unregister(t)}(a),h(t),s.clear(),o=!0};if("then"===i){if(0===r.length)return{then:()=>a};const e=v(t,s,{type:"GET",path:r.map(t=>t.toString())}).then(S);return e.then.bind(e)}return g(t,s,[...r,i])},set(e,n,i){u(o);const[a,c]=b(i);return v(t,s,{type:"SET",path:[...r,n].map(t=>t.toString()),value:a},c).then(S)},apply(n,i,a){u(o);const c=r[r.length-1];if(c===e)return v(t,s,{type:"ENDPOINT"}).then(S);if("bind"===c)return g(t,s,r.slice(0,-1));const[l,h]=m(a);return v(t,s,{type:"APPLY",path:r.map(t=>t.toString()),argumentList:l},h).then(S)},construct(e,n){u(o);const[i,a]=m(n);return v(t,s,{type:"CONSTRUCT",path:r.map(t=>t.toString()),argumentList:i},a).then(S)}});return function(t,e){const n=(d.get(e)||0)+1;d.set(e,n),p&&p.register(t,e,t)}(a,t),a}function m(t){const e=t.map(b);return[e.map(t=>t[0]),(n=e.map(t=>t[1]),Array.prototype.concat.apply([],n))];var n}const f=new WeakMap;function w(t,e){return f.set(t,e),t}function y(e){return Object.assign(e,{[t]:!0})}function b(t){for(const[e,n]of o)if(n.canHandle(t)){const[s,r]=n.serialize(t);return[{type:"HANDLER",name:e,value:s},r]}return[{type:"RAW",value:t},f.get(t)||[]]}function S(t){switch(t.type){case"HANDLER":return o.get(t.name).deserialize(t.value);case"RAW":return t.value}}function v(t,e,n,s){return new Promise(r=>{const i=new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-");e.set(i,r),t.start&&t.start(),t.postMessage(Object.assign({id:i},n),s)})}const _={trace:10,debug:20,info:30,warn:40,error:50};function E(t){const{prefix:e="PowerSync",minLevel:n=_.info}=t??{};return{prefix:e,minLevel:n,log({level:t,message:n,error:s}){if(t<this.minLevel)return;let r=console.log;t>=_.error?r=console.error:t>=_.warn?r=console.warn:t>=_.info&&(r=console.info);const i=`[${e}]: ${n}`;s?r(i,s):r(i)}}}var C,A,P,T,L,x,O,I;!function(t){t.TEXT="TEXT",t.INTEGER="INTEGER",t.REAL="REAL"}(C||(C={})),C.TEXT,C.INTEGER,C.REAL,function(t){t[t.QUEUED_UPLOAD=0]="QUEUED_UPLOAD",t[t.QUEUED_DOWNLOAD=1]="QUEUED_DOWNLOAD",t[t.QUEUED_DELETE=2]="QUEUED_DELETE",t[t.SYNCED=3]="SYNCED",t[t.ARCHIVED=4]="ARCHIVED"}(A||(A={})),function(t){t.UTF8="utf8",t.Base64="base64"}(P||(P={})),function(t){t.PUT="PUT",t.PATCH="PATCH",t.DELETE="DELETE"}(T||(T={})),function(t){t.HTTP="http",t.WEB_SOCKET="web-socket"}(L||(L={})),function(t){t.Buffered="buffered",t.Sequential="sequential"}(x||(x={}));class k{listeners=new Set;constructor(){}dispose(){this.listeners.clear()}registerListener(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}iterateListeners(t){for(const e of this.listeners)t(e)}async iterateAsyncListeners(t){for(let e of Array.from(this.listeners.values()))await t(e)}}function q(t,e){const n={};return t.forEach((t,s)=>n[t]=e[s]),n}function R(t){return{...t,array:[],[Symbol.iterator]:()=>({next:()=>({done:!0,value:void 0})})}}class M{async getAll(t,e){const n=await this.execute(t,e);return Array.from(n)}async getOptional(t,e){const{array:n}=await this.execute(t,e);return n.length>0?n[0]:null}async get(t,e){const n=await this.getOptional(t,e);if(null==n)throw new Error("Result set is empty");return n}async execute(t,e){return function(t){const{insertId:e,rowsAffected:n,columnNames:s,rawRows:r}=t;let i;function o(){return i||(i=r.map(t=>q(s,t)))}function a(t){return i?i[t]:q(s,r[t])}return{insertId:e,rowsAffected:n,get array(){return o()},rows:{length:r.length,get _array(){return o()},item:a},[Symbol.iterator](){let t=0;return{next:function(){if(t>=r.length)return{done:!0,value:void 0};const e=a(t);return t++,{done:!1,value:e}}}}}}(await this.executeRaw(t,e))}async executeBatch(t,e=[]){let n,s=0;for(const r of e){const e=await this.execute(t,r);n=e.insertId,s+=e.rowsAffected??0}return R({rowsAffected:s,insertId:n})}}class U extends k{readTransaction(t,e){return this.readLock(e=>D.runWith(e,t),e)}writeTransaction(t,e){return this.writeLock(e=>D.runWith(e,t),e)}getAll(t,e){return this.readLock(n=>n.getAll(t,e))}getOptional(t,e){return this.readLock(n=>n.getOptional(t,e))}get(t,e){return this.readLock(n=>n.get(t,e))}execute(t,e){return this.writeLock(n=>n.execute(t,e))}executeRaw(t,e){return this.writeLock(n=>n.executeRaw(t,e))}executeBatch(t,e){return this.writeTransaction(n=>n.executeBatch(t,e))}}class D extends M{inner;finalized=!1;constructor(t){super(),this.inner=t}async commit(){this.finalized||(this.finalized=!0,await this.inner.execute("COMMIT"))}async rollback(){this.finalized||(this.finalized=!0,await this.inner.execute("ROLLBACK"))}execute(t,e){return this.inner.execute(t,e)}executeRaw(t,e){return this.inner.executeRaw(t,e)}executeBatch(t,e){return this.inner.executeBatch(t,e)}static async runWith(t,e){let n=new D(t);try{await t.execute("BEGIN IMMEDIATE");const s=await e(n);return await n.commit(),s}catch(t){try{await n.rollback()}catch(t){}throw t}}}!function(t){t.INSERT="INSERT",t.UPDATE="UPDATE",t.DELETE="DELETE"}(O||(O={})),function(t){t.ON_DATA="onData",t.ON_ERROR="onError",t.ON_STATE_CHANGE="onStateChange",t.SETTINGS_WILL_UPDATE="settingsWillUpdate",t.CLOSED="closed"}(I||(I={}));class N{#t;#e=0;#n=new Set;#s;#r=new Set;constructor(t){this.#t=t;const e=t.inner;this.#s=new BroadcastChannel(`${e.options.filename}-table-updates`),this.#s.onmessage=({data:t})=>{this.#i(t)}}#i(t){for(const e of this.#r)e.postMessage(t)}get#o(){return this.#t.inner}get#a(){return this.#t.logger}async connect(t){let e=!0;const n=this.#e++;this.#n.add(n);let s,r=new Map;function i(){if(!e)throw new Error("Client has already been closed")}function o(t){i();const e=r.get(t);if(!e)throw new Error("Attempted to use a connection lease that has already been returned.");return e}const a=async()=>{if(e){e=!1,s&&this.#r.delete(s);for(const{lease:t}of r.values())this.#a.log({level:_.debug,message:"Closing connection lease that hasn't been returned."}),await t.returnLease();this.#n.delete(n),0==this.#n.size?await this.forceClose():this.#a.log({level:_.debug,message:"Keeping underlying connection active since its used by other clients."})}};return t&&navigator.locks.request(t,{},()=>{a()}),{close:a,debugIsAutoCommit:async()=>this.#o.unsafeUseInner().isAutoCommit(),requestAccess:async(t,n)=>{i();const s=await this.#o.acquireConnection(null!=n?AbortSignal.timeout(n):void 0);if(!e)return await s.returnLease(),i();const o=crypto.randomUUID();return r.set(o,{lease:s,write:t}),o},completeAccess:async t=>{const e=o(t);r.delete(t);try{if(e.write){const{rawRows:t}=await e.lease.use(t=>t.execute("SELECT powersync_update_hooks('get')"));if(t.length){const e=JSON.parse(t[0][0]);e.length&&(this.#s.postMessage(e),this.#i(e))}}}finally{await e.lease.returnLease()}},execute:async(t,e,n)=>{const{lease:s}=o(t);return await s.use(t=>t.execute(e,n))},executeBatch:async(t,e,n)=>{const{lease:s}=o(t);return await s.use(t=>t.executeBatch(e,n))},setUpdateListener:async t=>{i(),s&&this.#r.delete(s),s=t,t&&this.#r.add(t)}}}async forceClose(){this.#a.log({level:_.debug,message:`Closing connection to ${JSON.stringify(this.#o.options)}.`});const t=this.#o;this.#t.onClose(),this.#s.close(),await t.close()}}const F=()=>{if("locks"in navigator&&navigator.locks)return navigator.locks;throw new Error("Navigator locks are not available in an insecure context. Use a secure context such as HTTPS or http://localhost.")},$=0,B=1,W=5,z=10,j=12,H=14,V=3338,J=3594,G=4106,K=2570,Q=1802,Y=1034,X=3850,Z=266,tt=522,et=1546,nt=2058,st=778,rt=4,it=8,ot=64,at=256,ct=512,lt=2048,ut=16384,ht=524288,dt=0,pt=1,gt=2,mt=4,ft=2048,wt=16384,yt=11,bt=14,St=21,vt=31,_t=32,Et=33;void 0===BigInt.prototype.toJSON&&(BigInt.prototype.toJSON=function(){return this.toString()});const Ct=0x7fffffffffffffffn,At=-0x8000000000000000n,Pt=Object.getPrototypeOf(async function(){}).constructor;class Tt extends Error{constructor(t,e){super(t),this.code=e}}const Lt=!0;function xt(t){const e=[],n=t.match(/([ns@]*):([nsv@])/);switch(n[2]){case"n":e.push("number");break;case"s":e.push("string");break;case"v":e.push(null)}const s=[];for(let t of n[1])switch(t){case"n":s.push("number");break;case"s":s.push("string")}return e.push(s),e}var Ot,It;async function kt(t){if(t){const{default:t}=await import("./mc-wa-sqlite-async-lGclTjKJ.js");return t()}{const{default:t}=await import("./wa-sqlite-async-CM6BmfRh.js");return t()}}async function qt(t){if(t){const{default:t}=await import("./mc-wa-sqlite-DDFgWP93.js");return t()}{const{default:t}=await import("./wa-sqlite-B0tZMM0j.js");return t()}}!function(t){t.IDBBatchAtomicVFS="IDBBatchAtomicVFS",t.OPFSCoopSyncVFS="OPFSCoopSyncVFS",t.AccessHandlePoolVFS="AccessHandlePoolVFS",t.OPFSWriteAheadVFS="OPFSWriteAheadVFS",t.InMemoryVfs="InMemoryVFS"}(Ot||(Ot={})),function(t){t.MEMORY="memory",t.FILESYSTEM="file"}(It||(It={}));class Rt{#c;#l=new Map;constructor(t){this.#c=t}lookup(t){const e=this.#l.get(t);return null!=e?(this.#l.delete(t),this.#l.set(t,e),e):null}addStatement(t,e){if(this.#l.set(t,e),this.#l.size>this.#c)for(const[t,e]of this.#l.entries())return this.#l.delete(t),e;return null}drain(){const t=[...this.#l.values()];return this.#l.clear(),t}}class Mt{options;_sqliteAPI=null;sqlite3_stmt_isexplain;db=0;statementCache;constructor(t){this.options=t,this.statementCache=t.preparedStatementsCache>0?new Rt(t.preparedStatementsCache):null}get isOpen(){return 0!=this.db}async init(){const{module:t,vfs:e}=await async function({vfs:t,filename:e,encryptionKey:n}){let s,r=qt;switch(t){case Ot.IDBBatchAtomicVFS:{r=kt;const{IDBBatchAtomicVFS:t}=await import("./IDBBatchAtomicVFS-DbkDb777.js");s=n=>t.create(e,n,{lockPolicy:"exclusive"});break}case Ot.AccessHandlePoolVFS:{const{AccessHandlePoolVFS:t}=await import("./AccessHandlePoolVFS-BPUHfZME.js");s=n=>t.create(e,n);break}case Ot.OPFSCoopSyncVFS:{const{OPFSCoopSyncVFS:t}=await import("./OPFSCoopSyncVFS-BgTiWPfa.js");s=n=>t.create(e,n);break}case Ot.OPFSWriteAheadVFS:{const{OPFSWriteAheadVFS:t}=await import("./OPFSWriteAheadVFS-Rt5CGCZP.js");s=n=>t.create(e,n,{});break}case Ot.InMemoryVfs:{const{MemoryVFS:t}=await import("./MemoryVFS-DVJL5F8j.js");s=n=>t.create(e,n);break}}const i=await r(n);return{module:i,vfs:await s(i)}}(this.options);await this.initWithModule(t,e)}async initWithModule(t,e){const n=this._sqliteAPI=await this.openSQLiteAPI(t,e);if(this.db=await n.open_v2(this.options.filename,this.options.readonly?1:6),await this.executeRaw(`PRAGMA temp_store = ${this.options.temporaryStorage};`),this.options.encryptionKey){const t=this.options.encryptionKey.replaceAll("'","''");await this.executeRaw(`PRAGMA key = '${t}';`)}await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`),await this.executeRaw("SELECT powersync_update_hooks('install');")}async openSQLiteAPI(t,e){e.mxPathname=128,this.sqlite3_stmt_isexplain=t.cwrap("sqlite3_stmt_isexplain","int",["int"]);const n=function(t){const e={};t.retryOps=[],t.pendingOps=[];const n=t._getSqliteFree(),s=t._malloc(8),r=[s,s+4],i=new TextEncoder;function o(e){if("string"!=typeof e)return 0;const n=i.encode(e),s=t._sqlite3_malloc(n.byteLength+1);return t.HEAPU8.set(n,s),t.HEAPU8[s+n.byteLength]=0,s}function a(t,e){return BigInt(e)<<32n|0xffffffffn&BigInt(t)}const c=function(){const t=BigInt(Number.MAX_SAFE_INTEGER)>>32n,e=BigInt(Number.MIN_SAFE_INTEGER)>>32n;return function(n,s){return s>t||s<e?a(n,s):4294967296*s+(2147483647&n)-(2147483648&n)}}(),l=new Set;function u(t){if(!l.has(t))throw new Tt("not a database",21)}const h=new Map;function d(t){if(!h.has(t))throw new Tt("not a statement",21)}function p(e,n,s=null,r=[0]){if(r.includes(n))return n;const i=s?t.ccall("sqlite3_errmsg","string",["number"],[s]):e;throw new Tt(i,n)}async function g(e){let n;for(let s=0;s<2;++s){if(t.retryOps.length)try{await Promise.all(t.retryOps)}finally{t.retryOps=[]}if(n=await e(),0===n||0===t.retryOps.length){if(t.pendingOps.length)try{await Promise.all(t.pendingOps)}catch(t){return console.error("Error in pendingOps:",t),t.code||1}finally{t.pendingOps=[]}return n}}return n}return e.bind_collection=function(t,n){d(t);const s=Array.isArray(n),r=e.bind_parameter_count(t);for(let i=1;i<=r;++i){const r=n[s?i-1:e.bind_parameter_name(t,i)];void 0!==r&&e.bind(t,i,r)}return 0},e.bind=function(t,n,s){switch(d(t),typeof s){case"number":return s===(0|s)?e.bind_int(t,n,s):e.bind_double(t,n,s);case"string":return e.bind_text(t,n,s);case"boolean":return e.bind_int(t,n,s?1:0);default:return s instanceof Uint8Array||Array.isArray(s)?e.bind_blob(t,n,s):null===s?e.bind_null(t,n):"bigint"==typeof s?e.bind_int64(t,n,s):void 0===s?27:(console.warn("unknown binding converted to null",s),e.bind_null(t,n))}},e.bind_blob=function(){const e="sqlite3_bind_blob",s=t.cwrap(e,...xt("nnnnn:n"));return function(r,i,o){d(r);const a=o.byteLength??o.length,c=t._sqlite3_malloc(a);t.HEAPU8.subarray(c).set(o);const l=s(r,i,c,a,n);return p(e,l,h.get(r))}}(),e.bind_parameter_count=function(){const e=t.cwrap("sqlite3_bind_parameter_count",...xt("n:n"));return function(t){return d(t),e(t)}}(),e.bind_double=function(){const e="sqlite3_bind_double",n=t.cwrap(e,...xt("nnn:n"));return function(t,s,r){d(t);const i=n(t,s,r);return p(e,i,h.get(t))}}(),e.bind_int=function(){const e="sqlite3_bind_int",n=t.cwrap(e,...xt("nnn:n"));return function(t,s,r){if(d(t),r>2147483647||r<-2147483648)return 25;const i=n(t,s,r);return p(e,i,h.get(t))}}(),e.bind_int64=function(){const e="sqlite3_bind_int64",n=t.cwrap(e,...xt("nnnn:n"));return function(t,s,r){if(d(t),r>Ct||r<At)return 25;const i=r>>32n,o=n(t,s,Number(0xffffffffn&r),Number(i));return p(e,o,h.get(t))}}(),e.bind_null=function(){const e="sqlite3_bind_null",n=t.cwrap(e,...xt("nn:n"));return function(t,s){d(t);const r=n(t,s);return p(e,r,h.get(t))}}(),e.bind_parameter_name=function(){const e=t.cwrap("sqlite3_bind_parameter_name",...xt("n:s"));return function(t,n){return d(t),e(t,n)}}(),e.bind_text=function(){const e="sqlite3_bind_text",s=t.cwrap(e,...xt("nnnnn:n"));return function(t,r,i){d(t);const a=o(i),c=s(t,r,a,-1,n);return p(e,c,h.get(t))}}(),e.changes=function(){const e=t.cwrap("sqlite3_changes",...xt("n:n"));return function(t){return u(t),e(t)}}(),e.clear_bindings=function(){const e="sqlite3_clear_bindings",n=t.cwrap(e,...xt("n:n"));return function(t){d(t);const s=n(t);return p(e,s,h.get(t))}}(),e.last_insert_id=function(){const e=t.cwrap("sqlite3_last_insert_rowid",...xt("n:n"));return function(t){return u(t),e(t)}}(),e.close=function(){const e="sqlite3_close",n=t.cwrap(e,...xt("n:n"),{async:Lt});return async function(t){u(t);const s=await n(t);return l.delete(t),p(e,s,t)}}(),e.column=function(n,s){d(n);const r=e.column_type(n,s);switch(r){case 4:return e.column_blob(n,s);case 2:return e.column_double(n,s);case 1:const i=e.column_int(n,s),o=t.getTempRet0();return c(i,o);case 5:return null;case 3:return e.column_text(n,s);default:throw new Tt("unknown type",r)}},e.column_blob=function(){const n=t.cwrap("sqlite3_column_blob",...xt("nn:n"));return function(s,r){d(s);const i=e.column_bytes(s,r),o=n(s,r);return t.HEAPU8.subarray(o,o+i)}}(),e.column_bytes=function(){const e=t.cwrap("sqlite3_column_bytes",...xt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_count=function(){const e=t.cwrap("sqlite3_column_count",...xt("n:n"));return function(t){return d(t),e(t)}}(),e.column_double=function(){const e=t.cwrap("sqlite3_column_double",...xt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_int=function(){const e=t.cwrap("sqlite3_column_int64",...xt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_int64=function(){const e=t.cwrap("sqlite3_column_int64",...xt("nn:n"));return function(n,s){return d(n),a(e(n,s),t.getTempRet0())}}(),e.column_name=function(){const e=t.cwrap("sqlite3_column_name",...xt("nn:s"));return function(t,n){return d(t),e(t,n)}}(),e.column_names=function(t){const n=[],s=e.column_count(t);for(let r=0;r<s;++r)n.push(e.column_name(t,r));return n},e.column_text=function(){const e=t.cwrap("sqlite3_column_text",...xt("nn:s"));return function(t,n){return d(t),e(t,n)}}(),e.column_type=function(){const e=t.cwrap("sqlite3_column_type",...xt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.create_function=function(e,n,s,r,i,o,a,c){function l(e){return e instanceof Pt?async(n,s,r)=>e(n,t.HEAP32.subarray(r/4,r/4+s)):(n,s,r)=>e(n,t.HEAP32.subarray(r/4,r/4+s))}return u(e),p("sqlite3_create_function",t.create_function(e,n,s,r,i,o&&l(o),a&&l(a),c),e)},e.data_count=function(){const e=t.cwrap("sqlite3_data_count",...xt("n:n"));return function(t){return d(t),e(t)}}(),e.exec=async function(t,n,s){for await(const r of e.statements(t,n)){let t;for(;100===await e.step(r);)if(s){t=t??e.column_names(r);const n=e.row(r);await s(n,t)}}return 0},e.finalize=function(){const e=t.cwrap("sqlite3_finalize",...xt("n:n"),{async:Lt});return async function(t){const n=await e(t);return h.delete(t),n}}(),e.get_autocommit=function(){const e=t.cwrap("sqlite3_get_autocommit",...xt("n:n"));return function(t){return e(t)}}(),e.libversion=function(){const e=t.cwrap("sqlite3_libversion",...xt(":s"));return function(){return e()}}(),e.libversion_number=function(){const e=t.cwrap("sqlite3_libversion_number",...xt(":n"));return function(){return e()}}(),e.limit=function(){const e=t.cwrap("sqlite3_limit",...xt("nnn:n"));return function(t,n,s){return e(t,n,s)}}(),e.open_v2=function(){const e="sqlite3_open_v2",n=t.cwrap(e,...xt("snnn:n"),{async:Lt});return async function(s,i,a){i=i||6,a=o(a);try{const o=await g(()=>n(s,r[0],i,a)),c=t.getValue(r[0],"*");return l.add(c),t.ccall("RegisterExtensionFunctions","number",["number"],[c]),p(e,o),c}finally{t._sqlite3_free(a)}}}(),e.progress_handler=function(e,n,s,r){u(e),t.progress_handler(e,n,s,r)},e.reset=function(){const e="sqlite3_reset",n=t.cwrap(e,...xt("n:n"),{async:Lt});return async function(t){d(t);const s=await n(t);return p(e,s,h.get(t))}}(),e.result=function(t,n){switch(typeof n){case"number":n===(0|n)?e.result_int(t,n):e.result_double(t,n);break;case"string":e.result_text(t,n);break;default:if(n instanceof Uint8Array||Array.isArray(n))e.result_blob(t,n);else if(null===n)e.result_null(t);else{if("bigint"==typeof n)return e.result_int64(t,n);console.warn("unknown result converted to null",n),e.result_null(t)}}},e.result_blob=function(){const e=t.cwrap("sqlite3_result_blob",...xt("nnnn:n"));return function(s,r){const i=r.byteLength??r.length,o=t._sqlite3_malloc(i);t.HEAPU8.subarray(o).set(r),e(s,o,i,n)}}(),e.result_double=function(){const e=t.cwrap("sqlite3_result_double",...xt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int=function(){const e=t.cwrap("sqlite3_result_int",...xt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int64=function(){const e=t.cwrap("sqlite3_result_int64",...xt("nnn:n"));return function(t,n){if(n>Ct||n<At)return 25;const s=n>>32n;e(t,Number(0xffffffffn&n),Number(s))}}(),e.result_null=function(){const e=t.cwrap("sqlite3_result_null",...xt("n:n"));return function(t){e(t)}}(),e.result_text=function(){const e=t.cwrap("sqlite3_result_text",...xt("nnnn:n"));return function(t,s){const r=o(s);e(t,r,-1,n)}}(),e.row=function(n){const s=[],r=e.data_count(n);for(let i=0;i<r;++i){const r=e.column(n,i);s.push(r?.buffer===t.HEAPU8.buffer?r.slice():r)}return s},e.set_authorizer=function(e,n,s){function r(e,n,s,r,i,o){return[e,n,t.UTF8ToString(s),t.UTF8ToString(r),t.UTF8ToString(i),t.UTF8ToString(o)]}var i;return u(e),p("sqlite3_set_authorizer",t.set_authorizer(e,(i=n)instanceof Pt?async(t,e,n,s,o,a)=>i(...r(t,e,n,s,o,a)):(t,e,n,s,o,a)=>i(...r(t,e,n,s,o,a)),s),e)},e.sql=function(){const e=t.cwrap("sqlite3_sql",...xt("n:s"));return function(t){return d(t),e(t)}}(),e.statements=function(n,s,r={}){const o=t.cwrap("sqlite3_prepare_v3","number",["number","number","number","number","number","number"],{async:!0});return async function*(){const a=[];try{const c=i.encode(s),l=c.byteLength-c.byteLength%4+12,u=t._sqlite3_malloc(l),d=u+c.byteLength+1;a.push(()=>t._sqlite3_free(u)),t.HEAPU8.set(c,u),t.HEAPU8[d-1]=0;const m=u+l-8,f=u+l-4;let w;function y(){w&&!r.unscoped&&e.finalize(w),w=0}a.push(y),t.setValue(f,u,"*");do{y();const b=t.getValue(f,"*"),S=await g(()=>o(n,b,d-f,r.flags||0,m,f));0!==S&&p("sqlite3_prepare_v3",S,n),w=t.getValue(m,"*"),w&&(h.set(w,n),yield w)}while(w)}finally{for(;a.length;)a.pop()()}}()},e.step=function(){const e="sqlite3_step",n=t.cwrap(e,...xt("n:n"),{async:Lt});return async function(t){d(t);const s=await g(()=>n(t));return p(e,s,h.get(t),[100,101])}}(),e.commit_hook=function(e,n){u(e),t.commit_hook(e,n)},e.update_hook=function(e,n){function s(e,n,s,r,i){return[e,t.UTF8ToString(n),t.UTF8ToString(s),a(r,i)]}var r;u(e),t.update_hook(e,(r=n)instanceof Pt?async(t,e,n,i,o)=>r(...s(t,e,n,i,o)):(t,e,n,i,o)=>r(...s(t,e,n,i,o)))},e.value=function(n){const s=e.value_type(n);switch(s){case 4:return e.value_blob(n);case 2:return e.value_double(n);case 1:const r=e.value_int(n),i=t.getTempRet0();return c(r,i);case 5:return null;case 3:return e.value_text(n);default:throw new Tt("unknown type",s)}},e.value_blob=function(){const n=t.cwrap("sqlite3_value_blob",...xt("n:n"));return function(s){const r=e.value_bytes(s),i=n(s);return t.HEAPU8.subarray(i,i+r)}}(),e.value_bytes=function(){const e=t.cwrap("sqlite3_value_bytes",...xt("n:n"));return function(t){return e(t)}}(),e.value_double=function(){const e=t.cwrap("sqlite3_value_double",...xt("n:n"));return function(t){return e(t)}}(),e.value_int=function(){const e=t.cwrap("sqlite3_value_int64",...xt("n:n"));return function(t){return e(t)}}(),e.value_int64=function(){const e=t.cwrap("sqlite3_value_int64",...xt("n:n"));return function(n){return a(e(n),t.getTempRet0())}}(),e.value_text=function(){const e=t.cwrap("sqlite3_value_text",...xt("n:s"));return function(t){return e(t)}}(),e.value_type=function(){const e=t.cwrap("sqlite3_value_type",...xt("n:n"));return function(t){return e(t)}}(),e.vfs_register=function(e,n){return p("sqlite3_vfs_register",t.vfs_register(e,n))},e}(t);if(n.vfs_register(e,!0),t.ccall("powersync_init_static","int",[]),this.options.encryptionKey){if(0!==t.ccall("sqlite3mc_vfs_create","int",["string","int"],[this.options.filename,1]))throw new Error("Failed to create multiple cipher vfs, Database encryption will not work")}return n}requireSqlite(){if(!this._sqliteAPI)throw new Error("Initialization has not completed");return this._sqliteAPI}isAutoCommit(){return 0!=this.requireSqlite().get_autocommit(this.db)}async execute(t,e){const n=await this.executeSingleStatementRaw(t,e);return this.wrapQueryResults(this.requireSqlite(),n)}async executeBatch(t,e){const n=[],s=this.requireSqlite();for await(const r of s.statements(this.db,t)){let t;for(const i of e){const e=await this.stepThroughStatement(s,r,i,t,!1);n.push(this.wrapQueryResults(s,e))}break}return n}wrapQueryResults(t,{rawRows:e,columnNames:n}){return{rowsAffected:t.changes(this.db),insertId:t.last_insert_id(this.db),autocommit:0!=t.get_autocommit(this.db),rawRows:e,columnNames:n}}async executeSingleStatementRaw(t,e){const n=await this.executeRaw(t,e);return n.length?n[0]:{columnNames:[],rawRows:[]}}async executeRaw(t,e){const n=[],s=this.requireSqlite();for await(const r of this.cachedStatements(s,t)){let t;const i=await this.stepThroughStatement(s,r,e??[],t);if(t=i.columnNames,t.length&&n.push(i),e)break}return n}async stepThroughStatement(t,e,n,s,r=!0){n.forEach((t,e,n)=>{"boolean"==typeof t&&(n[e]=t?1:0)}),t.reset(e),n&&t.bind_collection(e,n);const i=[];for(;100===await t.step(e);)if(r){const n=t.row(e);i.push(n)}return s??=t.column_names(e),{columnNames:s,rawRows:i}}async close(){if(this.isOpen){const t=this.requireSqlite();if(this.statementCache)for(const e of this.statementCache.drain())await t.finalize(e);await t.close(this.db),this.db=0}}async*cachedStatements(t,e){{const t=this.statementCache?.lookup(e);if(null!=t)return void(yield t)}const n=t.statements(this.db,e,{unscoped:!0}),s=[];try{for await(const t of n)s.push(t),yield t}finally{if(1===s.length&&this.statementCache){const n=s[0];if(0==this.sqlite3_stmt_isexplain(n)){const s=this.statementCache.addStatement(e,n);return void(null!=s&&await t.finalize(s))}}for(const e of s)await t.finalize(e)}}}var Ut,Dt;async function Nt(t,e,n){const{rawRows:s}=await t.executeRaw("SELECT CAST(powersync_control(?, ?) AS TEXT)",[e,n]);return s[0][0]}function Ft(t,e=null){return Nt(t,"target_checkpoint_request_id",e)}!function(t){t.DATA="ps_data",t.CRUD="ps_crud",t.BUCKETS="ps_buckets",t.OPLOG="ps_oplog",t.UNTYPED="ps_untyped"}(Ut||(Ut={})),function(t){t.PROCESS_TEXT_LINE="line_text",t.PROCESS_BSON_LINE="line_binary",t.STOP="stop",t.START="start",t.NOTIFY_TOKEN_REFRESHED="refreshed_token",t.NOTIFY_CRUD_UPLOAD_COMPLETED="completed_upload",t.UPDATE_SUBSCRIPTIONS="update_subscriptions",t.CONNECTION_STATE="connection"}(Dt||(Dt={}));const $t=2147483647,Bt="9223372036854775807";class Wt{internal;totalOperations;downloadedOperations;downloadedFraction;constructor(t){this.internal=t;const e=this.untilPriority($t);this.totalOperations=e.totalOperations,this.downloadedOperations=e.downloadedOperations,this.downloadedFraction=e.downloadedFraction}untilPriority(t){let e=0,n=0;for(const s of Object.values(this.internal.buckets))s.priority<=t&&(n+=s.since_last,e+=s.target_count-s.at_last);return{totalOperations:e,downloadedOperations:n,downloadedFraction:0==e?0:n/e}}}class zt{core;jsState;constructor(t,e){this.core=t,this.jsState=e}get connected(){return this.core?.connected??!1}get connecting(){return this.core?.connecting??!1}get downloading(){return null!=this.core?.downloading}get uploading(){return this.jsState.uploading??!1}get downloadError(){return this.jsState.downloadError}get uploadError(){return this.jsState.uploadError}get dataFlowStatus(){return{downloading:this.downloading,uploading:this.uploading,downloadError:this.downloadError,uploadError:this.uploadError}}get lastSyncedAt(){return this.statusForPriority($t)?.lastSyncedAt}get hasSynced(){return this.statusForPriority($t)?.hasSynced}get syncStreams(){return this.core?.streams.map(t=>new Ht(this,t))}forStream(t){const e=JSON.stringify(t.parameters),n=this.core?.streams?.find(n=>n.name==t.name&&e==JSON.stringify(n.parameters));return n&&new Ht(this,n)}get priorityStatusEntries(){return this.core?.priority_status.map(jt)}get downloadProgress(){const t=this.core?.downloading;return null==t?null:new Wt(t)}statusForPriority(t){const e=this.core?.priority_status;if(null!=e){for(const n of e)if(n.priority>=t)return jt(n);return{priority:t,lastSyncedAt:void 0,hasSynced:!1}}}isEqual(t){const e=(t,e)=>e instanceof Error?this.serializeError(e):e,n={core:this.core,jsState:this.jsState},s=t,r={core:s.core,jsState:s.jsState};return JSON.stringify(n,e)==JSON.stringify(r,e)}getMessage(){return`SyncStatus<connected: ${this.connected} connecting: ${this.connecting} lastSyncedAt: ${this.lastSyncedAt} hasSynced: ${this.hasSynced}. Downloading: ${this.downloading}. Uploading: ${this.uploading}. UploadError: ${this.uploadError}, DownloadError?: ${this.downloadError}>`}toJSON(){return{core:this.core,dataFlow:{uploading:this.uploading,uploadError:this.serializeError(this.uploadError),downloadError:this.serializeError(this.downloadError)}}}serializeError(t){if(void 0===t)return;const e={name:t.name,message:t.message,stack:t.stack};return void 0!==t.cause&&(e.cause=t.cause instanceof Error?this.serializeError(t.cause):t.cause),e}}function jt(t){return{priority:t.priority,hasSynced:t.has_synced??void 0,lastSyncedAt:(e=t.last_synced_at,null==e?void 0:new Date(e/1e3))};var e}class Ht{status;core;subscription;constructor(t,e){this.status=t,this.core=e,this.subscription={name:e.name,parameters:e.parameters,active:e.active,isDefault:e.is_default,hasExplicitSubscription:e.has_explicit_subscription,expiresAt:null!=e.expires_at?new Date(1e3*e.expires_at):null,hasSynced:null!=e.last_synced_at,lastSyncedAt:null!=e.last_synced_at?new Date(1e3*e.last_synced_at):null}}get progress(){if(null==this.status.core?.downloading)return null;const{total:t,downloaded:e}=this.core.progress;return{totalOperations:t,downloadedOperations:e,downloadedFraction:0==t?0:e/t}}get priority(){return this.core.priority}}function Vt(t,e){return{appMetadata:t.appMetadata??{},connectionMethod:t.connectionMethod??e,fetchStrategy:t.fetchStrategy??x.Buffered,params:t.params??{},includeDefaultStreams:t.includeDefaultStreams??!0,retryDelayMs:t.retryDelayMs??5e3,crudUploadThrottleMs:t.crudUploadThrottleMs??1e3}}class Jt extends k{options;connectingPromise;syncStreamInitPromise;disconnectingPromise;pendingConnectionOptions;currentOptions;syncStreamImplementation;syncDisposer;locallyActiveSubscriptions=new Map;constructor(t){super(),this.options=t,this.connectingPromise=null,this.syncStreamInitPromise=null,this.disconnectingPromise=null,this.pendingConnectionOptions=null,this.syncStreamImplementation=null,this.currentOptions=null,this.syncDisposer=null}get connector(){return this.pendingConnectionOptions?.connector??null}get connectionOptions(){return this.currentOptions??this.pendingConnectionOptions?.options??null}get logger(){return this.options.logger}async close(){await(this.syncStreamImplementation?.dispose()),await(this.syncDisposer?.())}async connect(t,e,n){const s=!!this.pendingConnectionOptions;this.pendingConnectionOptions={connector:t,options:Vt(e,this.options.defaultConnectionMethod),schema:n},s&&!this.syncStreamImplementation||await this.disconnectInternal();const r=async()=>this.pendingConnectionOptions?(this.connectingPromise=this.connectInternal().catch(()=>{}).finally(r),this.connectingPromise):void(this.connectingPromise=null);return this.connectingPromise??=this.connectInternal().catch(()=>{}).finally(r),this.connectingPromise}async connectInternal(){let t=null;await this.disconnectInternal(),this.syncStreamInitPromise=new Promise(async(e,n)=>{try{if(!this.pendingConnectionOptions)return this.logger.log({level:_.debug,message:"No pending connection options found, not creating sync stream implementation"}),void e();if(this.disconnectingPromise)return void e();const{connector:n,options:s,schema:r}=this.pendingConnectionOptions;t=s,this.currentOptions=s,this.pendingConnectionOptions=null;const{sync:i,onDispose:o}=await this.options.createSyncImplementation(n,{subscriptions:this.activeStreams,serializedSchema:r});this.iterateListeners(t=>t.syncStreamCreated?.(i)),this.syncStreamImplementation=i,this.syncDisposer=o,await this.syncStreamImplementation.waitForReady(),e()}catch(t){n(t)}}),await this.syncStreamInitPromise,this.syncStreamInitPromise=null,t&&(await this.disconnectingPromise,this.logger.log({level:_.debug,message:"Attempting to connect to PowerSync instance"}),await(this.syncStreamImplementation?.connect(t)))}async disconnect(){this.pendingConnectionOptions=null,this.currentOptions=null,await this.disconnectInternal()}async disconnectInternal(){if(this.disconnectingPromise)return this.disconnectingPromise;this.disconnectingPromise=this.performDisconnect(),await this.disconnectingPromise,this.disconnectingPromise=null}async performDisconnect(){await this.syncStreamInitPromise;const t=this.syncStreamImplementation;this.syncStreamImplementation=null;const e=this.syncDisposer;this.syncDisposer=null,await(t?.disconnect()),await(t?.dispose()),await(e?.())}stream(t,e,n){const s={name:e,parameters:n},r=e=>t.firstStatusMatching(t=>t.forStream(s)?.subscription.hasSynced,e);return{...s,subscribe:async s=>{await t.rustSubscriptionsCommand({subscribe:{stream:{name:e,params:n},ttl:s?.ttl,priority:s?.priority}}),this.syncStreamImplementation||await t.resolveOfflineSyncStatus();const i=`${e}|${JSON.stringify(n)}`;let o=this.locallyActiveSubscriptions.get(i);if(null==o){const t=()=>{this.locallyActiveSubscriptions.delete(i),this.subscriptionsMayHaveChanged()};o=new Gt(e,n,this.logger,r,t),this.locallyActiveSubscriptions.set(i,o),this.subscriptionsMayHaveChanged()}return new Kt(o)},unsubscribeAll:async()=>{await t.rustSubscriptionsCommand({unsubscribe:{name:e,params:n}}),this.subscriptionsMayHaveChanged()}}}get activeStreams(){return[...this.locallyActiveSubscriptions.values()].map(t=>({name:t.name,params:t.parameters}))}subscriptionsMayHaveChanged(){this.syncStreamImplementation?.updateSubscriptions(this.activeStreams)}}class Gt{name;parameters;logger;waitForFirstSync;clearSubscription;refcount=0;constructor(t,e,n,s,r){this.name=t,this.parameters=e,this.logger=n,this.waitForFirstSync=s,this.clearSubscription=r}decrementRefCount(){this.refcount--,0==this.refcount&&this.clearSubscription()}}class Kt{subscription;active=!0;constructor(t){this.subscription=t,t.refcount++,Qt?.register(this,t,this)}get name(){return this.subscription.name}get parameters(){return this.subscription.parameters}waitForFirstSync(t){return this.subscription.waitForFirstSync(t)}unsubscribe(){this.active&&(this.active=!1,Qt?.unregister(this),this.subscription.decrementRefCount())}}const Qt="FinalizationRegistry"in globalThis?new FinalizationRegistry(t=>{t.logger.log({level:_.warn,message:`A subscription to ${t.name} with params ${JSON.stringify(t.parameters)} leaked! Please ensure calling unsubscribe() when you don't need a subscription anymore. For global subscriptions, consider storing them in global fields to avoid this warning.`})}):null;class Yt{table;head;_length;constructor(t){this.table=[...t],this.head=0,this._length=this.table.length}get isEmpty(){return 0==this.length}get length(){return this._length}removeFirst(){if(this.isEmpty)throw new Error("Queue is empty");const t=this.table[this.head];return this._length--,this.table[this.head]=void 0,this.head=(this.head+1)%this.table.length,t}addLast(t){if(this.length==this.table.length)throw new Error("Queue is full");this.table[(this.head+this._length)%this.table.length]=t,this._length++}}class Xt{available;size;firstWaiter;lastWaiter;constructor(t){this.available=new Yt(t),this.size=this.available.length}addWaiter(t,e){const n={isActive:!0,acquiredItems:[],remainingItems:t,onAcquire:e,prev:this.lastWaiter};return this.lastWaiter?(this.lastWaiter.next=n,this.lastWaiter=n):this.lastWaiter=this.firstWaiter=n,n}deactivateWaiter(t){const{prev:e,next:n}=t;t.isActive=!1,e&&(e.next=n),n&&(n.prev=e),t==this.firstWaiter&&(this.firstWaiter=n),t==this.lastWaiter&&(this.lastWaiter=e)}requestPermits(t,e){if(t<=0||t>this.size)throw new Error(`Invalid amount of items requested (${t}), must be between 1 and ${this.size}`);return new Promise((n,s)=>{function r(){s(e?.reason??new Error("Semaphore acquire aborted"))}if(e?.aborted)return r();let i;const o=()=>{const t=i.acquiredItems;i.acquiredItems=[];for(const e of t){const t=this.firstWaiter;t?(t.acquiredItems.push(e),t.remainingItems--,0==t.remainingItems&&t.onAcquire()):this.available.addLast(e)}},a=()=>{e?.removeEventListener("abort",a),i.isActive&&(this.deactivateWaiter(i),r())},c=()=>{this.deactivateWaiter(i),e?.removeEventListener("abort",a);const t=i.acquiredItems;n({items:t,release:o})};for(i=this.addWaiter(t,c);!this.available.isEmpty&&i.remainingItems>0;)i.acquiredItems.push(this.available.removeFirst()),i.remainingItems--;if(0==i.remainingItems)return c();e?.addEventListener("abort",a)})}async requestOne(t){const{items:e,release:n}=await this.requestPermits(1,t);return{release:n,item:e[0]}}requestAll(t){return this.requestPermits(this.size,t)}}class Zt{inner=new Xt([null]);async acquire(t){const{release:e}=await this.inner.requestOne(t);return e}async runExclusive(t,e){const n=await this.acquire(e);try{return await t()}finally{n()}}}class te{clientId;id;op;opData;previousValues;table;transactionId;metadata;static fromRow(t){const e=JSON.parse(t.data);return new te(parseInt(t.id),e.op,e.type,e.id,t.tx_id,e.data,e.old,e.metadata)}constructor(t,e,n,s,r,i,o,a){this.clientId=t,this.id=s,this.op=e,this.opData=i,this.table=n,this.transactionId=r,this.previousValues=o,this.metadata=a}toJSON(){return{op_id:this.clientId,op:this.op,type:this.table,id:this.id,tx_id:this.transactionId,data:this.opData,old:this.previousValues,metadata:this.metadata}}equals(t){return JSON.stringify(this.toComparisonArray())==JSON.stringify(t.toComparisonArray())}toComparisonArray(){return[this.transactionId,this.clientId,this.op,this.table,this.id,this.opData,this.previousValues,this.metadata]}}const ee=Symbol.asyncIterator??Symbol.for("Symbol.asyncIterator"),ne={done:!0,value:void 0};function se(t){return{done:!1,value:t}}function re(t){let e,n=!1,s=null,r=!1,i=[];const o=()=>{const t=e;return e=void 0,t};return{next:()=>new Promise((a,c)=>n?a(ne):s?(s({resolve:a,reject:c}),void(s=null)):i.length?a(se(i.shift())):(e={resolve:a,reject:c},void(r||(()=>{const e=t=>{r=!1;const e=o();e?t(e):s=t};r=!0,t.next().then(t=>{n=1==t.done,e(e=>e.resolve(t))},t=>{e(e=>e.reject(t))})})()))),inject:t=>{const e=o();null!=e?e.resolve(se(t)):i.push(t)}}}class ie{options;waitingConsumer;outstandingEvents;constructor(t={}){this.options=t,this.outstandingEvents=[]}get countOutstandingEvents(){return this.outstandingEvents.length}notifyInner(t){const e=this.waitingConsumer;this.waitingConsumer=void 0;const n=e=>{t(e),this.options.eventDelivered?.()};e?n(e):this.outstandingEvents.push(n)}notify(t){this.notifyInner(e=>e.resolve(t))}notifyError(t){this.notifyInner(e=>e.reject(t))}waitForEvent(t){return new Promise((e,n)=>{if(null!=this.waitingConsumer)throw new Error("Illegal call to waitForEvent, already has a waiter.");const s=()=>{t?.removeEventListener("abort",r)},r=()=>{s(),this.waitingConsumer=void 0,e(void 0)},i={resolve:t=>{s(),e(t)},reject:t=>{s(),n(t)}};if(t.aborted)e(void 0);else if(this.countOutstandingEvents>0){const[t]=this.outstandingEvents.splice(0,1);t(i)}else this.waitingConsumer=i,t.addEventListener("abort",r)})}static queueBasedAsyncIterable(t,e){return{[ee]:()=>{const n=new ie,s=new AbortController;function r(){s.abort(),e?.removeEventListener("abort",r)}return e&&(e.aborted?s.abort():e.addEventListener("abort",r)),t(n,s.signal),{async next(){const t=await n.waitForEvent(s.signal);return null==t?ne:se(t)},return:async()=>(r(),ne)}}}}}class oe extends k{db;logger;updateListener;_clientId;constructor(t,e){super(),this.db=t,this.logger=e,this.updateListener=t.registerListener({tablesUpdated:({tables:t})=>{t.includes(Ut.CRUD)&&this.iterateListeners(t=>t.crudUpdate?.())}})}async dispose(){this.updateListener?.()}async _getClientId(){return(await this.db.get("SELECT powersync_client_id() as client_id")).client_id}getClientId(){return null==this._clientId&&(this._clientId=this._getClientId()),this._clientId}async updateLocalTarget(t){const e=await this.db.readTransaction(async t=>{if(await Ft(t)!=Bt)return;const e=await t.getOptional("SELECT seq FROM main.sqlite_sequence WHERE name = 'ps_crud'");return e?.seq});if(null==e)return!1;const n=await t();return this.writeTransaction(async t=>{const s=await t.execute("SELECT 1 FROM ps_crud LIMIT 1");if(s.rows?.length)return this.logger.log({level:_.debug,message:`New data uploaded since write checkpoint ${n} - need new write checkpoint`}),!1;const{seq:r}=await t.get("SELECT seq FROM main.sqlite_sequence WHERE name = 'ps_crud'");return r!=e?(this.logger.log({level:_.debug,message:`New data uploaded since write checpoint ${n} - need new write checkpoint (sequence updated)`}),!1):(this.logger.log({level:_.debug,message:`Updating target write checkpoint to ${n}`}),await Ft(t,n),!0)})}async nextCrudItem(){const t=await this.db.getOptional("SELECT * FROM ps_crud ORDER BY id ASC LIMIT 1");if(t)return te.fromRow(t)}async hasCrud(){return!!await this.db.getOptional("SELECT 1 FROM ps_crud LIMIT 1")}async getCrudBatch(t=100){if(!await this.hasCrud())return null;const e=await this.db.getAll("SELECT * FROM ps_crud ORDER BY id ASC LIMIT ?",[t]),n=[];for(const t of e)n.push(te.fromRow(t));if(0===n.length)return null;const s=n[n.length-1];return{crud:n,haveMore:!0,complete:async t=>this.handleCrudCheckpoint(s.clientId,t)}}handleCrudCheckpoint(t,e){return this.writeTransaction(async n=>{if(await n.execute("DELETE FROM ps_crud WHERE id <= ?",[t]),e){const t=await n.execute("SELECT 1 FROM ps_crud LIMIT 1");t.rows?.length&&await Ft(n,e)}else await Ft(n,Bt)})}async writeTransaction(t,e){return this.db.writeTransaction(t,e)}async control(t,e){return await this.writeTransaction(async n=>await Nt(n,t,e))}async hasMigratedSubkeys(){const{r:t}=await this.db.get("SELECT EXISTS(SELECT * FROM ps_kv WHERE key = ?) as r",[oe._subkeyMigrationKey]);return 0!=t}async migrateToFixedSubkeys(){await this.writeTransaction(async t=>{await t.execute("UPDATE ps_oplog SET key = powersync_remove_duplicate_key_encoding(key);"),await t.execute("INSERT OR REPLACE INTO ps_kv (key, value) VALUES (?, ?);",[oe._subkeyMigrationKey,"1"])})}static _subkeyMigrationKey="powersync_js_migrated_subkeys"}class ae extends Error{reason;constructor(t){super(t),this.reason=t,Object.setPrototypeOf(this,ae.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ae)}}const ce=/\/+$/,le={LogLevels:_,EventQueue:ie,AbortOperation:ae};class ue{connector;logger;credentials=null;constructor(t,e){this.connector=t,this.logger=e}async getCredentials(){return this.credentials?this.credentials:this.prefetchCredentials()}async prefetchCredentials(){return this.credentials=await this.fetchCredentials(),this.credentials}async fetchCredentials(){const t=await this.connector.fetchCredentials();if(t?.endpoint.match(ce))throw new Error(`A trailing forward slash "/" was found in the fetchCredentials endpoint: "${t.endpoint}". Remove the trailing forward slash "/" to fix this error.`);return t}invalidateCredentials(){this.credentials=null,this.connector.invalidateCredentials?.()}getUserAgent(){return"powersync-js/1.1.1"}async buildRequest(t){const e=await this.getCredentials();if(null!=e&&(null==e.endpoint||""==e.endpoint))throw new Error("PowerSync endpoint not configured");if(null==e?.token||""==e?.token){const t=new Error("Not signed in");throw t.status=401,t}const n=this.getUserAgent();return{url:e.endpoint+t,headers:{"content-type":"application/json",Authorization:`Token ${e.token}`,"x-user-agent":n},userAgent:n,path:t}}async get(t,e){const n=await this.buildRequest(t),s=await this.fetch({resource:n.url,request:{method:"GET",headers:{...e,...n.headers}},expectStreamingResponse:!1});if(401===s.status&&this.invalidateCredentials(),!s.ok)throw new Error(`Received ${s.status} - ${s.statusText} when getting from ${t}: ${await s.text()}}`);return s.json()}createTextDecoder(){return new TextDecoder}createSocket(t){return new WebSocket(t)}async socketStreamRaw(t){const e=await this.loadWebSocketSupport(le),n=await this.buildRequest(t.path);n.url=n.url.replace(/^https?:\/\//,function(t){return"https://"===t?"wss://":"ws://"});const{fetchStrategy:s=x.Buffered,abortSignal:r,data:i}=t;return await e.webSocketSyncStream({remote:this,buffered:s==x.Buffered,abortSignal:r,requestPayload:i,request:n})}async fetchStreamRaw(t){const{data:e,path:n,abortSignal:s}=t,r=await this.buildRequest(n);if(s.aborted)throw new ae("Abort request received before making fetchStreamRaw request");const i=new AbortController;let o,a=null;s.addEventListener("abort",()=>{const t=s.reason??new ae("Cancelling network request before it resolves. Abort signal has been received.");null==a?i.abort(t):a.cancel(t).catch(()=>{})});let c=!1;try{const t="application/x-ndjson",s="application/vnd.powersync.bson-stream";if(o=await this.fetch({resource:r.url,request:{method:"POST",headers:{...r.headers,accept:`${s};q=0.9,${t};q=0.8`},body:JSON.stringify(e),signal:i.signal,cache:"no-store"},expectStreamingResponse:!0}),!o.ok||!o.body){const t=await o.text(),e=new Error(`HTTP ${o.statusText}: ${t}`);throw e.status=o.status,this.logger.log({level:_.error,message:`Could not POST streaming to ${n} - ${o.status} - ${o.statusText}: ${t}`,error:e}),401===o.status&&this.invalidateCredentials(),e}c=o.headers.get("content-type")==s}catch(t){if("AbortError"==t.name)throw new ae(`Pending fetch request to ${r.url} has been aborted.`);throw t}a=o.body.getReader();return{isBson:c,stream:{next:async()=>{if(i.signal.aborted)return ne;try{return await a.read()}catch(t){if(i.signal.aborted)return ne;throw t}}}}}async fetchStream(t){const{isBson:e,stream:n}=await this.fetchStreamRaw(t);return e?function(t){const e=[];let n=!1;const s=new DataView(new ArrayBuffer(4));let r=null,i=4;return{async next(){for(;;){if(e.length)return se(e.shift());if(n)return ne;const o=await t.next();if(o.done){if(n=!0,r||4!=i)throw new Error("illegal end of stream in BSON object");return ne}const a=o.value;for(let t=0;t<a.length;){const n=a.length-t;if(r){const s=Math.min(n,i),o=new Uint8Array(a.buffer,a.byteOffset+t,s);r.set(o,r.length-i),t+=s,i-=s,0==i&&(e.push(r),r=null,i=4)}else{const e=Math.min(n,i);for(let n=0;n<e;n++)s.setUint8(4-i+n,a[t+n]);if(t+=e,i-=e,0==i){const t=s.getInt32(0,!0);if(i=t-4,i<1)throw new Error(`invalid length for bson: ${t}`);r=new Uint8Array(t),new DataView(r.buffer).setInt32(0,t,!0)}}}}}}}(n):function(t,e){let n="";const s=[];let r=!1;return{next:async()=>{for(;;){if(r)return ne;{const t=s.shift();if(t)return{done:!1,value:t}}const{done:i,value:o}=await t.next();if(i){const t=n.trim();return 0!=t.length?(r=!0,{done:!1,value:t}):ne}const a=e.decode(o,{stream:!0});n+=a;const c=n.split("\n");for(let t=0;t<c.length-1;t++){const e=c[t].trim();e.length>0&&s.push(e)}n=c[c.length-1]}}}}(n,this.createTextDecoder())}}function he(t){return"EstablishSyncStream"in t||"CloseSyncStream"in t}var de;!function(t){t.CRUD="crud",t.SYNC="sync"}(de||(de={}));class pe extends k{options;abortController;crudUpdateListener;streamingSyncPromise;logger;activeStreams;connectionMayHaveChanged=!1;crudUploadNotifier=function(){const t=new ie;return{notify(){t.countOutstandingEvents>0||t.notify()},waitForNotification:e=>t.waitForEvent(e)}}();notifyCompletedUploads;handleActiveStreamsChange;syncStatus;constructor(t){super(),this.options=t,this.activeStreams=t.subscriptions,this.logger=t.logger,this.syncStatus=new zt(null,{}),this.abortController=null}triggerCrudUpload(){this.crudUploadNotifier.notify()}async waitForReady(){}waitUntilStatusMatches(t){return new Promise(e=>{if(t(this.syncStatus))return void e();const n=this.registerListener({statusChanged:()=>{t(this.syncStatus)&&(e(),n?.())}})})}get lastSyncedAt(){const t=this.syncStatus.lastSyncedAt;return t&&new Date(t)}get isConnected(){return this.syncStatus.connected}async dispose(){super.dispose(),this.crudUpdateListener?.(),this.crudUpdateListener=void 0}async getWriteCheckpoint(){let t=`/write-checkpoint2.json?client_id=${await this.options.adapter.getClientId()}`;const e=(await this.options.remote.get(t)).data.write_checkpoint;return this.logger.log({level:_.debug,message:`Created write checkpoint: ${e}`}),e}async crudUploadLoop(t,e){for(;!t.aborted;)await Promise.all([this._uploadAllCrud(t,e),this.delayRetry(t,e.crudUploadThrottleMs)]),await this.crudUploadNotifier.waitForNotification(t)}async _uploadAllCrud(t,e){return this.obtainLock({type:de.CRUD,signal:t,callback:async()=>{let n;for(;!t.aborted;)try{const t=await this.options.adapter.nextCrudItem();if(!t){await this.options.adapter.updateLocalTarget(()=>this.getWriteCheckpoint())?this.notifyCompletedUploads?.():null!=n&&this.logger.log({level:_.debug,message:"Upload complete, no write checkpoint needed."});break}if(this.updateJsSyncState({uploading:!0}),t.clientId==n?.clientId)throw this.logger.log({level:_.warn,message:"Potentially previously uploaded CRUD entries are still present in the upload queue.\nMake sure to handle uploads and complete CRUD transactions or batches by calling and awaiting their [.complete()] method.\nThe next upload iteration will be delayed."}),new Error("Delaying due to previously encountered CRUD item.");n=t,await this.options.uploadCrud(),this.updateJsSyncState({uploadError:void 0})}catch(s){if(n=void 0,this.updateJsSyncState({uploading:!1,uploadError:s}),await this.delayRetry(t,e.retryDelayMs),!this.isConnected)break;this.logger.log({level:_.debug,message:"Caught exception when uploading. Upload will retry after a delay.",error:s})}finally{this.updateJsSyncState({uploading:!1})}}})}async connect(t){this.abortController&&await this.disconnect();const e=new AbortController;return this.abortController=e,this.streamingSyncPromise=Promise.all([this.crudUploadLoop(e.signal,t).catch(t=>this.logger.log({level:_.error,message:"Error in crud upload loop",error:t})),this.streamingSync(e.signal,t)]),new Promise(t=>{let e=!1;const n=this.registerListener({statusChanged:s=>{if(s.connecting&&(e=!0),null!=s.downloadError)this.logger.log({level:_.warn,message:"Initial connect attempt did not successfully connect to server"});else if(!e||s.connecting)return;n(),t()}})})}async disconnect(){if(this.abortController){this.abortController.signal.aborted||this.abortController.abort(new ae("Disconnect has been requested"));try{await this.streamingSyncPromise}catch(t){this.logger.log({level:_.warn,message:"Error in sync while disconnecting",error:t})}this.streamingSyncPromise=void 0,this.abortController=null,this.markAsDisconnected()}}markAsDisconnected(){const t=this.syncStatus.core;null!=t&&this.updateSyncStatus({connected:!1,connecting:!1,priority_status:t.priority_status,downloading:null,streams:t.streams})}async streamingSync(t,e){this.crudUpdateListener=this.options.adapter.registerListener({crudUpdate:()=>this.triggerCrudUpload()});let n=new AbortController;for(t.addEventListener("abort",()=>{n.abort(t?.reason??new ae("Received command to disconnect from upstream")),this.crudUpdateListener?.(),this.crudUpdateListener=void 0,this.markAsDisconnected()});;){let s=!0,r=null;try{if(t?.aborted)break;r=await this.streamingSyncIteration(n.signal,e)}catch(t){t instanceof ae?(this.logger.log({level:_.warn,message:"Sync aborted",error:t}),s=!1):this.connectionMayHaveChanged&&t.message?.indexOf("No iteration is active")>=0?(this.connectionMayHaveChanged=!1,this.logger.log({level:_.info,message:"Sync error after changed connection, retrying immediately"}),s=!1):this.logger.log({level:_.error,message:"Sync error",error:t}),this.updateJsSyncState({downloadError:t})}finally{this.notifyCompletedUploads=void 0,t.aborted||(n.abort(new ae("Closing sync stream network requests before retry.")),n=new AbortController),1!=r?.immediateRestart&&(this.markAsDisconnected(),s&&await this.delayRetry(n.signal,e.retryDelayMs))}}this.markAsDisconnected()}markConnectionMayHaveChanged(){this.connectionMayHaveChanged=!0,this.handleActiveStreamsChange?.()}async requireKeyFormat(t){const e=await this.options.adapter.hasMigratedSubkeys();return t&&!e?(await this.options.adapter.migrateToFixedSubkeys(),!0):e}streamingSyncIteration(t,e){return this.obtainLock({type:de.SYNC,signal:t,callback:async()=>{const n=Object.entries(e.appMetadata).filter(([t,e])=>"string"!=typeof e);if(n.length>0)throw new Error(`Invalid appMetadata provided. Only string values are allowed. Invalid values: ${n.map(([t,e])=>`${t}: ${e}`).join(", ")}`);return await this.requireKeyFormat(!0),await this.rustSyncIteration(t,e)}})}receiveSyncLines(t){const{options:e,connection:n}=t,s=this.options.remote,r=async()=>n.connectionMethod==L.HTTP?await s.fetchStream(e):await this.options.remote.socketStreamRaw({...e,fetchStrategy:n.fetchStrategy});let i,o=!1;return{async next(){if(o)return ne;if(null==i)return i=await r(),se({command:Dt.CONNECTION_STATE,payload:"established"});{const t=await i.next();return t.done?(o=!0,se({command:Dt.CONNECTION_STATE,payload:"end"})):se({command:"string"==typeof t.value?Dt.PROCESS_TEXT_LINE:Dt.PROCESS_BSON_LINE,payload:t.value})}}}}async rustSyncIteration(t,e){const n=this,s=this.options.adapter,r=this.options.remote;let i,o=!1;if(t.aborted)throw new ae("Connection request has been aborted");const a=this.options.serializedSchema;async function c(t,e){const r=await s.control(t,e??null),i=null==e||"string"==typeof e?e:"<bytes>";return n.logger.log({level:_.trace,message:`powersync_control(${t}, ${i}) -> ${r}`}),t!=Dt.STOP&&(n.connectionMayHaveChanged=!1),JSON.parse(r)}async function l(t){if("LogLine"in t){const{severity:e,line:s}=t.LogLine;switch(e){case"DEBUG":n.logger.log({level:_.debug,message:s});break;case"INFO":n.logger.log({level:_.info,message:s});break;case"WARNING":n.logger.log({level:_.warn,message:s})}}else"UpdateSyncStatus"in t?n.updateSyncStatus(t.UpdateSyncStatus.status):"FetchCredentials"in t?t.FetchCredentials.did_expire?r.invalidateCredentials():(r.invalidateCredentials(),r.fetchCredentials().then(t=>{i?.()},t=>{n.logger.log({level:_.warn,message:"Could not prefetch credentials",error:t})})):"FlushFileSystem"in t||"DidCompleteSync"in t&&n.updateJsSyncState({downloadError:void 0})}try{const s={immediateRestart:!1};let r=null;for(const i of await function(){const t={parameters:e.params,app_metadata:e.appMetadata,active_streams:n.activeStreams,include_defaults:e.includeDefaultStreams};return a&&(t.schema=a),c(Dt.START,JSON.stringify(t))}())if("EstablishSyncStream"in i){const s={path:"/sync/stream",abortSignal:t,data:i.EstablishSyncStream.request};r=re(n.receiveSyncLines({options:s,connection:e}))}else{if("CloseSyncStream"in i)return s;await l(i)}if(null==r)return s;this.notifyCompletedUploads=()=>{r.inject({command:Dt.NOTIFY_CRUD_UPLOAD_COMPLETED})},this.handleActiveStreamsChange=()=>{r.inject({command:Dt.UPDATE_SUBSCRIPTIONS,payload:JSON.stringify(this.activeStreams)})},i=()=>{r.inject({command:Dt.NOTIFY_TOKEN_REFRESHED})};let u=!1;t:for(;;){const{done:t,value:e}=await r.next();if(t)break;u||e.command!=Dt.PROCESS_TEXT_LINE&&e.command!=Dt.PROCESS_BSON_LINE||(u=!0,this.triggerCrudUpload?.());const n=await c(e.command,e.payload);for(const t of n){if("EstablishSyncStream"in t)throw new Error("Received EstablishSyncStream while already connected.");if("CloseSyncStream"in t){o=t.CloseSyncStream.hide_disconnect;break t}await l(t)}}}finally{this.notifyCompletedUploads=this.handleActiveStreamsChange=void 0,i=void 0,await async function(){const t=await c(Dt.STOP);for(const e of t)he(e)||await l(e)}()}return{immediateRestart:o}}updateSyncStatus(t,e){const n=new zt(t,{...this.syncStatus.jsState,...e});this.syncStatus.isEqual(n)||(this.syncStatus=n,this.iterateListeners(t=>t.statusChanged?.(n)))}updateJsSyncState(t){this.updateSyncStatus(this.syncStatus.core,t)}async delayRetry(t,e){return new Promise(n=>{if(t?.aborted)return void n();let s;const r=()=>{n(),s&&(clearTimeout(s),s=void 0),t?.removeEventListener("abort",r)};t?.addEventListener("abort",r,{once:!0}),s=setTimeout(r,e)})}updateSubscriptions(t){this.activeStreams=t,this.handleActiveStreamsChange?.()}}class ge extends Error{static NAME="ConnectionClosedError";static MATCHES(t){return t instanceof ge||t instanceof Error&&t.name==ge.NAME}constructor(t){super(t),this.name=ge.NAME}}class me{inner;leaseMutex;constructor(t,e){this.inner=t,this.leaseMutex=e?null:new Zt}get options(){return this.inner.options}acquireMutex(t){return this.leaseMutex?this.leaseMutex.acquire(t):new Promise((e,n)=>{const s={signal:t};navigator.locks.request(`db-lock-${this.options.filename}`,s,t=>new Promise(t=>e(()=>{t()}))).catch(n)})}unsafeUseInner(){return this.inner}async acquireConnection(t){const e=await this.acquireMutex(t),n=new fe(e,this.inner);try{this.inner.requireSqlite(),this.inner.isAutoCommit()||await this.inner.executeRaw("ROLLBACK")}catch(t){throw e(),t}return n}async close(){const t=await this.acquireMutex();try{await this.inner.close()}finally{t()}}}class fe{returnMutex;connection;useMutex=new Zt;closed=!1;constructor(t,e){this.returnMutex=t,this.connection=e}async returnLease(){await this.useMutex.runExclusive(async()=>{this.closed||(this.closed=!0,this.returnMutex())})}async use(t){return await this.useMutex.runExclusive(async()=>{if(this.closed)throw new Error("lease token has already been closed");return await t(this.connection)})}}const we="open-wasqlite-db";const ye="SharedWorkerGlobalScope"in globalThis;class be extends ue{connector;constructor(t,e){super(t,e),this.connector=t}fetch({resource:t,request:e}){return fetch(t,e)}async loadWebSocketSupport(t){if(!Se){const e=await import("./websockets-Q8W_lerF.js");Se=new e.WebSocketSupport(t)}return Se}getUserAgent(){let t=[super.getUserAgent(),"powersync-web"];try{t.push(...function(t){t??=navigator;const e=function(t){const e=t.userAgentData?.brands;if(null!=e){const t=[{name:"Google Chrome",value:"Chrome"},{name:"Opera",value:"Opera"},{name:"Edge",value:"Edge"},{name:"Chromium",value:"Chromium"}];for(let{name:n,value:s}of t){const t=e.find(t=>t.brand==n);if(null!=t)return`${s}/${t.version}`}}const n=t.userAgent,s=[{re:/(?:firefox|fxios)\/(\d+)/i,value:"Firefox"},{re:/(?:edg|edge|edga|edgios)\/(\d+)/i,value:"Edge"},{re:/opr\/(\d+)/i,value:"Opera"},{re:/(?:chrome|chromium|crios)\/(\d+)/i,value:"Chrome"},{re:/version\/(\d+).*safari/i,value:"Safari"}];for(let{re:t,value:e}of s){const s=t.exec(n);if(null!=s)return`${e}/${s[1]}`}return null}(t),n=function(t){if(null!=t.userAgentData?.platform)return t.userAgentData.platform.toLowerCase();const e=t.userAgent,n=[{re:/windows/i,value:"windows"},{re:/android/i,value:"android"},{re:/linux/i,value:"linux"},{re:/iphone|ipad|ipod/i,value:"ios"},{re:/macintosh|mac os x/i,value:"macos"}];for(let{re:t,value:s}of n)if(t.test(e))return s;return null}(t);return[e,n].filter(t=>null!=t)}())}catch(t){this.logger.log({level:_.warn,message:"Failed to get user agent info",error:t})}return t.join(" ")}}let Se;class ve extends pe{constructor(t){super(t)}get webOptions(){return this.options}async obtainLock(t){const e=`streaming-sync-${t.type}-${this.webOptions.identifier}`;return t.type==de.SYNC&&this.logger.log({level:_.debug,message:`requesting lock for ${e}`}),F().request(e,{signal:t.signal},t.callback)}}class _e{clients;inner;currentLevel=_.info;sendBroadcasts=!0;constructor(t,e){this.clients=e,this.inner=E({prefix:t})}log(t){if(this.inner.log(t),this.sendBroadcasts&&t.level>=this.currentLevel){const e=this.sanitizeRecord(t);this.iterateClients(t=>t.clientProvider.log(e))}}setLevel(t){this.inner.minLevel=t,this.currentLevel=t}async iterateClients(t){for(const e of this.clients)try{await t(e)}catch(t){console.error("Caught exception when iterating client",t)}}sanitizeRecord(t){if(!t.error)return t;let e;try{e=structuredClone(t.error)}catch(t){console.error(t),e="Could not serialize log params. Check shared worker logs for more details."}return{...t,error:e}}}class Ee extends U{options;config;#u;#h=new AbortController;#d;constructor(t,e){super(),this.options=t,this.config=e,this.#u={connection:t.connection,notifyRemoteClosed:t.remoteCanCloseUnexpectedly?new AbortController:void 0,traceQueries:!0===e.debugMode};const{port1:n,port2:s}=new MessageChannel;t.connection.setUpdateListener(w(n,[n])),this.#d=s,s.onmessage=t=>{const e={tables:t.data};this.iterateListeners(t=>{t.tablesUpdated&&t.tablesUpdated(e)})}}get name(){return this.config.dbFilename}markRemoteClosed(){this.#u.notifyRemoteClosed.abort()}async close(){this.#h.abort(),this.#d.close(),await Ae(this.#u,t=>t.close(),!0),this.options.onClose?.(),this.options.source?.[n]()}readLock(t,e){return this.#p(!1,t,e)}writeLock(t,e){return this.#p(!0,t,e)}async#p(t,e,n){const s=await Ae(this.#u,e=>e.requestAccess(t,n?.timeoutMs));try{return await e(new Ce(this.#u,s))}finally{await Ae(this.#u,t=>t.completeAccess(s))}}async refreshSchema(){}async shareConnection(){const t=this.#h,n=this.options.source;if(null==n)throw new Error("shareConnection() is only available for connections based by workers.");await new Promise((e,n)=>navigator.locks.request(`shared-connection-${this.name}-${Date.now()}-${Math.round(1e4*Math.random())}`,{signal:t.signal},async()=>{e(),t.signal.aborted||await new Promise(e=>{t.signal.addEventListener("abort",()=>{e()})})}).catch(t=>{"AbortError"==t.name?e():n(t)}));return{port:await n[e](),identifier:this.name}}getConfiguration(){return this.config}}class Ce extends M{#u;#g;constructor(t,e){super(),this.#u=t,this.#g=e}async maybeTrace(t,e){if(!this.#u.traceQueries)return Ae(this.#u,t);{const n=performance.now(),s=e();try{const e=await Ae(this.#u,t);return performance.measure(`[SQL] ${s}`,{start:n}),e}catch(t){throw performance.measure(`[SQL] [ERROR: ${t.message}] ${s}`,{start:n}),t}}}async executeRaw(t,e){return await this.#m(t,e)}async#m(t,e){return this.maybeTrace(n=>n.execute(this.#g,t,e),()=>t)}async executeBatch(t,e=[]){const n=await this.maybeTrace(n=>n.executeBatch(this.#g,t,e),()=>`${t} (batch of ${e.length})`),s={insertId:void 0,rowsAffected:0};for(const t of n)s.insertId=t.insertId,s.rowsAffected=(s.rowsAffected??0)+t.rowsAffected;return R(s)}}async function Ae(t,e,n=!1){const s=t.notifyRemoteClosed;return s?new Promise((r,i)=>{function o(){i(new ge("Remote peer closed with request in flight"))}function a(t){s.signal.removeEventListener("abort",o),t()}s.signal.aborted&&(i(new ge("Called operation on closed remote")),!n)||(s.signal.addEventListener("abort",o),e(t.connection).then(t=>a(()=>r(t))).catch(t=>a(()=>i(t))))}):e(t.connection)}var Pe;!function(t){t.CLOSE_CLIENT="close-client",t.CLOSE_ACK="close-ack"}(Pe||(Pe={}));const Te={};class Le extends k{ports;isInitialized;statusListener;fetchCredentialsController;uploadDataController;syncParams;lastConnectOptions;portMutex;subscriptions=[];connectionManager;syncStatus;logger;database=this.generateReconnectableDatabase();sharedCloseSignal=function(t){return new Promise((e,n)=>{const s={signal:t};F().request(`tab-close-signal-${crypto.randomUUID()}`,s,t=>(e(t.name),new Promise(t=>{}))).catch(n)})}();constructor(){super(),this.ports=[],this.syncParams=null,this.lastConnectOptions=void 0,this.portMutex=new Zt,this.isInitialized=new Promise(t=>{const e=this.registerListener({initialized:()=>{t(),e?.()}})}),this.logger=new _e("shared-sync",this.ports),this.connectionManager=new Jt({createSyncImplementation:async()=>{await this.waitForReady();const t=this.generateStreamingImplementation(),e=t.registerListener({statusChanged:t=>{this.syncStatus=t;const e=t.toJSON();this.ports.forEach(t=>t.clientProvider.statusChanged(e))}});return{sync:t,onDispose:e}},logger:this.logger,defaultConnectionMethod:L.HTTP})}get isConnected(){return this.connectionManager.syncStreamImplementation?.isConnected??!1}async getLastWrappedPort(){return await this.portMutex.runExclusive(()=>{for(let t=this.ports.length-1;t>=0;t--)if(!this.ports[t].isClosing)return this.ports[t]})}async getRandomWrappedPort(){return await this.portMutex.runExclusive(()=>{const t=this.ports.filter(t=>!t.isClosing);return t[Math.floor(Math.random()*t.length)]})}async waitUntilStatusMatches(t){return this.withSyncImplementation(async e=>e.waitUntilStatusMatches(t))}async waitForReady(){return this.isInitialized}collectActiveSubscriptions(){this.logger.log({level:_.debug,message:"Collecting active stream subscriptions across tabs"});const t=new Map;for(const e of this.ports)for(const n of e.currentSubscriptions){const e=JSON.stringify(n);t.set(e,n)}this.subscriptions=[...t.values()],this.logger.log({level:_.debug,message:`Collected stream subscriptions, ${JSON.stringify(this.subscriptions)}`}),this.connectionManager.syncStreamImplementation?.updateSubscriptions(this.subscriptions)}updateSubscriptions(t,e){t.currentSubscriptions=e,this.collectActiveSubscriptions()}setLogLevel(t){this.logger.setLevel(t)}async setParams(t){await this.portMutex.runExclusive(async()=>{this.collectActiveSubscriptions()}),this.syncParams||(this.syncParams=t,this.logger.sendBroadcasts=t.enableBroadcastLogs,await this.database.readLock(async()=>{}),self.onerror=t=>{this.logger.log({level:_.error,message:"Uncaught exception in PowerSync shared sync worker",error:t})},this.iterateListeners(t=>t.initialized?.()))}async dispose(){return await this.waitForReady(),this.statusListener?.(),this.connectionManager.close()}async connect(t,e){return this.lastConnectOptions=t,this.connectionManager.connect(Te,t??{},e)}async disconnect(){return this.connectionManager.disconnect()}async addPort(t){return await this.portMutex.runExclusive(()=>{const e={port:t,clientProvider:l(t),currentSubscriptions:[],closeListeners:[],isClosing:!1};this.ports.push(e);const n=this.syncStatus;return n&&e.clientProvider.statusChanged(n.toJSON()),e})}async removePort(t){return t.isClosing=!0,await this.portMutex.runExclusive(async()=>{const e=this.ports.findIndex(e=>e==t);if(e<0)return this.logger.log({level:_.warn,message:`Could not remove port ${t} since it is not present in active ports.`}),()=>{};const s=this.ports[e];this.ports.splice(e,1),[this.fetchCredentialsController,this.uploadDataController].forEach(e=>{e?.activePort==t&&e.controller.abort(new ae("Closing pending requests after client port is removed"))});for(const t of s.closeListeners)await t();return this.collectActiveSubscriptions(),()=>s.clientProvider[n]()})}triggerCrudUpload(){this.withSyncImplementation(async t=>{t.triggerCrudUpload()})}async getWriteCheckpoint(){return this.withSyncImplementation(async t=>t.getWriteCheckpoint())}async withSyncImplementation(t){if(await this.waitForReady(),this.connectionManager.syncStreamImplementation)return t(this.connectionManager.syncStreamImplementation);return t(await new Promise(t=>{const e=this.connectionManager.registerListener({syncStreamCreated:n=>{t(n),e?.()}})}))}generateStreamingImplementation(){const t=this.syncParams;return new ve({adapter:new oe(this.database,this.logger),remote:new be({invalidateCredentials:async()=>{const t=await this.getLastWrappedPort();if(!t)throw new Error("No client port found to invalidate credentials");try{this.logger.log({level:_.info,message:"calling the last port client provider to invalidate credentials"}),t.clientProvider.invalidateCredentials()}catch(t){this.logger.log({level:_.error,message:"error invalidating credentials",error:t})}},fetchCredentials:async()=>{const t=await this.getLastWrappedPort();if(!t)throw new Error("No client port found to fetch credentials");return new Promise(async(e,n)=>{const s=new AbortController;this.fetchCredentialsController={controller:s,activePort:t},s.signal.onabort=n;try{this.logger.log({level:_.info,message:"calling the last port client provider for credentials"}),e(await t.clientProvider.fetchCredentials())}catch(t){n(t)}finally{this.fetchCredentialsController=void 0}})}},this.logger),uploadCrud:async()=>{const t=await this.getLastWrappedPort();if(!t)throw new Error("No client port found to upload crud");return new Promise(async(e,n)=>{const s=new AbortController;this.uploadDataController={controller:s,activePort:t},s.signal.onabort=()=>e();try{e(await t.clientProvider.uploadCrud())}catch(t){n(t)}finally{this.uploadDataController=void 0}})},...t.streamOptions,subscriptions:this.subscriptions,logger:this.logger})}async openInternalDB(t){const e=await this.getRandomWrappedPort();if(!e)throw new Error("Could not open DB connection since no client is connected.");const n=setTimeout(()=>{s.abort()},1e4),s=new AbortController,r=()=>{s.abort()},i=()=>{const t=e.closeListeners.indexOf(r);t>=0&&e.closeListeners.splice(t,1)};e.closeListeners.push(r);const o=l(await xe({action:()=>e.clientProvider.getDBWorkerPort(),signal:s.signal,cleanupOnAbort:t=>{t.close()}}).catch(t=>{throw i(),t})),a=this.syncParams.dbParams.dbFilename,c=await this.sharedCloseSignal,u=await xe({action:async()=>{const t=await o.connectToExisting({identifier:a,lockName:c});return new Ee({connection:t,source:o,remoteCanCloseUnexpectedly:!0},this.syncParams.dbParams)},signal:s.signal,cleanupOnAbort:t=>{t.close()}}).finally(()=>{i()});return clearTimeout(n),e.closeListeners.push(async()=>{this.logger.log({level:_.info,message:"Aborting open connection because associated tab closed."}),t(u),u.markRemoteClosed(),u.close().catch(t=>this.logger.log({level:_.warn,message:"error closing database connection",error:t}))}),u}generateReconnectableDatabase(){const t=this.syncParams,e=this;return new class extends U{connectionState=null;get name(){return t?.dbParams.dbFilename}async connect(){if(null==this.connectionState){const t=this.handleClientClosed.bind(this);this.connectionState=(async()=>{try{const n=await e.openInternalDB(t);return n.registerListener({tablesUpdated:t=>{this.iterateListeners(e=>e.tablesUpdated?.(t))}}),this.connectionState=n,n}catch(t){throw this.connectionState=null,t}})()}return await this.connectionState}async close(){null!=this.connectionState&&await(await this.connectionState).close()}handleClientClosed(t){if(t===this.connectionState){this.connectionState=null;const t=e.connectionManager.syncStreamImplementation;t?.triggerCrudUpload(),t?.markConnectionMayHaveChanged()}}async readLock(t,e){return(await this.connect()).readLock(t,e)}async writeLock(t,e){return(await this.connect()).writeLock(t,e)}async refreshSchema(){}}}}function xe(t){const{action:e,signal:n,cleanupOnAbort:s}=t;return new Promise((t,r)=>{function i(){n.removeEventListener("abort",i),r(new ae("Operation aborted by abort controller"))}function o(t){n.removeEventListener("abort",i),t()}n.aborted?r(new ae("Operation aborted by abort controller")):(n.addEventListener("abort",i,{once:!0}),e().then(e=>{if(n.aborted)return o(()=>s?.(e));o(()=>t(e))}).catch(t=>o(()=>r(t))))})}class Oe{sync;port;resolvedPort=null;resolvedPortPromise=null;constructor(t,e){this.sync=t,this.port=e,a(this,this.port),this.port.addEventListener("message",async t=>{const e=t.data;e?.event==Pe.CLOSE_CLIENT&&await this.removePort()})}async removePort(){if(this.resolvedPort){const t=this.resolvedPort;this.resolvedPort=null;const e=await this.sync.removePort(t);this.resolvedPort=null,this.port.postMessage({event:Pe.CLOSE_ACK,data:{}}),e?.()}}async addLockBasedCloseSignal(t){this.resolvedPort=await this.sync.addPort(this.port),F().request(t,async()=>{await this.removePort()})}setLogLevel(t){this.sync.setLogLevel(t)}triggerCrudUpload(){return this.sync.triggerCrudUpload()}setParams(t,e){return this.resolvedPort.currentSubscriptions=e,this.sync.setParams(t)}getWriteCheckpoint(){return this.sync.getWriteCheckpoint()}connect(t,e){return this.sync.connect(t,e)}updateSubscriptions(t){this.resolvedPort&&this.sync.updateSubscriptions(this.resolvedPort,t)}disconnect(){return this.sync.disconnect()}}const Ie=new class{logger;#f=new Map;#w=new Zt;constructor(t){this.logger=t}async handleConnection({logLevel:t,database:e,lockName:n}){const s={log:e=>{e.level>=t&&this.logger.log(e)}};return y(await this.openConnectionLocally(s,e,n))}async connectToExisting(t,e){return F().request(we,async()=>{const n=this.#f.get(t);if(null==n)throw new Error(`connectToExisting(${t}) failed because the worker doesn't own a database with that name.`);return y(await n.connect(e))})}async openConnectionLocally(t,e,n){let s;for(let n=0;n<2;n++)try{s=await this.#y(t,e)}catch(t){this.logger.log({level:_.warn,message:`Attempt ${n+1} of 3 to open database failed, retrying in 1 second...`,error:t}),await new Promise(t=>setTimeout(t,1e3))}return s??=await this.#y(t,e),s.connect(n)}async#y(t,e){const{filename:n,readonly:s,vfs:r}=e,i=!(ye||s||r==Ot.InMemoryVfs),o=this.#f;async function a(){let s=o.get(n);if(null==s){const r=new Mt(e),a=new me(r,i),c=await a.acquireMutex();try{await r.init()}catch(t){throw c(),await r.close(),t}c();s=new N({inner:a,logger:t,onClose:()=>o.delete(n)}),o.set(n,s)}return s}return i?F().request(we,a):this.#w.runExclusive(a)}closeAll(){const t=[...this.#f.values()];return Promise.all(t.map(t=>{t.forceClose()}))}}(E({prefix:"db-worker",minLevel:_.trace})),ke={connect:t=>Ie.handleConnection(t),connectToExisting:({identifier:t,lockName:e})=>Ie.connectToExisting(t,e)};if(ye){const t=new Le;self.onconnect=e=>{e.ports[0].onmessage=e=>{const{service:n,port:s}=e.data;"database"===n?a(ke,s):"sync"===n&&new Oe(t,s)}}}else a(ke);export{St as A,bt as B,B as C,z as D,wt as E,ft as F,lt as G,ut as H,ht as I,yt as J,ot as K,$ as S,X as a,nt as b,J as c,j as d,dt as e,W as f,gt as g,mt as h,pt as i,rt as j,H as k,K as l,V as m,it as n,G as o,tt as p,Z as q,at as r,ct as s,st as t,et as u,Y as v,Q as w,Et as x,_t as y,vt as z};
6
+ const t=Symbol("Comlink.proxy"),e=Symbol("Comlink.endpoint"),n=Symbol("Comlink.releaseProxy"),s=Symbol("Comlink.finalizer"),r=Symbol("Comlink.thrown"),i=t=>"object"==typeof t&&null!==t||"function"==typeof t,o=new Map([["proxy",{canHandle:e=>i(e)&&e[t],serialize(t){const{port1:e,port2:n}=new MessageChannel;return a(t,e),[n,[n]]},deserialize:t=>(t.start(),l(t))}],["throw",{canHandle:t=>i(t)&&r in t,serialize({value:t}){let e;return e=t instanceof Error?{isError:!0,value:{message:t.message,name:t.name,stack:t.stack}}:{isError:!1,value:t},[e,[]]},deserialize(t){if(t.isError)throw Object.assign(new Error(t.value.message),t.value);throw t.value}}]]);function a(t,e=globalThis,n=["*"]){e.addEventListener("message",function i(o){if(!o||!o.data)return;if(!function(t,e){for(const n of t){if(e===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(e))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:l,type:u,path:h}=Object.assign({path:[]},o.data),d=(o.data.argumentList||[]).map(S);let p;try{const e=h.slice(0,-1).reduce((t,e)=>t[e],t),n=h.reduce((t,e)=>t[e],t);switch(u){case"GET":p=n;break;case"SET":e[h.slice(-1)[0]]=S(o.data.value),p=!0;break;case"APPLY":p=n.apply(e,d);break;case"CONSTRUCT":p=w(new n(...d));break;case"ENDPOINT":{const{port1:e,port2:n}=new MessageChannel;a(t,n),p=y(e,[e])}break;case"RELEASE":p=void 0;break;default:return}}catch(t){p={value:t,[r]:0}}Promise.resolve(p).catch(t=>({value:t,[r]:0})).then(n=>{const[r,o]=b(n);e.postMessage(Object.assign(Object.assign({},r),{id:l}),o),"RELEASE"===u&&(e.removeEventListener("message",i),c(e),s in t&&"function"==typeof t[s]&&t[s]())}).catch(t=>{const[n,s]=b({value:new TypeError("Unserializable return value"),[r]:0});e.postMessage(Object.assign(Object.assign({},n),{id:l}),s)})}),e.start&&e.start()}function c(t){(function(t){return"MessagePort"===t.constructor.name})(t)&&t.close()}function l(t,e){const n=new Map;return t.addEventListener("message",function(t){const{data:e}=t;if(!e||!e.id)return;const s=n.get(e.id);if(s)try{s(e)}finally{n.delete(e.id)}}),g(t,n,[],e)}function u(t){if(t)throw new Error("Proxy has been released and is not useable")}function h(t){return v(t,new Map,{type:"RELEASE"}).then(()=>{c(t)})}const d=new WeakMap,p="FinalizationRegistry"in globalThis&&new FinalizationRegistry(t=>{const e=(d.get(t)||0)-1;d.set(t,e),0===e&&h(t)});function g(t,s,r=[],i=function(){}){let o=!1;const a=new Proxy(i,{get(e,i){if(u(o),i===n)return()=>{!function(t){p&&p.unregister(t)}(a),h(t),s.clear(),o=!0};if("then"===i){if(0===r.length)return{then:()=>a};const e=v(t,s,{type:"GET",path:r.map(t=>t.toString())}).then(S);return e.then.bind(e)}return g(t,s,[...r,i])},set(e,n,i){u(o);const[a,c]=b(i);return v(t,s,{type:"SET",path:[...r,n].map(t=>t.toString()),value:a},c).then(S)},apply(n,i,a){u(o);const c=r[r.length-1];if(c===e)return v(t,s,{type:"ENDPOINT"}).then(S);if("bind"===c)return g(t,s,r.slice(0,-1));const[l,h]=m(a);return v(t,s,{type:"APPLY",path:r.map(t=>t.toString()),argumentList:l},h).then(S)},construct(e,n){u(o);const[i,a]=m(n);return v(t,s,{type:"CONSTRUCT",path:r.map(t=>t.toString()),argumentList:i},a).then(S)}});return function(t,e){const n=(d.get(e)||0)+1;d.set(e,n),p&&p.register(t,e,t)}(a,t),a}function m(t){const e=t.map(b);return[e.map(t=>t[0]),(n=e.map(t=>t[1]),Array.prototype.concat.apply([],n))];var n}const f=new WeakMap;function y(t,e){return f.set(t,e),t}function w(e){return Object.assign(e,{[t]:!0})}function b(t){for(const[e,n]of o)if(n.canHandle(t)){const[s,r]=n.serialize(t);return[{type:"HANDLER",name:e,value:s},r]}return[{type:"RAW",value:t},f.get(t)||[]]}function S(t){switch(t.type){case"HANDLER":return o.get(t.name).deserialize(t.value);case"RAW":return t.value}}function v(t,e,n,s){return new Promise(r=>{const i=new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-");e.set(i,r),t.start&&t.start(),t.postMessage(Object.assign({id:i},n),s)})}const _={trace:10,debug:20,info:30,warn:40,error:50};function C(t){const{prefix:e="PowerSync",minLevel:n=_.info}=t??{};return{prefix:e,minLevel:n,log({level:t,message:n,error:s}){if(t<this.minLevel)return;let r=console.log;t>=_.error?r=console.error:t>=_.warn?r=console.warn:t>=_.info&&(r=console.info);const i=`[${e}]: ${n}`;s?r(i,s):r(i)}}}var E,k,A,L,q,T,x,P;!function(t){t.TEXT="TEXT",t.INTEGER="INTEGER",t.REAL="REAL"}(E||(E={})),E.TEXT,E.INTEGER,E.REAL,function(t){t[t.QUEUED_UPLOAD=0]="QUEUED_UPLOAD",t[t.QUEUED_DOWNLOAD=1]="QUEUED_DOWNLOAD",t[t.QUEUED_DELETE=2]="QUEUED_DELETE",t[t.SYNCED=3]="SYNCED",t[t.ARCHIVED=4]="ARCHIVED"}(k||(k={})),function(t){t.UTF8="utf8",t.Base64="base64"}(A||(A={})),function(t){t.PUT="PUT",t.PATCH="PATCH",t.DELETE="DELETE"}(L||(L={})),function(t){t.HTTP="http",t.WEB_SOCKET="web-socket"}(q||(q={})),function(t){t.Buffered="buffered",t.Sequential="sequential"}(T||(T={}));class I{listeners=new Set;constructor(){}dispose(){this.listeners.clear()}registerListener(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}iterateListeners(t){for(const e of this.listeners)t(e)}async iterateAsyncListeners(t){for(let e of Array.from(this.listeners.values()))await t(e)}}function O(t,e){const n={};return t.forEach((t,s)=>n[t]=e[s]),n}function R(t){return{...t,array:[],[Symbol.iterator]:()=>({next:()=>({done:!0,value:void 0})})}}class M{async getAll(t,e){const n=await this.execute(t,e);return Array.from(n)}async getOptional(t,e){const{array:n}=await this.execute(t,e);return n.length>0?n[0]:null}async get(t,e){const n=await this.getOptional(t,e);if(null==n)throw new Error("Result set is empty");return n}async execute(t,e){return function(t){const{insertId:e,rowsAffected:n,columnNames:s,rawRows:r}=t;let i;function o(){return i||(i=r.map(t=>O(s,t)))}function a(t){return i?i[t]:O(s,r[t])}return{insertId:e,rowsAffected:n,get array(){return o()},rows:{length:r.length,get _array(){return o()},item:a},[Symbol.iterator](){let t=0;return{next:function(){if(t>=r.length)return{done:!0,value:void 0};const e=a(t);return t++,{done:!1,value:e}}}}}}(await this.executeRaw(t,e))}async executeBatch(t,e=[]){let n,s=0;for(const r of e){const e=await this.execute(t,r);n=e.insertId,s+=e.rowsAffected??0}return R({rowsAffected:s,insertId:n})}}class F extends I{readTransaction(t,e){return this.readLock(e=>U.runWith(e,t),e)}writeTransaction(t,e){return this.writeLock(e=>U.runWith(e,t),e)}getAll(t,e){return this.readLock(n=>n.getAll(t,e))}getOptional(t,e){return this.readLock(n=>n.getOptional(t,e))}get(t,e){return this.readLock(n=>n.get(t,e))}execute(t,e){return this.writeLock(n=>n.execute(t,e))}executeRaw(t,e){return this.writeLock(n=>n.executeRaw(t,e))}executeBatch(t,e){return this.writeTransaction(n=>n.executeBatch(t,e))}}class U extends M{inner;finalized=!1;constructor(t){super(),this.inner=t}async commit(){this.finalized||(this.finalized=!0,await this.inner.execute("COMMIT"))}async rollback(){this.finalized||(this.finalized=!0,await this.inner.execute("ROLLBACK"))}execute(t,e){return this.inner.execute(t,e)}executeRaw(t,e){return this.inner.executeRaw(t,e)}executeBatch(t,e){return this.inner.executeBatch(t,e)}static async runWith(t,e){let n=new U(t);try{await t.execute("BEGIN IMMEDIATE");const s=await e(n);return await n.commit(),s}catch(t){try{await n.rollback()}catch(t){}throw t}}}!function(t){t.INSERT="INSERT",t.UPDATE="UPDATE",t.DELETE="DELETE"}(x||(x={})),function(t){t.ON_DATA="onData",t.ON_ERROR="onError",t.ON_STATE_CHANGE="onStateChange",t.SETTINGS_WILL_UPDATE="settingsWillUpdate",t.CLOSED="closed"}(P||(P={}));class D{#t;#e=0;#n=new Set;#s;#r=new Set;constructor(t){this.#t=t;const e=t.inner;this.#s=new BroadcastChannel(`${e.options.filename}-table-updates`),this.#s.onmessage=({data:t})=>{this.#i(t)}}#i(t){for(const e of this.#r)e.postMessage(t)}get#o(){return this.#t.inner}get#a(){return this.#t.logger}async connect(t){let e=!0;const n=this.#e++;this.#n.add(n);let s,r=new Map;function i(){if(!e)throw new Error("Client has already been closed")}function o(t){i();const e=r.get(t);if(!e)throw new Error("Attempted to use a connection lease that has already been returned.");return e}const a=async()=>{if(e){e=!1,s&&this.#r.delete(s);for(const{lease:t}of r.values())this.#a.log({level:_.debug,message:"Closing connection lease that hasn't been returned."}),await t.returnLease();this.#n.delete(n),0==this.#n.size?await this.forceClose():this.#a.log({level:_.debug,message:"Keeping underlying connection active since its used by other clients."})}};return t&&navigator.locks.request(t,{},()=>{a()}),{close:a,debugIsAutoCommit:async()=>this.#o.unsafeUseInner().isAutoCommit(),requestAccess:async(t,n)=>{i();const s=await this.#o.acquireConnection(null!=n?AbortSignal.timeout(n):void 0);if(!e)return await s.returnLease(),i();const o=crypto.randomUUID();return r.set(o,{lease:s,write:t}),o},completeAccess:async t=>{const e=o(t);r.delete(t);try{if(e.write){const{rawRows:t}=await e.lease.use(t=>t.execute("SELECT powersync_update_hooks('get')"));if(t.length){const e=JSON.parse(t[0][0]);e.length&&(this.#s.postMessage(e),this.#i(e))}}}finally{await e.lease.returnLease()}},execute:async(t,e,n)=>{const{lease:s}=o(t);return await s.use(t=>t.execute(e,n))},executeBatch:async(t,e,n)=>{const{lease:s}=o(t);return await s.use(t=>t.executeBatch(e,n))},setUpdateListener:async t=>{i(),s&&this.#r.delete(s),s=t,t&&this.#r.add(t)}}}async forceClose(){this.#a.log({level:_.debug,message:`Closing connection to ${JSON.stringify(this.#o.options)}.`});const t=this.#o;this.#t.onClose(),this.#s.close(),await t.close()}}const N=()=>{if("locks"in navigator&&navigator.locks)return navigator.locks;throw new Error("Navigator locks are not available in an insecure context. Use a secure context such as HTTPS or http://localhost.")},$=0,B=1,W=5,j=10,z=12,H=14,V=3338,J=3594,G=4106,K=2570,Q=1802,Y=1034,X=3850,Z=266,tt=522,et=1546,nt=2058,st=778,rt=4,it=8,ot=64,at=256,ct=512,lt=2048,ut=16384,ht=524288,dt=0,pt=1,gt=2,mt=4,ft=2048,yt=16384,wt=11,bt=14,St=21,vt=31,_t=32,Ct=33;void 0===BigInt.prototype.toJSON&&(BigInt.prototype.toJSON=function(){return this.toString()});const Et=0x7fffffffffffffffn,kt=-0x8000000000000000n,At=Object.getPrototypeOf(async function(){}).constructor;class Lt extends Error{constructor(t,e){super(t),this.code=e}}const qt=!0;function Tt(t){const e=[],n=t.match(/([ns@]*):([nsv@])/);switch(n[2]){case"n":e.push("number");break;case"s":e.push("string");break;case"v":e.push(null)}const s=[];for(let t of n[1])switch(t){case"n":s.push("number");break;case"s":s.push("string")}return e.push(s),e}var xt,Pt;async function It(t){if(t){const{default:t}=await import("./mc-wa-sqlite-async-DJG_ANKO.js");return t()}{const{default:t}=await import("./wa-sqlite-async-BxkwNY-2.js");return t()}}async function Ot(t){if(t){const{default:t}=await import("./mc-wa-sqlite-PubB6u8c.js");return t()}{const{default:t}=await import("./wa-sqlite-D1_4mGs8.js");return t()}}!function(t){t.IDBBatchAtomicVFS="IDBBatchAtomicVFS",t.OPFSCoopSyncVFS="OPFSCoopSyncVFS",t.AccessHandlePoolVFS="AccessHandlePoolVFS",t.OPFSWriteAheadVFS="OPFSWriteAheadVFS",t.InMemoryVfs="InMemoryVFS"}(xt||(xt={})),function(t){t.MEMORY="memory",t.FILESYSTEM="file"}(Pt||(Pt={}));class Rt{#c;#l=new Map;constructor(t){this.#c=t}lookup(t){const e=this.#l.get(t);return null!=e?(this.#l.delete(t),this.#l.set(t,e),e):null}addStatement(t,e){if(this.#l.set(t,e),this.#l.size>this.#c)for(const[t,e]of this.#l.entries())return this.#l.delete(t),e;return null}drain(){const t=[...this.#l.values()];return this.#l.clear(),t}}class Mt{options;_sqliteAPI=null;sqlite3_stmt_isexplain;db=0;statementCache;constructor(t){this.options=t,this.statementCache=t.preparedStatementsCache>0?new Rt(t.preparedStatementsCache):null}get isOpen(){return 0!=this.db}async init(){const{module:t,vfs:e}=await async function({vfs:t,filename:e,encryptionKey:n}){let s,r=Ot;switch(t){case xt.IDBBatchAtomicVFS:{r=It;const{IDBBatchAtomicVFS:t}=await import("./IDBBatchAtomicVFS-DbkDb777.js");s=n=>t.create(e,n,{lockPolicy:"exclusive"});break}case xt.AccessHandlePoolVFS:{const{AccessHandlePoolVFS:t}=await import("./AccessHandlePoolVFS-BPUHfZME.js");s=n=>t.create(e,n);break}case xt.OPFSCoopSyncVFS:{const{OPFSCoopSyncVFS:t}=await import("./OPFSCoopSyncVFS-BgTiWPfa.js");s=n=>t.create(e,n);break}case xt.OPFSWriteAheadVFS:{const{OPFSWriteAheadVFS:t}=await import("./OPFSWriteAheadVFS-Rt5CGCZP.js");s=n=>t.create(e,n,{});break}case xt.InMemoryVfs:{const{MemoryVFS:t}=await import("./MemoryVFS-DVJL5F8j.js");s=n=>t.create(e,n);break}}const i=await r(n);return{module:i,vfs:await s(i)}}(this.options);await this.initWithModule(t,e)}async initWithModule(t,e){const n=this._sqliteAPI=await this.openSQLiteAPI(t,e);if(this.db=await n.open_v2(this.options.filename,this.options.readonly?1:6),await this.executeRaw(`PRAGMA temp_store = ${this.options.temporaryStorage};`),this.options.encryptionKey){const t=this.options.encryptionKey.replaceAll("'","''");await this.executeRaw(`PRAGMA key = '${t}';`)}await this.executeRaw(`PRAGMA cache_size = -${this.options.cacheSizeKb};`),await this.executeRaw("SELECT powersync_update_hooks('install');")}async openSQLiteAPI(t,e){e.mxPathname=128,this.sqlite3_stmt_isexplain=t.cwrap("sqlite3_stmt_isexplain","int",["int"]);const n=function(t){const e={};t.retryOps=[],t.pendingOps=[];const n=t._getSqliteFree(),s=t._malloc(8),r=[s,s+4],i=new TextEncoder;function o(e){if("string"!=typeof e)return 0;const n=i.encode(e),s=t._sqlite3_malloc(n.byteLength+1);return t.HEAPU8.set(n,s),t.HEAPU8[s+n.byteLength]=0,s}function a(t,e){return BigInt(e)<<32n|0xffffffffn&BigInt(t)}const c=function(){const t=BigInt(Number.MAX_SAFE_INTEGER)>>32n,e=BigInt(Number.MIN_SAFE_INTEGER)>>32n;return function(n,s){return s>t||s<e?a(n,s):4294967296*s+(2147483647&n)-(2147483648&n)}}(),l=new Set;function u(t){if(!l.has(t))throw new Lt("not a database",21)}const h=new Map;function d(t){if(!h.has(t))throw new Lt("not a statement",21)}function p(e,n,s=null,r=[0]){if(r.includes(n))return n;const i=s?t.ccall("sqlite3_errmsg","string",["number"],[s]):e;throw new Lt(i,n)}async function g(e){let n;for(let s=0;s<2;++s){if(t.retryOps.length)try{await Promise.all(t.retryOps)}finally{t.retryOps=[]}if(n=await e(),0===n||0===t.retryOps.length){if(t.pendingOps.length)try{await Promise.all(t.pendingOps)}catch(t){return console.error("Error in pendingOps:",t),t.code||1}finally{t.pendingOps=[]}return n}}return n}return e.bind_collection=function(t,n){d(t);const s=Array.isArray(n),r=e.bind_parameter_count(t);for(let i=1;i<=r;++i){const r=n[s?i-1:e.bind_parameter_name(t,i)];void 0!==r&&e.bind(t,i,r)}return 0},e.bind=function(t,n,s){switch(d(t),typeof s){case"number":return s===(0|s)?e.bind_int(t,n,s):e.bind_double(t,n,s);case"string":return e.bind_text(t,n,s);case"boolean":return e.bind_int(t,n,s?1:0);default:return s instanceof Uint8Array||Array.isArray(s)?e.bind_blob(t,n,s):null===s?e.bind_null(t,n):"bigint"==typeof s?e.bind_int64(t,n,s):void 0===s?27:(console.warn("unknown binding converted to null",s),e.bind_null(t,n))}},e.bind_blob=function(){const e="sqlite3_bind_blob",s=t.cwrap(e,...Tt("nnnnn:n"));return function(r,i,o){d(r);const a=o.byteLength??o.length,c=t._sqlite3_malloc(a);t.HEAPU8.subarray(c).set(o);const l=s(r,i,c,a,n);return p(e,l,h.get(r))}}(),e.bind_parameter_count=function(){const e=t.cwrap("sqlite3_bind_parameter_count",...Tt("n:n"));return function(t){return d(t),e(t)}}(),e.bind_double=function(){const e="sqlite3_bind_double",n=t.cwrap(e,...Tt("nnn:n"));return function(t,s,r){d(t);const i=n(t,s,r);return p(e,i,h.get(t))}}(),e.bind_int=function(){const e="sqlite3_bind_int",n=t.cwrap(e,...Tt("nnn:n"));return function(t,s,r){if(d(t),r>2147483647||r<-2147483648)return 25;const i=n(t,s,r);return p(e,i,h.get(t))}}(),e.bind_int64=function(){const e="sqlite3_bind_int64",n=t.cwrap(e,...Tt("nnnn:n"));return function(t,s,r){if(d(t),r>Et||r<kt)return 25;const i=r>>32n,o=n(t,s,Number(0xffffffffn&r),Number(i));return p(e,o,h.get(t))}}(),e.bind_null=function(){const e="sqlite3_bind_null",n=t.cwrap(e,...Tt("nn:n"));return function(t,s){d(t);const r=n(t,s);return p(e,r,h.get(t))}}(),e.bind_parameter_name=function(){const e=t.cwrap("sqlite3_bind_parameter_name",...Tt("n:s"));return function(t,n){return d(t),e(t,n)}}(),e.bind_text=function(){const e="sqlite3_bind_text",s=t.cwrap(e,...Tt("nnnnn:n"));return function(t,r,i){d(t);const a=o(i),c=s(t,r,a,-1,n);return p(e,c,h.get(t))}}(),e.changes=function(){const e=t.cwrap("sqlite3_changes",...Tt("n:n"));return function(t){return u(t),e(t)}}(),e.clear_bindings=function(){const e="sqlite3_clear_bindings",n=t.cwrap(e,...Tt("n:n"));return function(t){d(t);const s=n(t);return p(e,s,h.get(t))}}(),e.last_insert_id=function(){const e=t.cwrap("sqlite3_last_insert_rowid",...Tt("n:n"));return function(t){return u(t),e(t)}}(),e.close=function(){const e="sqlite3_close",n=t.cwrap(e,...Tt("n:n"),{async:qt});return async function(t){u(t);const s=await n(t);return l.delete(t),p(e,s,t)}}(),e.column=function(n,s){d(n);const r=e.column_type(n,s);switch(r){case 4:return e.column_blob(n,s);case 2:return e.column_double(n,s);case 1:const i=e.column_int(n,s),o=t.getTempRet0();return c(i,o);case 5:return null;case 3:return e.column_text(n,s);default:throw new Lt("unknown type",r)}},e.column_blob=function(){const n=t.cwrap("sqlite3_column_blob",...Tt("nn:n"));return function(s,r){d(s);const i=e.column_bytes(s,r),o=n(s,r);return t.HEAPU8.subarray(o,o+i)}}(),e.column_bytes=function(){const e=t.cwrap("sqlite3_column_bytes",...Tt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_count=function(){const e=t.cwrap("sqlite3_column_count",...Tt("n:n"));return function(t){return d(t),e(t)}}(),e.column_double=function(){const e=t.cwrap("sqlite3_column_double",...Tt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_int=function(){const e=t.cwrap("sqlite3_column_int64",...Tt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.column_int64=function(){const e=t.cwrap("sqlite3_column_int64",...Tt("nn:n"));return function(n,s){return d(n),a(e(n,s),t.getTempRet0())}}(),e.column_name=function(){const e=t.cwrap("sqlite3_column_name",...Tt("nn:s"));return function(t,n){return d(t),e(t,n)}}(),e.column_names=function(t){const n=[],s=e.column_count(t);for(let r=0;r<s;++r)n.push(e.column_name(t,r));return n},e.column_text=function(){const e=t.cwrap("sqlite3_column_text",...Tt("nn:s"));return function(t,n){return d(t),e(t,n)}}(),e.column_type=function(){const e=t.cwrap("sqlite3_column_type",...Tt("nn:n"));return function(t,n){return d(t),e(t,n)}}(),e.create_function=function(e,n,s,r,i,o,a,c){function l(e){return e instanceof At?async(n,s,r)=>e(n,t.HEAP32.subarray(r/4,r/4+s)):(n,s,r)=>e(n,t.HEAP32.subarray(r/4,r/4+s))}return u(e),p("sqlite3_create_function",t.create_function(e,n,s,r,i,o&&l(o),a&&l(a),c),e)},e.data_count=function(){const e=t.cwrap("sqlite3_data_count",...Tt("n:n"));return function(t){return d(t),e(t)}}(),e.exec=async function(t,n,s){for await(const r of e.statements(t,n)){let t;for(;100===await e.step(r);)if(s){t=t??e.column_names(r);const n=e.row(r);await s(n,t)}}return 0},e.finalize=function(){const e=t.cwrap("sqlite3_finalize",...Tt("n:n"),{async:qt});return async function(t){const n=await e(t);return h.delete(t),n}}(),e.get_autocommit=function(){const e=t.cwrap("sqlite3_get_autocommit",...Tt("n:n"));return function(t){return e(t)}}(),e.libversion=function(){const e=t.cwrap("sqlite3_libversion",...Tt(":s"));return function(){return e()}}(),e.libversion_number=function(){const e=t.cwrap("sqlite3_libversion_number",...Tt(":n"));return function(){return e()}}(),e.limit=function(){const e=t.cwrap("sqlite3_limit",...Tt("nnn:n"));return function(t,n,s){return e(t,n,s)}}(),e.open_v2=function(){const e="sqlite3_open_v2",n=t.cwrap(e,...Tt("snnn:n"),{async:qt});return async function(s,i,a){i=i||6,a=o(a);try{const o=await g(()=>n(s,r[0],i,a)),c=t.getValue(r[0],"*");return l.add(c),t.ccall("RegisterExtensionFunctions","number",["number"],[c]),p(e,o),c}finally{t._sqlite3_free(a)}}}(),e.progress_handler=function(e,n,s,r){u(e),t.progress_handler(e,n,s,r)},e.reset=function(){const e="sqlite3_reset",n=t.cwrap(e,...Tt("n:n"),{async:qt});return async function(t){d(t);const s=await n(t);return p(e,s,h.get(t))}}(),e.result=function(t,n){switch(typeof n){case"number":n===(0|n)?e.result_int(t,n):e.result_double(t,n);break;case"string":e.result_text(t,n);break;default:if(n instanceof Uint8Array||Array.isArray(n))e.result_blob(t,n);else if(null===n)e.result_null(t);else{if("bigint"==typeof n)return e.result_int64(t,n);console.warn("unknown result converted to null",n),e.result_null(t)}}},e.result_blob=function(){const e=t.cwrap("sqlite3_result_blob",...Tt("nnnn:n"));return function(s,r){const i=r.byteLength??r.length,o=t._sqlite3_malloc(i);t.HEAPU8.subarray(o).set(r),e(s,o,i,n)}}(),e.result_double=function(){const e=t.cwrap("sqlite3_result_double",...Tt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int=function(){const e=t.cwrap("sqlite3_result_int",...Tt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int64=function(){const e=t.cwrap("sqlite3_result_int64",...Tt("nnn:n"));return function(t,n){if(n>Et||n<kt)return 25;const s=n>>32n;e(t,Number(0xffffffffn&n),Number(s))}}(),e.result_null=function(){const e=t.cwrap("sqlite3_result_null",...Tt("n:n"));return function(t){e(t)}}(),e.result_text=function(){const e=t.cwrap("sqlite3_result_text",...Tt("nnnn:n"));return function(t,s){const r=o(s);e(t,r,-1,n)}}(),e.row=function(n){const s=[],r=e.data_count(n);for(let i=0;i<r;++i){const r=e.column(n,i);s.push(r?.buffer===t.HEAPU8.buffer?r.slice():r)}return s},e.set_authorizer=function(e,n,s){function r(e,n,s,r,i,o){return[e,n,t.UTF8ToString(s),t.UTF8ToString(r),t.UTF8ToString(i),t.UTF8ToString(o)]}var i;return u(e),p("sqlite3_set_authorizer",t.set_authorizer(e,(i=n)instanceof At?async(t,e,n,s,o,a)=>i(...r(t,e,n,s,o,a)):(t,e,n,s,o,a)=>i(...r(t,e,n,s,o,a)),s),e)},e.sql=function(){const e=t.cwrap("sqlite3_sql",...Tt("n:s"));return function(t){return d(t),e(t)}}(),e.statements=function(n,s,r={}){const o=t.cwrap("sqlite3_prepare_v3","number",["number","number","number","number","number","number"],{async:!0});return async function*(){const a=[];try{const c=i.encode(s),l=c.byteLength-c.byteLength%4+12,u=t._sqlite3_malloc(l),d=u+c.byteLength+1;a.push(()=>t._sqlite3_free(u)),t.HEAPU8.set(c,u),t.HEAPU8[d-1]=0;const m=u+l-8,f=u+l-4;let y;function w(){y&&!r.unscoped&&e.finalize(y),y=0}a.push(w),t.setValue(f,u,"*");do{w();const b=t.getValue(f,"*"),S=await g(()=>o(n,b,d-f,r.flags||0,m,f));0!==S&&p("sqlite3_prepare_v3",S,n),y=t.getValue(m,"*"),y&&(h.set(y,n),yield y)}while(y)}finally{for(;a.length;)a.pop()()}}()},e.step=function(){const e="sqlite3_step",n=t.cwrap(e,...Tt("n:n"),{async:qt});return async function(t){d(t);const s=await g(()=>n(t));return p(e,s,h.get(t),[100,101])}}(),e.commit_hook=function(e,n){u(e),t.commit_hook(e,n)},e.update_hook=function(e,n){function s(e,n,s,r,i){return[e,t.UTF8ToString(n),t.UTF8ToString(s),a(r,i)]}var r;u(e),t.update_hook(e,(r=n)instanceof At?async(t,e,n,i,o)=>r(...s(t,e,n,i,o)):(t,e,n,i,o)=>r(...s(t,e,n,i,o)))},e.value=function(n){const s=e.value_type(n);switch(s){case 4:return e.value_blob(n);case 2:return e.value_double(n);case 1:const r=e.value_int(n),i=t.getTempRet0();return c(r,i);case 5:return null;case 3:return e.value_text(n);default:throw new Lt("unknown type",s)}},e.value_blob=function(){const n=t.cwrap("sqlite3_value_blob",...Tt("n:n"));return function(s){const r=e.value_bytes(s),i=n(s);return t.HEAPU8.subarray(i,i+r)}}(),e.value_bytes=function(){const e=t.cwrap("sqlite3_value_bytes",...Tt("n:n"));return function(t){return e(t)}}(),e.value_double=function(){const e=t.cwrap("sqlite3_value_double",...Tt("n:n"));return function(t){return e(t)}}(),e.value_int=function(){const e=t.cwrap("sqlite3_value_int64",...Tt("n:n"));return function(t){return e(t)}}(),e.value_int64=function(){const e=t.cwrap("sqlite3_value_int64",...Tt("n:n"));return function(n){return a(e(n),t.getTempRet0())}}(),e.value_text=function(){const e=t.cwrap("sqlite3_value_text",...Tt("n:s"));return function(t){return e(t)}}(),e.value_type=function(){const e=t.cwrap("sqlite3_value_type",...Tt("n:n"));return function(t){return e(t)}}(),e.vfs_register=function(e,n){return p("sqlite3_vfs_register",t.vfs_register(e,n))},e}(t);if(n.vfs_register(e,!0),t.ccall("powersync_init_static","int",[]),this.options.encryptionKey){if(0!==t.ccall("sqlite3mc_vfs_create","int",["string","int"],[this.options.filename,1]))throw new Error("Failed to create multiple cipher vfs, Database encryption will not work")}return n}requireSqlite(){if(!this._sqliteAPI)throw new Error("Initialization has not completed");return this._sqliteAPI}isAutoCommit(){return 0!=this.requireSqlite().get_autocommit(this.db)}async execute(t,e){const n=await this.executeSingleStatementRaw(t,e);return this.wrapQueryResults(this.requireSqlite(),n)}async executeBatch(t,e){const n=[],s=this.requireSqlite();for await(const r of s.statements(this.db,t)){let t;for(const i of e){const e=await this.stepThroughStatement(s,r,i,t,!1);n.push(this.wrapQueryResults(s,e))}break}return n}wrapQueryResults(t,{rawRows:e,columnNames:n}){return{rowsAffected:t.changes(this.db),insertId:t.last_insert_id(this.db),autocommit:0!=t.get_autocommit(this.db),rawRows:e,columnNames:n}}async executeSingleStatementRaw(t,e){const n=await this.executeRaw(t,e);return n.length?n[0]:{columnNames:[],rawRows:[]}}async executeRaw(t,e){const n=[],s=this.requireSqlite();for await(const r of this.cachedStatements(s,t)){let t;const i=await this.stepThroughStatement(s,r,e??[],t);if(t=i.columnNames,t.length&&n.push(i),e)break}return n}async stepThroughStatement(t,e,n,s,r=!0){n.forEach((t,e,n)=>{"boolean"==typeof t&&(n[e]=t?1:0)}),t.reset(e),n&&t.bind_collection(e,n);const i=[];for(;100===await t.step(e);)if(r){const n=t.row(e);i.push(n)}return s??=t.column_names(e),{columnNames:s,rawRows:i}}async close(){if(this.isOpen){const t=this.requireSqlite();if(this.statementCache)for(const e of this.statementCache.drain())await t.finalize(e);await t.close(this.db),this.db=0}}async*cachedStatements(t,e){{const t=this.statementCache?.lookup(e);if(null!=t)return void(yield t)}const n=t.statements(this.db,e,{unscoped:!0}),s=[];try{for await(const t of n)s.push(t),yield t}finally{if(1===s.length&&this.statementCache){const n=s[0];if(0==this.sqlite3_stmt_isexplain(n)){const s=this.statementCache.addStatement(e,n);return void(null!=s&&await t.finalize(s))}}for(const e of s)await t.finalize(e)}}}var Ft,Ut;async function Dt(t,e,n){const{rawRows:s}=await t.executeRaw("SELECT CAST(powersync_control(?, ?) AS TEXT)",[e,n]);return s[0][0]}function Nt(t,e=null){return Dt(t,"target_checkpoint_request_id",e)}!function(t){t.DATA="ps_data",t.CRUD="ps_crud",t.BUCKETS="ps_buckets",t.OPLOG="ps_oplog",t.UNTYPED="ps_untyped"}(Ft||(Ft={})),function(t){t.PROCESS_TEXT_LINE="line_text",t.PROCESS_BSON_LINE="line_binary",t.STOP="stop",t.START="start",t.NOTIFY_TOKEN_REFRESHED="refreshed_token",t.NOTIFY_CRUD_UPLOAD_COMPLETED="completed_upload",t.UPDATE_SUBSCRIPTIONS="update_subscriptions",t.CONNECTION_STATE="connection"}(Ut||(Ut={}));const $t=2147483647,Bt="9223372036854775807";class Wt{internal;totalOperations;downloadedOperations;downloadedFraction;constructor(t){this.internal=t;const e=this.untilPriority($t);this.totalOperations=e.totalOperations,this.downloadedOperations=e.downloadedOperations,this.downloadedFraction=e.downloadedFraction}untilPriority(t){let e=0,n=0;for(const s of Object.values(this.internal.buckets))s.priority<=t&&(n+=s.since_last,e+=s.target_count-s.at_last);return{totalOperations:e,downloadedOperations:n,downloadedFraction:0==e?0:n/e}}}class jt{core;jsState;constructor(t,e){this.core=t,this.jsState=e}get connected(){return this.core?.connected??!1}get connecting(){return this.core?.connecting??!1}get downloading(){return null!=this.core?.downloading}get uploading(){return this.jsState.uploading??!1}get downloadError(){return this.jsState.downloadError}get uploadError(){return this.jsState.uploadError}get dataFlowStatus(){return{downloading:this.downloading,uploading:this.uploading,downloadError:this.downloadError,uploadError:this.uploadError}}get lastSyncedAt(){return this.statusForPriority($t)?.lastSyncedAt}get hasSynced(){return this.statusForPriority($t)?.hasSynced}get syncStreams(){return this.core?.streams.map(t=>new Ht(this,t))}forStream(t){const e=JSON.stringify(t.parameters),n=this.core?.streams?.find(n=>n.name==t.name&&e==JSON.stringify(n.parameters));return n&&new Ht(this,n)}get priorityStatusEntries(){return this.core?.priority_status.map(zt)}get downloadProgress(){const t=this.core?.downloading;return null==t?null:new Wt(t)}statusForPriority(t){const e=this.core?.priority_status;if(null!=e){for(const n of e)if(n.priority>=t)return zt(n);return{priority:t,lastSyncedAt:void 0,hasSynced:!1}}}isEqual(t){const e=(t,e)=>e instanceof Error?this.serializeError(e):e,n={core:this.core,jsState:this.jsState},s=t,r={core:s.core,jsState:s.jsState};return JSON.stringify(n,e)==JSON.stringify(r,e)}getMessage(){return`SyncStatus<connected: ${this.connected} connecting: ${this.connecting} lastSyncedAt: ${this.lastSyncedAt} hasSynced: ${this.hasSynced}. Downloading: ${this.downloading}. Uploading: ${this.uploading}. UploadError: ${this.uploadError}, DownloadError?: ${this.downloadError}>`}toJSON(){return{core:this.core,dataFlow:{uploading:this.uploading,uploadError:this.serializeError(this.uploadError),downloadError:this.serializeError(this.downloadError)}}}serializeError(t){if(void 0===t)return;const e={name:t.name,message:t.message,stack:t.stack};return void 0!==t.cause&&(e.cause=t.cause instanceof Error?this.serializeError(t.cause):t.cause),e}}function zt(t){return{priority:t.priority,hasSynced:t.has_synced??void 0,lastSyncedAt:(e=t.last_synced_at,null==e?void 0:new Date(e/1e3))};var e}class Ht{status;core;subscription;constructor(t,e){this.status=t,this.core=e,this.subscription={name:e.name,parameters:e.parameters,active:e.active,isDefault:e.is_default,hasExplicitSubscription:e.has_explicit_subscription,expiresAt:null!=e.expires_at?new Date(1e3*e.expires_at):null,hasSynced:null!=e.last_synced_at,lastSyncedAt:null!=e.last_synced_at?new Date(1e3*e.last_synced_at):null}}get progress(){if(null==this.status.core?.downloading)return null;const{total:t,downloaded:e}=this.core.progress;return{totalOperations:t,downloadedOperations:e,downloadedFraction:0==t?0:e/t}}get priority(){return this.core.priority}}class Vt extends I{options;connectingPromise;syncStreamInitPromise;disconnectingPromise;pendingConnectionOptions;currentOptions;syncStreamImplementation;syncDisposer;locallyActiveSubscriptions=new Map;constructor(t){super(),this.options=t,this.connectingPromise=null,this.syncStreamInitPromise=null,this.disconnectingPromise=null,this.pendingConnectionOptions=null,this.syncStreamImplementation=null,this.currentOptions=null,this.syncDisposer=null}get connector(){return this.pendingConnectionOptions?.connector??null}get connectionOptions(){return this.currentOptions??this.pendingConnectionOptions?.options??null}get logger(){return this.options.logger}async close(){await(this.syncStreamImplementation?.dispose()),await(this.syncDisposer?.())}async connect(t,e,n){const s=!!this.pendingConnectionOptions,r=function(t,e){return{appMetadata:t.appMetadata??{},connectionMethod:t.connectionMethod??e,fetchStrategy:t.fetchStrategy??T.Buffered,params:t.params??{},includeDefaultStreams:t.includeDefaultStreams??!0,retryDelayMs:t.retryDelayMs??5e3,crudUploadThrottleMs:t.crudUploadThrottleMs??1e3,checkpointMode:t.checkpointMode??"legacy"}}(e,this.options.defaultConnectionMethod);this.pendingConnectionOptions={connector:t,options:r,schema:n},t.postCheckpointRequest&&"legacy"==r.checkpointMode&&this.logger.log({level:_.warn,message:"The backend connector implements postCheckpointRequest, but connect() was called without checkpoint requests enabled."}),s&&!this.syncStreamImplementation||await this.disconnectInternal();const i=async()=>this.pendingConnectionOptions?(this.connectingPromise=this.connectInternal().catch(()=>{}).finally(i),this.connectingPromise):void(this.connectingPromise=null);return this.connectingPromise??=this.connectInternal().catch(()=>{}).finally(i),this.connectingPromise}async connectInternal(){let t=null;await this.disconnectInternal(),this.syncStreamInitPromise=new Promise(async(e,n)=>{try{if(!this.pendingConnectionOptions)return this.logger.log({level:_.debug,message:"No pending connection options found, not creating sync stream implementation"}),void e();if(this.disconnectingPromise)return void e();const{connector:n,options:s,schema:r}=this.pendingConnectionOptions;t=s,this.currentOptions=s,this.pendingConnectionOptions=null;const i=this.subscriptionIdentity,{sync:o,onDispose:a}=await this.options.createSyncImplementation(n,{subscriptions:this.activeStreams,serializedSchema:r});this.iterateListeners(t=>t.syncStreamCreated?.(o)),this.syncStreamImplementation=o,this.syncDisposer=a,await this.syncStreamImplementation.waitForReady(),this.subscriptionIdentity!==i&&this.syncStreamImplementation.updateSubscriptions(this.activeStreams),e()}catch(t){n(t)}}),await this.syncStreamInitPromise,this.syncStreamInitPromise=null,t&&(await this.disconnectingPromise,this.logger.log({level:_.debug,message:"Attempting to connect to PowerSync instance"}),await(this.syncStreamImplementation?.connect(t)))}async disconnect(){this.pendingConnectionOptions=null,this.currentOptions=null,await this.disconnectInternal()}async disconnectInternal(){if(this.disconnectingPromise)return this.disconnectingPromise;this.disconnectingPromise=this.performDisconnect(),await this.disconnectingPromise,this.disconnectingPromise=null}async performDisconnect(){await this.syncStreamInitPromise;const t=this.syncStreamImplementation;this.syncStreamImplementation=null;const e=this.syncDisposer;this.syncDisposer=null,await(t?.disconnect()),await(t?.dispose()),await(e?.())}stream(t,e,n){const s={name:e,parameters:n},r=e=>t.firstStatusMatching(t=>t.forStream(s)?.subscription.hasSynced,e);return{...s,subscribe:async s=>{await t.rustSubscriptionsCommand({subscribe:{stream:{name:e,params:n},ttl:s?.ttl,priority:s?.priority}}),this.syncStreamImplementation||await t.resolveOfflineSyncStatus();const i=`${e}|${JSON.stringify(n)}`;let o=this.locallyActiveSubscriptions.get(i);if(null==o){const t=()=>{this.locallyActiveSubscriptions.delete(i),this.subscriptionsMayHaveChanged()};o=new Jt(e,n,this.logger,r,t),this.locallyActiveSubscriptions.set(i,o),this.subscriptionsMayHaveChanged()}return new Gt(o)},unsubscribeAll:async()=>{await t.rustSubscriptionsCommand({unsubscribe:{name:e,params:n}}),this.subscriptionsMayHaveChanged()}}}get activeStreams(){return[...this.locallyActiveSubscriptions.values()].map(t=>({name:t.name,params:t.parameters}))}get subscriptionIdentity(){return[...this.locallyActiveSubscriptions.keys()].join("\n")}subscriptionsMayHaveChanged(){this.syncStreamImplementation?.updateSubscriptions(this.activeStreams)}}class Jt{name;parameters;logger;waitForFirstSync;clearSubscription;refcount=0;constructor(t,e,n,s,r){this.name=t,this.parameters=e,this.logger=n,this.waitForFirstSync=s,this.clearSubscription=r}decrementRefCount(){this.refcount--,0==this.refcount&&this.clearSubscription()}}class Gt{subscription;active=!0;constructor(t){this.subscription=t,t.refcount++,Kt?.register(this,t,this)}get name(){return this.subscription.name}get parameters(){return this.subscription.parameters}waitForFirstSync(t){return this.subscription.waitForFirstSync(t)}unsubscribe(){this.active&&(this.active=!1,Kt?.unregister(this),this.subscription.decrementRefCount())}}const Kt="FinalizationRegistry"in globalThis?new FinalizationRegistry(t=>{t.logger.log({level:_.warn,message:`A subscription to ${t.name} with params ${JSON.stringify(t.parameters)} leaked! Please ensure calling unsubscribe() when you don't need a subscription anymore. For global subscriptions, consider storing them in global fields to avoid this warning.`})}):null;class Qt{table;head;_length;constructor(t){this.table=[...t],this.head=0,this._length=this.table.length}get isEmpty(){return 0==this.length}get length(){return this._length}removeFirst(){if(this.isEmpty)throw new Error("Queue is empty");const t=this.table[this.head];return this._length--,this.table[this.head]=void 0,this.head=(this.head+1)%this.table.length,t}addLast(t){if(this.length==this.table.length)throw new Error("Queue is full");this.table[(this.head+this._length)%this.table.length]=t,this._length++}}class Yt{available;size;firstWaiter;lastWaiter;constructor(t){this.available=new Qt(t),this.size=this.available.length}addWaiter(t,e){const n={isActive:!0,acquiredItems:[],remainingItems:t,onAcquire:e,prev:this.lastWaiter};return this.lastWaiter?(this.lastWaiter.next=n,this.lastWaiter=n):this.lastWaiter=this.firstWaiter=n,n}deactivateWaiter(t){const{prev:e,next:n}=t;t.isActive=!1,e&&(e.next=n),n&&(n.prev=e),t==this.firstWaiter&&(this.firstWaiter=n),t==this.lastWaiter&&(this.lastWaiter=e)}requestPermits(t,e){if(t<=0||t>this.size)throw new Error(`Invalid amount of items requested (${t}), must be between 1 and ${this.size}`);return new Promise((n,s)=>{function r(){s(e?.reason??new Error("Semaphore acquire aborted"))}if(e?.aborted)return r();let i;const o=()=>{const t=i.acquiredItems;i.acquiredItems=[];for(const e of t){const t=this.firstWaiter;t?(t.acquiredItems.push(e),t.remainingItems--,0==t.remainingItems&&t.onAcquire()):this.available.addLast(e)}},a=()=>{e?.removeEventListener("abort",a),i.isActive&&(this.deactivateWaiter(i),r())},c=()=>{this.deactivateWaiter(i),e?.removeEventListener("abort",a);const t=i.acquiredItems;n({items:t,release:o})};for(i=this.addWaiter(t,c);!this.available.isEmpty&&i.remainingItems>0;)i.acquiredItems.push(this.available.removeFirst()),i.remainingItems--;if(0==i.remainingItems)return c();e?.addEventListener("abort",a)})}async requestOne(t){const{items:e,release:n}=await this.requestPermits(1,t);return{release:n,item:e[0]}}requestAll(t){return this.requestPermits(this.size,t)}}class Xt{inner=new Yt([null]);async acquire(t){const{release:e}=await this.inner.requestOne(t);return e}async runExclusive(t,e){const n=await this.acquire(e);try{return await t()}finally{n()}}}class Zt{clientId;id;op;opData;previousValues;table;transactionId;metadata;static fromRow(t){const e=JSON.parse(t.data);return new Zt(parseInt(t.id),e.op,e.type,e.id,t.tx_id,e.data,e.old,e.metadata)}constructor(t,e,n,s,r,i,o,a){this.clientId=t,this.id=s,this.op=e,this.opData=i,this.table=n,this.transactionId=r,this.previousValues=o,this.metadata=a}toJSON(){return{op_id:this.clientId,op:this.op,type:this.table,id:this.id,tx_id:this.transactionId,data:this.opData,old:this.previousValues,metadata:this.metadata}}equals(t){return JSON.stringify(this.toComparisonArray())==JSON.stringify(t.toComparisonArray())}toComparisonArray(){return[this.transactionId,this.clientId,this.op,this.table,this.id,this.opData,this.previousValues,this.metadata]}}const te=Symbol.asyncIterator??Symbol.for("Symbol.asyncIterator"),ee={done:!0,value:void 0};function ne(t){return{done:!1,value:t}}function se(t){let e,n=!1,s=null,r=!1,i=[];const o=()=>{const t=e;return e=void 0,t};return{next:()=>new Promise((a,c)=>{if(n)return a(ee);if(s)return s({resolve:a,reject:c}),void(s=null);if(i.length){const t=i.shift();return void("fulfilled"===t.status?a(ne(t.value)):c(t.reason))}e={resolve:a,reject:c},r||(()=>{const e=t=>{r=!1;const e=o();e?t(e):s=t};r=!0,t.next().then(t=>{n=1==t.done,e(e=>e.resolve(t))},t=>{e(e=>e.reject(t))})})()}),inject:t=>{const e=o();null!=e?e.resolve(ne(t)):i.push({status:"fulfilled",value:t})},injectError(t){const e=o();null!=e?e.reject(t):i.push({status:"rejected",reason:t})}}}function re(){const t=new ie;return{notify(){t.countOutstandingEvents>0||t.notify()},waitForNotification:e=>t.waitForEvent(e)}}class ie{options;waitingConsumer;outstandingEvents;constructor(t={}){this.options=t,this.outstandingEvents=[]}get countOutstandingEvents(){return this.outstandingEvents.length}notifyInner(t){const e=this.waitingConsumer;this.waitingConsumer=void 0;const n=e=>{t(e),this.options.eventDelivered?.()};e?n(e):this.outstandingEvents.push(n)}notify(t){this.notifyInner(e=>e.resolve(t))}notifyError(t){this.notifyInner(e=>e.reject(t))}waitForEvent(t){return new Promise((e,n)=>{if(null!=this.waitingConsumer)throw new Error("Illegal call to waitForEvent, already has a waiter.");const s=()=>{t?.removeEventListener("abort",r)},r=()=>{s(),this.waitingConsumer=void 0,e(void 0)},i={resolve:t=>{s(),e(t)},reject:t=>{s(),n(t)}};if(t.aborted)e(void 0);else if(this.countOutstandingEvents>0){const[t]=this.outstandingEvents.splice(0,1);t(i)}else this.waitingConsumer=i,t.addEventListener("abort",r)})}static queueBasedAsyncIterable(t,e){return{[te]:()=>{const n=new ie,s=new AbortController;function r(){s.abort(),e?.removeEventListener("abort",r)}return e&&(e.aborted?s.abort():e.addEventListener("abort",r)),t(n,s.signal),{async next(){const t=await n.waitForEvent(s.signal);return null==t?ee:ne(t)},return:async()=>(r(),ee)}}}}}class oe extends I{db;logger;updateListener;_clientId;constructor(t,e){super(),this.db=t,this.logger=e,this.updateListener=t.registerListener({tablesUpdated:({tables:t})=>{t.includes(Ft.CRUD)&&this.iterateListeners(t=>t.crudUpdate?.())}})}async dispose(){this.updateListener?.()}async _getClientId(){return(await this.db.get("SELECT powersync_client_id() as client_id")).client_id}getClientId(){return null==this._clientId&&(this._clientId=this._getClientId()),this._clientId}async updateLocalTarget(t){const e=await this.db.readTransaction(async t=>{if(await Nt(t)!=Bt)return;const e=await t.getOptional("SELECT seq FROM main.sqlite_sequence WHERE name = 'ps_crud'");return e?.seq});if(null==e)return!1;const n=await t();return this.writeTransaction(async t=>{const s=await t.execute("SELECT 1 FROM ps_crud LIMIT 1");if(s.rows?.length)return this.logger.log({level:_.debug,message:`New data uploaded since write checkpoint ${n} - need new write checkpoint`}),!1;const{seq:r}=await t.get("SELECT seq FROM main.sqlite_sequence WHERE name = 'ps_crud'");return r!=e?(this.logger.log({level:_.debug,message:`New data uploaded since write checpoint ${n} - need new write checkpoint (sequence updated)`}),!1):(this.logger.log({level:_.debug,message:`Updating target write checkpoint to ${n}`}),await Nt(t,n),!0)})}readCheckpointRequestId(t,e=null){return this.db.writeTransaction(async n=>await Dt(n,`${t}_checkpoint_request_id`,e))}async nextCrudItem(){const t=await this.db.getOptional("SELECT * FROM ps_crud ORDER BY id ASC LIMIT 1");if(t)return Zt.fromRow(t)}async hasCrud(){return!!await this.db.getOptional("SELECT 1 FROM ps_crud LIMIT 1")}async getCrudBatch(t=100){if(!await this.hasCrud())return null;const e=await this.db.getAll("SELECT * FROM ps_crud ORDER BY id ASC LIMIT ?",[t]),n=[];for(const t of e)n.push(Zt.fromRow(t));if(0===n.length)return null;const s=n[n.length-1];return{crud:n,haveMore:!0,complete:async t=>this.handleCrudCheckpoint(s.clientId,t)}}handleCrudCheckpoint(t,e){return this.writeTransaction(async n=>{if(await n.execute("DELETE FROM ps_crud WHERE id <= ?",[t]),e){const t=await n.execute("SELECT 1 FROM ps_crud LIMIT 1");t.rows?.length&&await Nt(n,e)}else await Nt(n,Bt)})}async writeTransaction(t,e){return this.db.writeTransaction(t,e)}async control(t,e){return await this.writeTransaction(async n=>await Dt(n,t,e))}async hasMigratedSubkeys(){const{r:t}=await this.db.get("SELECT EXISTS(SELECT * FROM ps_kv WHERE key = ?) as r",[oe._subkeyMigrationKey]);return 0!=t}async migrateToFixedSubkeys(){await this.writeTransaction(async t=>{await t.execute("UPDATE ps_oplog SET key = powersync_remove_duplicate_key_encoding(key);"),await t.execute("INSERT OR REPLACE INTO ps_kv (key, value) VALUES (?, ?);",[oe._subkeyMigrationKey,"1"])})}static _subkeyMigrationKey="powersync_js_migrated_subkeys"}const ae={state:"pending"};class ce{currentState=ae;stateChanged=new I;waitingForCheckpointsReady=re();updateState(t){this.currentState=t,this.stateChanged.iterateListeners(t=>t.stateChanged?.())}downloadIterationEnded(){this.updateState(ae),this.waitingForCheckpointsReady=re()}disconnected(){this.updateState({state:"disconnected"})}waitForCheckpointWaiter(t){return this.waitingForCheckpointsReady.waitForNotification(t)}markCheckpointsReady(t){return t.then(t=>this.updateState({state:"ready"}),t=>{throw this.updateState({state:"error",error:t}),t})}async waitForCheckpointRequestsReady(t,e=!0){return new Promise((n,s)=>{const r=()=>{const t=this.currentState;switch(t.state){case"disconnected":return s(new Error("Cannot request checkpoints, sync client is disconnected.")),!0;case"ready":return n(!0),!0;case"error":return s(t.error),!0;case"pending":return e&&this.waitingForCheckpointsReady.notify(),!1}};if(r())return;let i,o;function a(){i(),t.removeEventListener("abort",o)}o=()=>{n(!1),a()},i=this.stateChanged.registerListener({stateChanged(){r()&&a()}}),t.addEventListener("abort",o)})}}function le(t,e){const n=t?.internal_last_applied_checkpoint_request_id;return null!=n&&BigInt(n)>=e}class ue extends Error{reason;constructor(t){super(t),this.reason=t,Object.setPrototypeOf(this,ue.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ue)}}const he=/\/+$/,de={LogLevels:_,EventQueue:ie,AbortOperation:ue};class pe{connector;logger;credentials=null;constructor(t,e){this.connector=t,this.logger=e}async getCredentials(){return this.credentials?this.credentials:this.prefetchCredentials()}async prefetchCredentials(){return this.credentials=await this.fetchCredentials(),this.credentials}async fetchCredentials(){const t=await this.connector.fetchCredentials();if(t?.endpoint.match(he))throw new Error(`A trailing forward slash "/" was found in the fetchCredentials endpoint: "${t.endpoint}". Remove the trailing forward slash "/" to fix this error.`);return t}invalidateCredentials(){this.credentials=null,this.connector.invalidateCredentials?.()}getUserAgent(){return"powersync-js/1.2.0"}async buildRequest(t){const e=await this.getCredentials();if(null!=e&&(null==e.endpoint||""==e.endpoint))throw new Error("PowerSync endpoint not configured");if(null==e?.token||""==e?.token){const t=new Error("Not signed in");throw t.status=401,t}const n=this.getUserAgent();return{url:e.endpoint+t,headers:{"content-type":"application/json",Authorization:`Token ${e.token}`,"x-user-agent":n},userAgent:n,path:t}}async fetchAndDecodeJson({path:t,method:e="GET",headers:n,body:s,signal:r}){const i=await this.buildRequest(t),o=await this.fetch({resource:i.url,request:{method:e,headers:{...n,...i.headers},body:s,signal:r},expectStreamingResponse:!1});if(401===o.status&&this.invalidateCredentials(),!o.ok)throw new Error(`Received ${o.status} - ${o.statusText} when getting from ${t}: ${await o.text()}}`);return o.json()}createTextDecoder(){return new TextDecoder}createSocket(t){return new WebSocket(t)}async socketStreamRaw(t){const e=await this.loadWebSocketSupport(de),n=await this.buildRequest(t.path);n.url=n.url.replace(/^https?:\/\//,function(t){return"https://"===t?"wss://":"ws://"});const{fetchStrategy:s=T.Buffered,abortSignal:r,data:i}=t;return await e.webSocketSyncStream({remote:this,buffered:s==T.Buffered,abortSignal:r,requestPayload:i,request:n})}async fetchStreamRaw(t){const{data:e,path:n,abortSignal:s}=t,r=await this.buildRequest(n);if(s.aborted)throw new ue("Abort request received before making fetchStreamRaw request");const i=new AbortController;let o,a=null;s.addEventListener("abort",()=>{const t=s.reason??new ue("Cancelling network request before it resolves. Abort signal has been received.");null==a?i.abort(t):a.cancel(t).catch(()=>{})});let c=!1;try{const t="application/x-ndjson",s="application/vnd.powersync.bson-stream";if(o=await this.fetch({resource:r.url,request:{method:"POST",headers:{...r.headers,accept:`${s};q=0.9,${t};q=0.8`},body:JSON.stringify(e),signal:i.signal,cache:"no-store"},expectStreamingResponse:!0}),!o.ok||!o.body){const t=await o.text(),e=new Error(`HTTP ${o.statusText}: ${t}`);throw e.status=o.status,this.logger.log({level:_.error,message:`Could not POST streaming to ${n} - ${o.status} - ${o.statusText}: ${t}`,error:e}),401===o.status&&this.invalidateCredentials(),e}c=o.headers.get("content-type")==s}catch(t){if("AbortError"==t.name)throw new ue(`Pending fetch request to ${r.url} has been aborted.`);throw t}a=o.body.getReader();return{isBson:c,stream:{next:async()=>{if(i.signal.aborted)return ee;try{return await a.read()}catch(t){if(i.signal.aborted)return ee;throw t}}}}}async fetchStream(t){const{isBson:e,stream:n}=await this.fetchStreamRaw(t);return e?function(t){const e=[];let n=!1;const s=new DataView(new ArrayBuffer(4));let r=null,i=4;return{async next(){for(;;){if(e.length)return ne(e.shift());if(n)return ee;const o=await t.next();if(o.done){if(n=!0,r||4!=i)throw new Error("illegal end of stream in BSON object");return ee}const a=o.value;for(let t=0;t<a.length;){const n=a.length-t;if(r){const s=Math.min(n,i),o=new Uint8Array(a.buffer,a.byteOffset+t,s);r.set(o,r.length-i),t+=s,i-=s,0==i&&(e.push(r),r=null,i=4)}else{const e=Math.min(n,i);for(let n=0;n<e;n++)s.setUint8(4-i+n,a[t+n]);if(t+=e,i-=e,0==i){const t=s.getInt32(0,!0);if(i=t-4,i<1)throw new Error(`invalid length for bson: ${t}`);r=new Uint8Array(t),new DataView(r.buffer).setInt32(0,t,!0)}}}}}}}(n):function(t,e){let n="";const s=[];let r=!1;return{next:async()=>{for(;;){if(r)return ee;{const t=s.shift();if(t)return{done:!1,value:t}}const{done:i,value:o}=await t.next();if(i){const t=n.trim();return 0!=t.length?(r=!0,{done:!1,value:t}):ee}const a=e.decode(o,{stream:!0});n+=a;const c=n.split("\n");for(let t=0;t<c.length-1;t++){const e=c[t].trim();e.length>0&&s.push(e)}n=c[c.length-1]}}}}(n,this.createTextDecoder())}}function ge(t){return"EstablishSyncStream"in t||"CloseSyncStream"in t}var me;!function(t){t.CRUD="crud",t.SYNC="sync"}(me||(me={}));class fe extends I{options;abortController;crudUpdateListener;streamingSyncPromise;logger;activeStreams;connectionMayHaveChanged=!1;crudUploadNotifier=re();checkpoints=new ce;notifyCompletedUploads;handleActiveStreamsChange;syncStatus;constructor(t){super(),this.options=t,this.activeStreams=t.subscriptions,this.logger=t.logger,this.syncStatus=new jt(null,{}),this.abortController=null}triggerCrudUpload(){this.crudUploadNotifier.notify()}async waitForReady(){}waitUntilStatusMatches(t){return new Promise(e=>{if(t(this.syncStatus))return void e();const n=this.registerListener({statusChanged:()=>{t(this.syncStatus)&&(e(),n?.())}})})}get lastSyncedAt(){const t=this.syncStatus.lastSyncedAt;return t&&new Date(t)}get isConnected(){return this.syncStatus.connected}async dispose(){super.dispose(),this.crudUpdateListener?.(),this.crudUpdateListener=void 0}async requestNextCheckpointFromService(t){await this.checkpoints.waitForCheckpointRequestsReady(t);const e=await this.options.adapter.readCheckpointRequestId("next"),n=await this.options.adapter.getClientId();return await this.requestCheckpointFromService(t,{client_id:n,checkpoint_request_id:e})}async requestCheckpointFromService(t,e){{const t=await this.options.postCheckpointRequest(e.client_id,e.checkpoint_request_id);if(null!=t)return t}return(await this.options.remote.fetchAndDecodeJson({method:"POST",path:"/sync/checkpoint-request",body:JSON.stringify(e),signal:t})).data.checkpoint_request_id}async getLegacyWriteCheckpoint(){let t=`/write-checkpoint2.json?client_id=${await this.options.adapter.getClientId()}`;const e=(await this.options.remote.fetchAndDecodeJson({path:t})).data.write_checkpoint;return this.logger.log({level:_.debug,message:`Created write checkpoint: ${e}`}),e}async crudUploadLoop(t,e){for(;!t.aborted;)await Promise.all([this._uploadAllCrud(t,e),this.delayRetry(t,e.crudUploadThrottleMs)]),await this.crudUploadNotifier.waitForNotification(t)}async _uploadAllCrud(t,e){return this.obtainLock({type:me.CRUD,signal:t,callback:async()=>{let n;for(;!t.aborted;)try{const s=await this.options.adapter.nextCrudItem();if(!s){await this.options.adapter.updateLocalTarget(()=>"legacy"===e.checkpointMode?this.getLegacyWriteCheckpoint():this.requestNextCheckpointFromService(t))?this.notifyCompletedUploads?.():null!=n&&this.logger.log({level:_.debug,message:"Upload complete, no write checkpoint needed."});break}if(this.updateJsSyncState({uploading:!0}),s.clientId==n?.clientId)throw this.logger.log({level:_.warn,message:"Potentially previously uploaded CRUD entries are still present in the upload queue.\nMake sure to handle uploads and complete CRUD transactions or batches by calling and awaiting their [.complete()] method.\nThe next upload iteration will be delayed."}),new Error("Delaying due to previously encountered CRUD item.");n=s,await this.options.uploadCrud(),this.updateJsSyncState({uploadError:void 0})}catch(s){if(n=void 0,this.updateJsSyncState({uploading:!1,uploadError:s}),await this.delayRetry(t,e.retryDelayMs),!this.isConnected)break;this.logger.log({level:_.debug,message:"Caught exception when uploading. Upload will retry after a delay.",error:s})}finally{this.updateJsSyncState({uploading:!1})}}})}async connect(t){this.abortController&&await this.disconnect();const e=new AbortController;return this.abortController=e,this.streamingSyncPromise=Promise.all([this.crudUploadLoop(e.signal,t).catch(t=>this.logger.log({level:_.error,message:"Error in crud upload loop",error:t})),this.streamingSync(e.signal,t),this.repostUnacknowledgedCheckpointRequests(e.signal,t)]).finally(()=>{this.checkpoints.disconnected()}),new Promise(t=>{let e=!1;const n=this.registerListener({statusChanged:s=>{if(s.connecting&&(e=!0),null!=s.downloadError)this.logger.log({level:_.warn,message:"Initial connect attempt did not successfully connect to server"});else if(!e||s.connecting)return;n(),t()}})})}async requestCheckpoint(){const t=(new AbortController).signal;return BigInt(await this.requestNextCheckpointFromService(t))}async disconnect(){if(this.abortController){this.abortController.signal.aborted||this.abortController.abort(new ue("Disconnect has been requested"));try{await this.streamingSyncPromise}catch(t){this.logger.log({level:_.warn,message:"Error in sync while disconnecting",error:t})}this.streamingSyncPromise=void 0,this.abortController=null,this.markAsDisconnected()}}markAsDisconnected(){const t=this.syncStatus.core;null!=t&&this.updateSyncStatus({...t,connected:!1,connecting:!1,downloading:null})}async streamingSync(t,e){this.crudUpdateListener=this.options.adapter.registerListener({crudUpdate:()=>this.triggerCrudUpload()});let n=new AbortController;for(t.addEventListener("abort",()=>{n.abort(t?.reason??new ue("Received command to disconnect from upstream")),this.crudUpdateListener?.(),this.crudUpdateListener=void 0,this.markAsDisconnected()});;){let s=!0,r=null;try{if(t?.aborted)break;r=await this.streamingSyncIteration(n.signal,e)}catch(t){t instanceof ue?(this.logger.log({level:_.warn,message:"Sync aborted",error:t}),s=!1):this.connectionMayHaveChanged&&t.message?.indexOf("No iteration is active")>=0?(this.connectionMayHaveChanged=!1,this.logger.log({level:_.info,message:"Sync error after changed connection, retrying immediately"}),s=!1):this.logger.log({level:_.error,message:"Sync error",error:t}),this.updateJsSyncState({downloadError:t})}finally{this.checkpoints.downloadIterationEnded(),this.notifyCompletedUploads=void 0,t.aborted||(n.abort(new ue("Closing sync stream network requests before retry.")),n=new AbortController),1!=r?.immediateRestart&&(this.markAsDisconnected(),s&&await this.delayRetry(n.signal,e.retryDelayMs,!0))}}this.markAsDisconnected()}markConnectionMayHaveChanged(){this.connectionMayHaveChanged=!0,this.handleActiveStreamsChange?.()}async requireKeyFormat(t){const e=await this.options.adapter.hasMigratedSubkeys();return t&&!e?(await this.options.adapter.migrateToFixedSubkeys(),!0):e}streamingSyncIteration(t,e){return this.obtainLock({type:me.SYNC,signal:t,callback:async()=>{const n=Object.entries(e.appMetadata).filter(([t,e])=>"string"!=typeof e);if(n.length>0)throw new Error(`Invalid appMetadata provided. Only string values are allowed. Invalid values: ${n.map(([t,e])=>`${t}: ${e}`).join(", ")}`);return await this.requireKeyFormat(!0),await this.rustSyncIteration(t,e)}})}receiveSyncLines(t){const{options:e,connection:n}=t,s=this.options.remote,r=async()=>n.connectionMethod==q.HTTP?await s.fetchStream(e):await this.options.remote.socketStreamRaw({...e,fetchStrategy:n.fetchStrategy});let i,o=!1;return{async next(){if(o)return ee;if(null==i)return i=await r(),ne({command:Ut.CONNECTION_STATE,payload:"established"});{const t=await i.next();return t.done?(o=!0,ne({command:Ut.CONNECTION_STATE,payload:"end"})):ne({command:"string"==typeof t.value?Ut.PROCESS_TEXT_LINE:Ut.PROCESS_BSON_LINE,payload:t.value})}}}}async repostUnacknowledgedCheckpointRequests(t,e){let n;const s=e.checkpointMode;if("legacy"!=s)for(n="requests"==s?1e4:Math.max(s.requests.retryDelay,1e4);!t.aborted;)try{await this.checkpoints.waitForCheckpointRequestsReady(t,!1);const e=await this.options.adapter.readCheckpointRequestId("current");if(await this.delayRetry(t,n),e!=await this.options.adapter.readCheckpointRequestId("current"))continue;if(le(this.syncStatus?.core,BigInt(e)))continue;await this.checkpoints.waitForCheckpointRequestsReady(t,!1),this.logger.log({level:_.debug,message:`Retry checkpoint request ${e}`}),await this.requestCheckpointFromService(t,{client_id:await this.options.adapter.getClientId(),checkpoint_request_id:e})}catch(e){if(t.aborted)return;this.logger.log({level:_.warn,error:e,message:"Error retrying checkpoint request."}),await this.delayRetry(t,n)}}async seedCheckpointRequestState(t,e){const n=await this.requestCheckpointFromService(t,e);await this.options.adapter.readCheckpointRequestId("seed",n)}async rustSyncIteration(t,e){const n=this,s=this.options.adapter,r=this.options.remote;let i,o=!1;if(t.aborted)throw new ue("Connection request has been aborted");const a=this.options.serializedSchema;async function c(t,e){const r=await s.control(t,e??null),i=null==e||"string"==typeof e?e:"<bytes>";return n.logger.log({level:_.trace,message:`powersync_control(${t}, ${i}) -> ${r}`}),t!=Ut.STOP&&(n.connectionMayHaveChanged=!1),JSON.parse(r)}async function l(t){if("LogLine"in t){const{severity:e,line:s}=t.LogLine;switch(e){case"DEBUG":n.logger.log({level:_.debug,message:s});break;case"INFO":n.logger.log({level:_.info,message:s});break;case"WARNING":n.logger.log({level:_.warn,message:s})}}else"UpdateSyncStatus"in t?n.updateSyncStatus(t.UpdateSyncStatus.status):"FetchCredentials"in t?t.FetchCredentials.did_expire?r.invalidateCredentials():(r.invalidateCredentials(),r.fetchCredentials().then(t=>{i?.()},t=>{n.logger.log({level:_.warn,message:"Could not prefetch credentials",error:t})})):"FlushFileSystem"in t||"DidCompleteSync"in t&&n.updateJsSyncState({downloadError:void 0})}try{const s={immediateRestart:!1};let r=null;for(const i of await function(){const t={parameters:e.params,app_metadata:e.appMetadata,active_streams:n.activeStreams,include_defaults:e.includeDefaultStreams,checkpoint_mode:"legacy"===e.checkpointMode?"legacy":"requests"};return a&&(t.schema=a),c(Ut.START,JSON.stringify(t))}())if("EstablishSyncStream"in i){const s=i.EstablishSyncStream,o={path:"/sync/stream",abortSignal:t,data:s.request};if(r=se(n.receiveSyncLines({options:o,connection:e})),s.checkpoint_request){this.checkpoints.markCheckpointsReady(this.seedCheckpointRequestState(t,s.checkpoint_request)).catch(e=>{t.aborted||r?.injectError(e)})}}else{if("CloseSyncStream"in i)return s;await l(i)}if(null==r)return s;this.notifyCompletedUploads=()=>{r.inject({command:Ut.NOTIFY_CRUD_UPLOAD_COMPLETED})},this.handleActiveStreamsChange=()=>{r.inject({command:Ut.UPDATE_SUBSCRIPTIONS,payload:JSON.stringify(this.activeStreams)})},i=()=>{r.inject({command:Ut.NOTIFY_TOKEN_REFRESHED})};let u=!1;t:for(;;){const{done:t,value:e}=await r.next();if(t)break;u||e.command!=Ut.PROCESS_TEXT_LINE&&e.command!=Ut.PROCESS_BSON_LINE||(u=!0,this.triggerCrudUpload?.());const n=await c(e.command,e.payload);for(const t of n){if("EstablishSyncStream"in t)throw new Error("Received EstablishSyncStream while already connected.");if("CloseSyncStream"in t){o=t.CloseSyncStream.hide_disconnect;break t}await l(t)}}}finally{this.notifyCompletedUploads=this.handleActiveStreamsChange=void 0,i=void 0,await async function(){const t=await c(Ut.STOP);for(const e of t)ge(e)||await l(e)}()}return{immediateRestart:o}}updateSyncStatus(t,e){const n=new jt(t,{...this.syncStatus.jsState,...e});this.syncStatus.isEqual(n)||(this.syncStatus=n,this.iterateListeners(t=>t.statusChanged?.(n)))}updateJsSyncState(t){this.updateSyncStatus(this.syncStatus.core,t)}async delayRetry(t,e,n=!1){return new Promise(s=>{if(t.aborted)return void s();let r,i=null;const o=()=>{s(),r&&(clearTimeout(r),r=void 0),i&&(i.abort(),i=null),t.removeEventListener("abort",o)};t.addEventListener("abort",o,{once:!0});const a=e*(.9+.2*Math.random());r=setTimeout(o,a),n&&(i=new AbortController,this.checkpoints.waitForCheckpointWaiter(i.signal).finally(o))})}updateSubscriptions(t){this.activeStreams=t,this.handleActiveStreamsChange?.()}}class ye extends Error{static NAME="ConnectionClosedError";static MATCHES(t){return t instanceof ye||t instanceof Error&&t.name==ye.NAME}constructor(t){super(t),this.name=ye.NAME}}class we{inner;leaseMutex;constructor(t,e){this.inner=t,this.leaseMutex=e?null:new Xt}get options(){return this.inner.options}acquireMutex(t){return this.leaseMutex?this.leaseMutex.acquire(t):new Promise((e,n)=>{const s={signal:t};navigator.locks.request(`db-lock-${this.options.filename}`,s,t=>new Promise(t=>e(()=>{t()}))).catch(n)})}unsafeUseInner(){return this.inner}async acquireConnection(t){const e=await this.acquireMutex(t),n=new be(e,this.inner);try{this.inner.requireSqlite(),this.inner.isAutoCommit()||await this.inner.executeRaw("ROLLBACK")}catch(t){throw e(),t}return n}async close(){const t=await this.acquireMutex();try{await this.inner.close()}finally{t()}}}class be{returnMutex;connection;useMutex=new Xt;closed=!1;constructor(t,e){this.returnMutex=t,this.connection=e}async returnLease(){await this.useMutex.runExclusive(async()=>{this.closed||(this.closed=!0,this.returnMutex())})}async use(t){return await this.useMutex.runExclusive(async()=>{if(this.closed)throw new Error("lease token has already been closed");return await t(this.connection)})}}const Se="open-wasqlite-db";const ve="SharedWorkerGlobalScope"in globalThis;class _e extends pe{connector;constructor(t,e){super(t,e),this.connector=t}fetch({resource:t,request:e}){return fetch(t,e)}async loadWebSocketSupport(t){if(!Ce){const e=await import("./websockets-Q8W_lerF.js");Ce=new e.WebSocketSupport(t)}return Ce}getUserAgent(){let t=[super.getUserAgent(),"powersync-web"];try{t.push(...function(t){t??=navigator;const e=function(t){const e=t.userAgentData?.brands;if(null!=e){const t=[{name:"Google Chrome",value:"Chrome"},{name:"Opera",value:"Opera"},{name:"Edge",value:"Edge"},{name:"Chromium",value:"Chromium"}];for(let{name:n,value:s}of t){const t=e.find(t=>t.brand==n);if(null!=t)return`${s}/${t.version}`}}const n=t.userAgent,s=[{re:/(?:firefox|fxios)\/(\d+)/i,value:"Firefox"},{re:/(?:edg|edge|edga|edgios)\/(\d+)/i,value:"Edge"},{re:/opr\/(\d+)/i,value:"Opera"},{re:/(?:chrome|chromium|crios)\/(\d+)/i,value:"Chrome"},{re:/version\/(\d+).*safari/i,value:"Safari"}];for(let{re:t,value:e}of s){const s=t.exec(n);if(null!=s)return`${e}/${s[1]}`}return null}(t),n=function(t){if(null!=t.userAgentData?.platform)return t.userAgentData.platform.toLowerCase();const e=t.userAgent,n=[{re:/windows/i,value:"windows"},{re:/android/i,value:"android"},{re:/linux/i,value:"linux"},{re:/iphone|ipad|ipod/i,value:"ios"},{re:/macintosh|mac os x/i,value:"macos"}];for(let{re:t,value:s}of n)if(t.test(e))return s;return null}(t);return[e,n].filter(t=>null!=t)}())}catch(t){this.logger.log({level:_.warn,message:"Failed to get user agent info",error:t})}return t.join(" ")}}let Ce;class Ee extends fe{constructor(t){super(t)}get webOptions(){return this.options}async obtainLock(t){const e=`streaming-sync-${t.type}-${this.webOptions.identifier}`;return t.type==me.SYNC&&this.logger.log({level:_.debug,message:`requesting lock for ${e}`}),N().request(e,{signal:t.signal},t.callback)}}class ke{clients;inner;currentLevel=_.info;sendBroadcasts=!0;constructor(t,e){this.clients=e,this.inner=C({prefix:t})}log(t){if(this.inner.log(t),this.sendBroadcasts&&t.level>=this.currentLevel){const e=this.sanitizeRecord(t);this.iterateClients(t=>t.clientProvider.log(e))}}setLevel(t){this.inner.minLevel=t,this.currentLevel=t}async iterateClients(t){for(const e of this.clients)try{await t(e)}catch(t){console.error("Caught exception when iterating client",t)}}sanitizeRecord(t){if(!t.error)return t;let e;try{e=structuredClone(t.error)}catch(t){console.error(t),e="Could not serialize log params. Check shared worker logs for more details."}return{...t,error:e}}}class Ae extends F{options;config;#u;#h=new AbortController;#d;constructor(t,e){super(),this.options=t,this.config=e,this.#u={connection:t.connection,notifyRemoteClosed:t.remoteCanCloseUnexpectedly?new AbortController:void 0,traceQueries:!0===e.debugMode};const{port1:n,port2:s}=new MessageChannel;t.connection.setUpdateListener(y(n,[n])),this.#d=s,s.onmessage=t=>{const e={tables:t.data};this.iterateListeners(t=>{t.tablesUpdated&&t.tablesUpdated(e)})}}get name(){return this.config.dbFilename}markRemoteClosed(){this.#u.notifyRemoteClosed.abort()}async close(){this.#h.abort(),this.#d.close(),await qe(this.#u,t=>t.close(),!0),this.options.onClose?.(),this.options.source?.[n]()}readLock(t,e){return this.#p(!1,t,e)}writeLock(t,e){return this.#p(!0,t,e)}async#p(t,e,n){const s=await qe(this.#u,e=>e.requestAccess(t,n?.timeoutMs));try{return await e(new Le(this.#u,s))}finally{await qe(this.#u,t=>t.completeAccess(s))}}async refreshSchema(){}async shareConnection(){const t=this.#h,n=this.options.source;if(null==n)throw new Error("shareConnection() is only available for connections based by workers.");await new Promise((e,n)=>navigator.locks.request(`shared-connection-${this.name}-${Date.now()}-${Math.round(1e4*Math.random())}`,{signal:t.signal},async()=>{e(),t.signal.aborted||await new Promise(e=>{t.signal.addEventListener("abort",()=>{e()})})}).catch(t=>{"AbortError"==t.name?e():n(t)}));return{port:await n[e](),identifier:this.name}}getConfiguration(){return this.config}}class Le extends M{#u;#g;constructor(t,e){super(),this.#u=t,this.#g=e}async maybeTrace(t,e){if(!this.#u.traceQueries)return qe(this.#u,t);{const n=performance.now(),s=e();try{const e=await qe(this.#u,t);return performance.measure(`[SQL] ${s}`,{start:n}),e}catch(t){throw performance.measure(`[SQL] [ERROR: ${t.message}] ${s}`,{start:n}),t}}}async executeRaw(t,e){return await this.#m(t,e)}async#m(t,e){return this.maybeTrace(n=>n.execute(this.#g,t,e),()=>t)}async executeBatch(t,e=[]){const n=await this.maybeTrace(n=>n.executeBatch(this.#g,t,e),()=>`${t} (batch of ${e.length})`),s={insertId:void 0,rowsAffected:0};for(const t of n)s.insertId=t.insertId,s.rowsAffected=(s.rowsAffected??0)+t.rowsAffected;return R(s)}}async function qe(t,e,n=!1){const s=t.notifyRemoteClosed;return s?new Promise((r,i)=>{function o(){i(new ye("Remote peer closed with request in flight"))}function a(t){s.signal.removeEventListener("abort",o),t()}s.signal.aborted&&(i(new ye("Called operation on closed remote")),!n)||(s.signal.addEventListener("abort",o),e(t.connection).then(t=>a(()=>r(t))).catch(t=>a(()=>i(t))))}):e(t.connection)}var Te;!function(t){t.CLOSE_CLIENT="close-client",t.CLOSE_ACK="close-ack"}(Te||(Te={}));const xe={};class Pe extends I{ports;isInitialized;statusListener;syncParams;lastConnectOptions;portMutex;subscriptions=[];connectionManager;syncStatus;logger;database=this.generateReconnectableDatabase();sharedCloseSignal=function(t){return new Promise((e,n)=>{const s={signal:t};N().request(`tab-close-signal-${crypto.randomUUID()}`,s,t=>(e(t.name),new Promise(t=>{}))).catch(n)})}();constructor(){super(),this.ports=[],this.syncParams=null,this.lastConnectOptions=void 0,this.portMutex=new Xt,this.isInitialized=new Promise(t=>{const e=this.registerListener({initialized:()=>{t(),e?.()}})}),this.logger=new ke("shared-sync",this.ports),this.connectionManager=new Vt({createSyncImplementation:async()=>{await this.waitForReady();const t=this.generateStreamingImplementation(),e=t.registerListener({statusChanged:t=>{this.syncStatus=t;const e=t.toJSON();this.ports.forEach(t=>t.clientProvider.statusChanged(e))}});return{sync:t,onDispose:e}},logger:this.logger,defaultConnectionMethod:q.HTTP})}get isConnected(){return this.connectionManager.syncStreamImplementation?.isConnected??!1}async getLastWrappedPort(){return await this.portMutex.runExclusive(()=>{for(let t=this.ports.length-1;t>=0;t--)if(!this.ports[t].isClosing)return this.ports[t]})}async getRandomWrappedPort(){return await this.portMutex.runExclusive(()=>{const t=this.ports.filter(t=>!t.isClosing);return t[Math.floor(Math.random()*t.length)]})}async waitUntilStatusMatches(t){return this.withSyncImplementation(async e=>e.waitUntilStatusMatches(t))}async waitForReady(){return this.isInitialized}collectActiveSubscriptions(){this.logger.log({level:_.debug,message:"Collecting active stream subscriptions across tabs"});const t=new Map;for(const e of this.ports)for(const n of e.currentSubscriptions){const e=JSON.stringify(n);t.set(e,n)}this.subscriptions=[...t.values()],this.logger.log({level:_.debug,message:`Collected stream subscriptions, ${JSON.stringify(this.subscriptions)}`}),this.connectionManager.syncStreamImplementation?.updateSubscriptions(this.subscriptions)}updateSubscriptions(t,e){t.currentSubscriptions=e,this.collectActiveSubscriptions()}setLogLevel(t){this.logger.setLevel(t)}async setParams(t){await this.portMutex.runExclusive(async()=>{this.collectActiveSubscriptions()}),this.syncParams||(this.syncParams=t,this.logger.sendBroadcasts=t.enableBroadcastLogs,await this.database.readLock(async()=>{}),self.onerror=t=>{this.logger.log({level:_.error,message:"Uncaught exception in PowerSync shared sync worker",error:t})},this.iterateListeners(t=>t.initialized?.()))}async dispose(){return await this.waitForReady(),this.statusListener?.(),this.connectionManager.close()}async connect(t,e){return this.lastConnectOptions=t,this.connectionManager.connect(xe,t??{},e)}async disconnect(){return this.connectionManager.disconnect()}async addPort(t){return await this.portMutex.runExclusive(()=>{const e={port:t,clientProvider:l(t),currentSubscriptions:[],closeListeners:[],isClosing:!1};this.ports.push(e);const n=this.syncStatus;return n&&e.clientProvider.statusChanged(n.toJSON()),e})}async removePort(t){return t.isClosing=!0,await this.portMutex.runExclusive(async()=>{const e=this.ports.findIndex(e=>e==t);if(e<0)return this.logger.log({level:_.warn,message:`Could not remove port ${t} since it is not present in active ports.`}),()=>{};const s=this.ports[e];this.ports.splice(e,1);for(const t of s.closeListeners)await t();return this.collectActiveSubscriptions(),()=>s.clientProvider[n]()})}triggerCrudUpload(){this.withSyncImplementation(async t=>{t.triggerCrudUpload()})}requestCheckpoint(){return this.withSyncImplementation(t=>t.requestCheckpoint())}async withSyncImplementation(t){if(await this.waitForReady(),this.connectionManager.syncStreamImplementation)return t(this.connectionManager.syncStreamImplementation);return t(await new Promise(t=>{const e=this.connectionManager.registerListener({syncStreamCreated:n=>{t(n),e?.()}})}))}generateStreamingImplementation(){const t=this.syncParams;return new Ee({adapter:new oe(this.database,this.logger),remote:new _e({invalidateCredentials:async()=>{const t=await this.getLastWrappedPort();if(!t)throw new Error("No client port found to invalidate credentials");try{this.logger.log({level:_.info,message:"calling the last port client provider to invalidate credentials"}),t.clientProvider.invalidateCredentials()}catch(t){this.logger.log({level:_.error,message:"error invalidating credentials",error:t})}},fetchCredentials:()=>this.#f(t=>(this.logger.log({level:_.info,message:"calling the last port client provider for credentials"}),t.clientProvider.fetchCredentials()),"fetchCredentials")},this.logger),uploadCrud:()=>this.#f(t=>t.clientProvider.uploadCrud(),"uploadCrud"),postCheckpointRequest:(t,e)=>this.#f(n=>n.clientProvider.postCheckpointRequest(t,e),"postCheckpointRequest"),...t.streamOptions,subscriptions:this.subscriptions,logger:this.logger})}async#f(t,e){const n=await this.getLastWrappedPort();if(!n)throw new Error(`No client port found for ${e}`);return new Promise((s,r)=>{function i(){r(new Error(`Tab closed while handling ${e}`))}n.closeListeners.push(i),t(n).then(s,r).finally(()=>{n.closeListeners.splice(n.closeListeners.indexOf(i),1)})})}async openInternalDB(t){const e=await this.getRandomWrappedPort();if(!e)throw new Error("Could not open DB connection since no client is connected.");const n=setTimeout(()=>{s.abort()},1e4),s=new AbortController,r=()=>{s.abort()},i=()=>{const t=e.closeListeners.indexOf(r);t>=0&&e.closeListeners.splice(t,1)};e.closeListeners.push(r);const o=l(await Ie({action:()=>e.clientProvider.getDBWorkerPort(),signal:s.signal,cleanupOnAbort:t=>{t.close()}}).catch(t=>{throw i(),t})),a=this.syncParams.dbParams.dbFilename,c=await this.sharedCloseSignal,u=await Ie({action:async()=>{const t=await o.connectToExisting({identifier:a,lockName:c});return new Ae({connection:t,source:o,remoteCanCloseUnexpectedly:!0},this.syncParams.dbParams)},signal:s.signal,cleanupOnAbort:t=>{t.close()}}).finally(()=>{i()});return clearTimeout(n),e.closeListeners.push(async()=>{this.logger.log({level:_.info,message:"Aborting open connection because associated tab closed."}),t(u),u.markRemoteClosed(),u.close().catch(t=>this.logger.log({level:_.warn,message:"error closing database connection",error:t}))}),u}generateReconnectableDatabase(){const t=this.syncParams,e=this;return new class extends F{connectionState=null;get name(){return t?.dbParams.dbFilename}async connect(){if(null==this.connectionState){const t=this.handleClientClosed.bind(this);this.connectionState=(async()=>{try{const n=await e.openInternalDB(t);return n.registerListener({tablesUpdated:t=>{this.iterateListeners(e=>e.tablesUpdated?.(t))}}),this.connectionState=n,n}catch(t){throw this.connectionState=null,t}})()}return await this.connectionState}async close(){null!=this.connectionState&&await(await this.connectionState).close()}handleClientClosed(t){if(t===this.connectionState){this.connectionState=null;const t=e.connectionManager.syncStreamImplementation;t?.triggerCrudUpload(),t?.markConnectionMayHaveChanged()}}async readLock(t,e){return(await this.connect()).readLock(t,e)}async writeLock(t,e){return(await this.connect()).writeLock(t,e)}async refreshSchema(){}}}}function Ie(t){const{action:e,signal:n,cleanupOnAbort:s}=t;return new Promise((t,r)=>{function i(){n.removeEventListener("abort",i),r(new ue("Operation aborted by abort controller"))}function o(t){n.removeEventListener("abort",i),t()}n.aborted?r(new ue("Operation aborted by abort controller")):(n.addEventListener("abort",i,{once:!0}),e().then(e=>{if(n.aborted)return o(()=>s?.(e));o(()=>t(e))}).catch(t=>o(()=>r(t))))})}class Oe{sync;port;resolvedPort=null;resolvedPortPromise=null;constructor(t,e){this.sync=t,this.port=e,a(this,this.port),this.port.addEventListener("message",async t=>{const e=t.data;e?.event==Te.CLOSE_CLIENT&&await this.removePort()})}async removePort(){if(this.resolvedPort){const t=this.resolvedPort;this.resolvedPort=null;const e=await this.sync.removePort(t);this.resolvedPort=null,this.port.postMessage({event:Te.CLOSE_ACK,data:{}}),e?.()}}async addLockBasedCloseSignal(t){this.resolvedPort=await this.sync.addPort(this.port),N().request(t,async()=>{await this.removePort()})}setLogLevel(t){this.sync.setLogLevel(t)}triggerCrudUpload(){return this.sync.triggerCrudUpload()}setParams(t,e){return this.resolvedPort.currentSubscriptions=e,this.sync.setParams(t)}connect(t,e){return this.sync.connect(t,e)}updateSubscriptions(t){this.resolvedPort&&this.sync.updateSubscriptions(this.resolvedPort,t)}requestCheckpoint(){return this.sync.requestCheckpoint()}disconnect(){return this.sync.disconnect()}}const Re=new class{logger;#y=new Map;#w=new Xt;constructor(t){this.logger=t}async handleConnection({logLevel:t,database:e,lockName:n}){const s={log:e=>{e.level>=t&&this.logger.log(e)}};return w(await this.openConnectionLocally(s,e,n))}async connectToExisting(t,e){return N().request(Se,async()=>{const n=this.#y.get(t);if(null==n)throw new Error(`connectToExisting(${t}) failed because the worker doesn't own a database with that name.`);return w(await n.connect(e))})}async openConnectionLocally(t,e,n){let s;for(let n=0;n<2;n++)try{s=await this.#b(t,e)}catch(t){this.logger.log({level:_.warn,message:`Attempt ${n+1} of 3 to open database failed, retrying in 1 second...`,error:t}),await new Promise(t=>setTimeout(t,1e3))}return s??=await this.#b(t,e),s.connect(n)}async#b(t,e){const{filename:n,readonly:s,vfs:r}=e,i=!(ve||s||r==xt.InMemoryVfs),o=this.#y;async function a(){let s=o.get(n);if(null==s){const r=new Mt(e),a=new we(r,i),c=await a.acquireMutex();try{await r.init()}catch(t){throw c(),await r.close(),t}c();s=new D({inner:a,logger:t,onClose:()=>o.delete(n)}),o.set(n,s)}return s}return i?N().request(Se,a):this.#w.runExclusive(a)}closeAll(){const t=[...this.#y.values()];return Promise.all(t.map(t=>{t.forceClose()}))}}(C({prefix:"db-worker",minLevel:_.trace})),Me={connect:t=>Re.handleConnection(t),connectToExisting:({identifier:t,lockName:e})=>Re.connectToExisting(t,e)};if(ve){const t=new Pe;self.onconnect=e=>{e.ports[0].onmessage=e=>{const{service:n,port:s}=e.data;"database"===n?a(Me,s):"sync"===n&&new Oe(t,s)}}}else a(Me);export{St as A,bt as B,B as C,j as D,yt as E,ft as F,lt as G,ut as H,ht as I,wt as J,ot as K,$ as S,X as a,nt as b,J as c,z as d,dt as e,W as f,gt as g,mt as h,pt as i,rt as j,H as k,K as l,V as m,it as n,G as o,tt as p,Z as q,at as r,ct as s,st as t,et as u,Y as v,Q as w,Ct as x,_t as y,vt as z};
7
7
  //# sourceMappingURL=worker.js.map