@powersync/web 2.4.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/index.react_native_web.js +142 -25
  2. package/dist/index.react_native_web.js.map +1 -1
  3. package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js +2 -0
  4. package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js.map +1 -0
  5. package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -1
  6. package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js +2 -0
  7. package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js.map +1 -0
  8. package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -1
  9. package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js +2 -0
  10. package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js.map +1 -0
  11. package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js +2 -0
  12. package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js.map +1 -0
  13. package/dist/worker/assets/mc-wa-sqlite-Cq3AePIW.wasm +0 -0
  14. package/dist/worker/assets/{mc-wa-sqlite-async-DdlQmAUV.wasm → mc-wa-sqlite-async-aRcIGeKj.wasm} +0 -0
  15. package/dist/worker/assets/wa-sqlite-CePoIZt_.wasm +0 -0
  16. package/dist/worker/assets/wa-sqlite-async-B3FiUnt1.wasm +0 -0
  17. package/dist/worker/{mc-wa-sqlite-PubB6u8c.js → mc-wa-sqlite-DRR2R_uj.js} +2 -2
  18. package/dist/worker/mc-wa-sqlite-DRR2R_uj.js.map +1 -0
  19. package/dist/worker/{mc-wa-sqlite-async-DJG_ANKO.js → mc-wa-sqlite-async-C40l6kIz.js} +2 -2
  20. package/dist/worker/mc-wa-sqlite-async-C40l6kIz.js.map +1 -0
  21. package/dist/worker/{wa-sqlite-D1_4mGs8.js → wa-sqlite-_a9CU4MM.js} +2 -2
  22. package/dist/worker/wa-sqlite-_a9CU4MM.js.map +1 -0
  23. package/dist/worker/wa-sqlite-async-Da0d0GJg.js +2 -0
  24. package/dist/worker/wa-sqlite-async-Da0d0GJg.js.map +1 -0
  25. package/dist/worker/{websockets-Q8W_lerF.js → websockets-Dx9ExO-W.js} +2 -2
  26. package/dist/worker/{websockets-Q8W_lerF.js.map → websockets-Dx9ExO-W.js.map} +1 -1
  27. package/dist/worker/worker.js +1 -1
  28. package/dist/worker/worker.js.map +1 -1
  29. package/lib/db/PowerSyncDatabase.d.ts +4 -3
  30. package/lib/db/PowerSyncDatabase.js +9 -2
  31. package/lib/db/PowerSyncDatabase.js.map +1 -1
  32. package/lib/db/adapters/options.d.ts +30 -0
  33. package/lib/db/adapters/options.js.map +1 -1
  34. package/lib/db/adapters/resolveAndValidateOptions.js +6 -1
  35. package/lib/db/adapters/resolveAndValidateOptions.js.map +1 -1
  36. package/lib/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +5 -0
  37. package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js +7 -2
  38. package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
  39. package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +4 -2
  40. package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -1
  41. package/lib/db/adapters/wa-sqlite/vfs.d.ts +24 -1
  42. package/lib/db/adapters/wa-sqlite/vfs.js +33 -4
  43. package/lib/db/adapters/wa-sqlite/vfs.js.map +1 -1
  44. package/lib/db/sync/SharedWebStreamingSyncImplementation.d.ts +2 -0
  45. package/lib/db/sync/SharedWebStreamingSyncImplementation.js +43 -12
  46. package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
  47. package/lib/db/sync/WebRemote.d.ts +2 -3
  48. package/lib/db/sync/WebRemote.js +0 -2
  49. package/lib/db/sync/WebRemote.js.map +1 -1
  50. package/lib/db/sync/WebStreamingSyncImplementation.d.ts +8 -1
  51. package/lib/db/sync/WebStreamingSyncImplementation.js +14 -0
  52. package/lib/db/sync/WebStreamingSyncImplementation.js.map +1 -1
  53. package/lib/devtools/index.d.ts +7 -0
  54. package/lib/devtools/index.js +8 -0
  55. package/lib/devtools/index.js.map +1 -0
  56. package/lib/devtools/registry.d.ts +12 -0
  57. package/lib/devtools/registry.js +42 -0
  58. package/lib/devtools/registry.js.map +1 -0
  59. package/lib/worker/sync/BroadcastLogger.d.ts +1 -4
  60. package/lib/worker/sync/BroadcastLogger.js +14 -15
  61. package/lib/worker/sync/BroadcastLogger.js.map +1 -1
  62. package/lib/worker/sync/SharedSyncImplementation.d.ts +9 -2
  63. package/lib/worker/sync/SharedSyncImplementation.js +66 -37
  64. package/lib/worker/sync/SharedSyncImplementation.js.map +1 -1
  65. package/lib/worker/sync/WorkerClient.d.ts +3 -3
  66. package/lib/worker/sync/WorkerClient.js +3 -3
  67. package/lib/worker/sync/WorkerClient.js.map +1 -1
  68. package/package.json +12 -8
  69. package/src/db/PowerSyncDatabase.ts +12 -5
  70. package/src/db/adapters/options.ts +32 -0
  71. package/src/db/adapters/resolveAndValidateOptions.ts +9 -1
  72. package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +12 -2
  73. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +6 -2
  74. package/src/db/adapters/wa-sqlite/vfs.ts +51 -4
  75. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +54 -17
  76. package/src/db/sync/WebRemote.ts +2 -5
  77. package/src/db/sync/WebStreamingSyncImplementation.ts +18 -0
  78. package/src/devtools/index.ts +7 -0
  79. package/src/devtools/registry.ts +53 -0
  80. package/src/worker/sync/BroadcastLogger.ts +15 -15
  81. package/src/worker/sync/SharedSyncImplementation.ts +89 -48
  82. package/src/worker/sync/WorkerClient.ts +4 -3
  83. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js +0 -2
  84. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +0 -1
  85. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js +0 -2
  86. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +0 -1
  87. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js +0 -2
  88. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +0 -1
  89. package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js +0 -2
  90. package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js.map +0 -1
  91. package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.wasm +0 -0
  92. package/dist/worker/assets/wa-sqlite-CIxTmRHQ.wasm +0 -0
  93. package/dist/worker/assets/wa-sqlite-async-zc68fxQq.wasm +0 -0
  94. package/dist/worker/mc-wa-sqlite-PubB6u8c.js.map +0 -1
  95. package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +0 -1
  96. package/dist/worker/wa-sqlite-D1_4mGs8.js.map +0 -1
  97. package/dist/worker/wa-sqlite-async-BxkwNY-2.js +0 -2
  98. package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +0 -1
@@ -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=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-BW9pqSNn.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 n="sqlite3_open_v2",s=t.cwrap(n,...Tt("snnn:n"),{async:qt});return async function(i,a,c){a=a||6,c=o(c);try{const o=await g(()=>s(i,r[0],a,c)),u=t.getValue(r[0],"*");if(0!==o){const s=u?t.ccall("sqlite3_errmsg","string",["number"],[u]):n,r=new Lt(s,o);if(u){l.add(u);try{await e.close(u)}catch{}finally{l.delete(u)}}throw r}return l.add(u),t.ccall("RegisterExtensionFunctions","void",["number"],[u]),u}finally{t._sqlite3_free(c)}}}(),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)=>{if(t.aborted)return void n(!1);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(t){return this.credentials?this.credentials:this.prefetchCredentials(t)}async prefetchCredentials(t){return this.credentials=await this.fetchCredentials(t),this.credentials}async fetchCredentials(t){const e=await this.connector.fetchCredentials(t);if(e?.endpoint.match(he))throw new Error(`A trailing forward slash "/" was found in the fetchCredentials endpoint: "${e.endpoint}". Remove the trailing forward slash "/" to fix this error.`);return e}invalidateCredentials(){this.credentials=null,this.connector.invalidateCredentials?.()}getUserAgent(){return"powersync-js/1.3.1"}async buildRequest(t,e){const n=await this.getCredentials(e);if(null!=n&&(null==n.endpoint||""==n.endpoint))throw new Error("PowerSync endpoint not configured");if(null==n?.token||""==n?.token){const t=new Error("Not signed in");throw t.status=401,t}const s=this.getUserAgent();return{url:n.endpoint+t,headers:{"content-type":"application/json",Authorization:`Token ${n.token}`,"x-user-agent":s},userAgent:s,path:t}}async fetchAndDecodeJson({path:t,method:e="GET",headers:n,body:s,signal:r}){const i=await this.buildRequest(t,r),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,t.abortSignal);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,s);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){if(!await this.checkpoints.waitForCheckpointRequestsReady(t))throw t.reason;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 n=await this.options.postCheckpointRequest(e.client_id,e.checkpoint_request_id,t);if(null!=n)return n}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(t),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;this.abortController=e;const n=e.signal;return this.streamingSyncPromise=Promise.all([this.crudUploadLoop(n,t).catch(t=>{n.reason!==t&&this.logger.log({level:_.error,message:"Error in crud upload loop",error:t})}),this.streamingSync(n,t),this.repostUnacknowledgedCheckpointRequests(n,t)]).finally(()=>{this.checkpoints.disconnected()}),new Promise(t=>{let e=!1,s=!1;const r=()=>{s||(s=!0,i(),n.removeEventListener("abort",r),t())},i=this.registerListener({statusChanged:t=>{if(t.connecting&&(e=!0),null!=t.downloadError)this.logger.log({level:_.warn,message:"Initial connect attempt did not successfully connect to server"});else if(!e||t.connecting)return;r()}});n.addEventListener("abort",r,{once:!0})})}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(e){const n=t.aborted;n?(this.logger.log({level:_.warn,message:"Sync aborted",error:e}),s=!1):this.connectionMayHaveChanged&&e.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:e}),n||this.updateJsSyncState({downloadError:e})}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{if(!await this.checkpoints.waitForCheckpointRequestsReady(t,!1))return;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;if(!await this.checkpoints.waitForCheckpointRequestsReady(t,!1))return;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(),this.syncStatus&&=new jt(this.syncStatus.core,{})}}},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:t=>this.#f(t=>(this.logger.log({level:_.info,message:"calling the last port client provider for credentials"}),t.clientProvider.fetchCredentials()),"fetchCredentials",t)},this.logger),uploadCrud:t=>this.#f(t=>t.clientProvider.uploadCrud(),"uploadCrud",t),postCheckpointRequest:(t,e,n)=>this.#f(n=>n.clientProvider.postCheckpointRequest(t,e),"postCheckpointRequest",n),...t.streamOptions,subscriptions:this.subscriptions,logger:this.logger})}async#f(t,e,n){const s=async()=>{const n=await this.getLastWrappedPort();if(!n)throw new Error(`No client port found for ${e}`);return await new Promise((s,r)=>{const i=()=>{r(new Error(`Tab closed while handling ${e}`))};n.closeListeners.push(i),t(n).then(s,r).finally(()=>{const t=n.closeListeners.indexOf(i);t>=0&&n.closeListeners.splice(t,1)})})};return n?Ie({signal:n,action:s}):s()}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,r=()=>n.reason instanceof Error?n.reason:new ue("Operation aborted by abort controller");return new Promise((t,i)=>{function o(){n.removeEventListener("abort",o),i(r())}function a(t){n.removeEventListener("abort",o),t()}n.aborted?i(r()):(n.addEventListener("abort",o,{once:!0}),e().then(e=>{if(n.aborted)return a(()=>s?.(e));a(()=>t(e))}).catch(t=>a(()=>i(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};
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]=f(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]=f(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 f(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 m=new WeakMap;function y(t,e){return m.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},m.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 C={trace:10,debug:20,info:30,warn:40,error:50};function _(t){const{prefix:e="PowerSync",minLevel:n=C.info}=t??{};return{prefix:e,minLevel:n,log({level:t,message:n,error:s}){if(t<this.minLevel)return;let r=console.log;t>=C.error?r=console.error:t>=C.warn?r=console.warn:t>=C.info&&(r=console.info);const i=`[${e}]: ${n}`;s?r(i,s):r(i)}}}var E,k,A,T,L,q,P,x;!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"}(T||(T={})),function(t){t.HTTP="http",t.WEB_SOCKET="web-socket"}(L||(L={})),function(t){t.Buffered="buffered",t.Sequential="sequential"}(q||(q={}));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 U extends I{readTransaction(t,e){return this.readLock(e=>F.runWith(e,t),e)}writeTransaction(t,e){return this.writeLock(e=>F.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 F 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 F(t);await t.execute("BEGIN IMMEDIATE");try{const t=await e(n);return await n.commit(),t}catch(e){n.finalized=!0;try{await t.execute("ROLLBACK")}catch(t){}throw e}}}!function(t){t.INSERT="INSERT",t.UPDATE="UPDATE",t.DELETE="DELETE"}(P||(P={})),function(t){t.ON_DATA="onData",t.ON_ERROR="onError",t.ON_STATE_CHANGE="onStateChange",t.SETTINGS_WILL_UPDATE="settingsWillUpdate",t.CLOSED="closed"}(x||(x={}));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:C.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:C.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:C.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,j=5,z=10,W=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,ft=4,mt=2048,yt=16384,wt=11,bt=14,St=21,vt=31,Ct=32,_t=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 Tt extends Error{constructor(t,e){super(t),this.code=e}}const Lt=!0;function qt(t){const e={};t.retryOps=[],t.pendingOps=[];const n=t._getSqliteFree(),s=t._malloc(8),r=[s,s+4],i=new TextEncoder,o=new TextDecoder("utf-8",{ignoreBOM:!0});function a(e){if("string"!=typeof e)return[0,-1];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,n.byteLength]}function c(e,n){return e?o.decode(t.HEAPU8.subarray(e,e+n)):null}function l(t,e){return BigInt(e)<<32n|0xffffffffn&BigInt(t)}const u=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?l(n,s):4294967296*s+(2147483647&n)-(2147483648&n)}}(),h=new Set;function d(t){if(!h.has(t))throw new Tt("not a database",21)}const p=new Map;function g(t){if(!p.has(t))throw new Tt("not a statement",21)}function f(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 m(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){g(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(g(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,...Pt("nnnnn:n"));return function(r,i,o){g(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 f(e,l,p.get(r))}}(),e.bind_parameter_count=function(){const e=t.cwrap("sqlite3_bind_parameter_count",...Pt("n:n"));return function(t){g(t);return e(t)}}(),e.bind_double=function(){const e="sqlite3_bind_double",n=t.cwrap(e,...Pt("nnn:n"));return function(t,s,r){g(t);const i=n(t,s,r);return f(e,i,p.get(t))}}(),e.bind_int=function(){const e="sqlite3_bind_int",n=t.cwrap(e,...Pt("nnn:n"));return function(t,s,r){if(g(t),r>2147483647||r<-2147483648)return 25;const i=n(t,s,r);return f(e,i,p.get(t))}}(),e.bind_int64=function(){const e="sqlite3_bind_int64",n=t.cwrap(e,...Pt("nnnn:n"));return function(t,s,r){if(g(t),r>Et||r<kt)return 25;const i=r>>32n,o=n(t,s,Number(0xffffffffn&r),Number(i));return f(e,o,p.get(t))}}(),e.bind_null=function(){const e="sqlite3_bind_null",n=t.cwrap(e,...Pt("nn:n"));return function(t,s){g(t);const r=n(t,s);return f(e,r,p.get(t))}}(),e.bind_parameter_name=function(){const e=t.cwrap("sqlite3_bind_parameter_name",...Pt("n:s"));return function(t,n){g(t);return e(t,n)}}(),e.bind_text=function(){const e="sqlite3_bind_text",s=t.cwrap(e,...Pt("nnnnn:n"));return function(t,r,i){g(t);const[o,c]=a(i),l=s(t,r,o,c,n);return f(e,l,p.get(t))}}(),e.changes=function(){const e=t.cwrap("sqlite3_changes",...Pt("n:n"));return function(t){d(t);return e(t)}}(),e.clear_bindings=function(){const e="sqlite3_clear_bindings",n=t.cwrap(e,...Pt("n:n"));return function(t){g(t);const s=n(t);return f(e,s,p.get(t))}}(),e.last_insert_id=function(){const e=t.cwrap("sqlite3_last_insert_rowid",...Pt("n:n"));return function(t){d(t);return e(t)}}(),e.close=function(){const e="sqlite3_close",n=t.cwrap(e,...Pt("n:n"),{async:Lt});return async function(t){d(t);const s=await n(t);return h.delete(t),f(e,s,t)}}(),e.column=function(n,s){g(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 u(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",...Pt("nn:n"));return function(s,r){g(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",...Pt("nn:n"));return function(t,n){g(t);return e(t,n)}}(),e.column_count=function(){const e=t.cwrap("sqlite3_column_count",...Pt("n:n"));return function(t){g(t);return e(t)}}(),e.column_double=function(){const e=t.cwrap("sqlite3_column_double",...Pt("nn:n"));return function(t,n){g(t);return e(t,n)}}(),e.column_int=function(){const e=t.cwrap("sqlite3_column_int64",...Pt("nn:n"));return function(t,n){g(t);return e(t,n)}}(),e.column_int64=function(){const e=t.cwrap("sqlite3_column_int64",...Pt("nn:n"));return function(n,s){g(n);return l(e(n,s),t.getTempRet0())}}(),e.column_name=function(){const e=t.cwrap("sqlite3_column_name",...Pt("nn:s"));return function(t,n){g(t);return 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 n=t.cwrap("sqlite3_column_text",...Pt("nn:n"));return function(t,s){g(t);return c(n(t,s),e.column_bytes(t,s))}}(),e.column_type=function(){const e=t.cwrap("sqlite3_column_type",...Pt("nn:n"));return function(t,n){g(t);return 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))}d(e);return f("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",...Pt("n:n"));return function(t){g(t);return 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",...Pt("n:n"),{async:Lt});return async function(t){const n=await e(t);return p.delete(t),n}}(),e.get_autocommit=function(){const e=t.cwrap("sqlite3_get_autocommit",...Pt("n:n"));return function(t){return e(t)}}(),e.libversion=function(){const e=t.cwrap("sqlite3_libversion",...Pt(":s"));return function(){return e()}}(),e.libversion_number=function(){const e=t.cwrap("sqlite3_libversion_number",...Pt(":n"));return function(){return e()}}(),e.limit=function(){const e=t.cwrap("sqlite3_limit",...Pt("nnn:n"));return function(t,n,s){return e(t,n,s)}}(),e.open_v2=function(){const n="sqlite3_open_v2",s=t.cwrap(n,...Pt("snnn:n"),{async:Lt});return async function(i,o,c){o=o||6,c=a(c)[0];try{const a=await m(()=>s(i,r[0],o,c)),l=t.getValue(r[0],"*");if(0!==a){const s=l?t.ccall("sqlite3_errmsg","string",["number"],[l]):n,r=new Tt(s,a);if(l){h.add(l);try{await e.close(l)}catch{}finally{h.delete(l)}}throw r}return h.add(l),t.ccall("RegisterExtensionFunctions","void",["number"],[l]),l}finally{t._sqlite3_free(c)}}}(),e.progress_handler=function(e,n,s,r){d(e),t.progress_handler(e,n,s,r)},e.reset=function(){const e="sqlite3_reset",n=t.cwrap(e,...Pt("n:n"),{async:Lt});return async function(t){g(t);const s=await n(t);return f(e,s,p.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",...Pt("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",...Pt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int=function(){const e=t.cwrap("sqlite3_result_int",...Pt("nn:n"));return function(t,n){e(t,n)}}(),e.result_int64=function(){const e=t.cwrap("sqlite3_result_int64",...Pt("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",...Pt("n:n"));return function(t){e(t)}}(),e.result_text=function(){const e=t.cwrap("sqlite3_result_text",...Pt("nnnn:n"));return function(t,s){const[r,i]=a(s);e(t,r,i,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)]}d(e);var i;return f("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",...Pt("n:s"));return function(t){g(t);return 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),h=u+c.byteLength+1;a.push(()=>t._sqlite3_free(u)),t.HEAPU8.set(c,u),t.HEAPU8[h-1]=0;const d=u+l-8,g=u+l-4;let y;function w(){y&&!r.unscoped&&e.finalize(y),y=0}a.push(w),t.setValue(g,u,"*");do{w();const b=t.getValue(g,"*"),S=await m(()=>o(n,b,h-g,r.flags||0,d,g));0!==S&&f("sqlite3_prepare_v3",S,n),y=t.getValue(d,"*"),y&&(p.set(y,n),yield y)}while(y)}finally{for(;a.length;)a.pop()()}}()},e.step=function(){const e="sqlite3_step",n=t.cwrap(e,...Pt("n:n"),{async:Lt});return async function(t){g(t);const s=await m(()=>n(t));return f(e,s,p.get(t),[100,101])}}(),e.commit_hook=function(e,n){d(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),l(r,i)]}var r;d(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 u(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",...Pt("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",...Pt("n:n"));return function(t){return e(t)}}(),e.value_double=function(){const e=t.cwrap("sqlite3_value_double",...Pt("n:n"));return function(t){return e(t)}}(),e.value_int=function(){const e=t.cwrap("sqlite3_value_int64",...Pt("n:n"));return function(t){return e(t)}}(),e.value_int64=function(){const e=t.cwrap("sqlite3_value_int64",...Pt("n:n"));return function(n){return l(e(n),t.getTempRet0())}}(),e.value_text=function(){const n=t.cwrap("sqlite3_value_text",...Pt("n:n"));return function(t){return c(n(t),e.value_bytes(t))}}(),e.value_type=function(){const e=t.cwrap("sqlite3_value_type",...Pt("n:n"));return function(t){return e(t)}}(),e.vfs_register=function(e,n){return f("sqlite3_vfs_register",t.vfs_register(e,n))},e}function Pt(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,It;function Ot(t,e=navigator.storageBuckets){if(null==t)return{};if(null==e)throw new Error("The 'storageBucket' option needs the Storage Buckets API (navigator.storageBuckets), which this browser does not have. Check for it before setting the option.");return{getRoot:()=>e.open(t).then(t=>t.getDirectory()),prefix:`${t}:`}}async function Rt(t){if(t){const{default:t}=await import("./mc-wa-sqlite-async-C40l6kIz.js");return t()}{const{default:t}=await import("./wa-sqlite-async-Da0d0GJg.js");return t()}}async function Mt(t){if(t){const{default:t}=await import("./mc-wa-sqlite-DRR2R_uj.js");return t()}{const{default:t}=await import("./wa-sqlite-_a9CU4MM.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"}(It||(It={}));class Ut{#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 Ft{options;_sqliteAPI=null;sqlite3_stmt_isexplain;db=0;statementCache;constructor(t){this.options=t,this.statementCache=t.preparedStatementsCache>0?new Ut(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,storageBucket:s}){let r,i=Mt;switch(t){case xt.IDBBatchAtomicVFS:{i=Rt;const{IDBBatchAtomicVFS:t}=await import("./IDBBatchAtomicVFS-CDb4d4wN.js");r=n=>t.create(e,n,{lockPolicy:"exclusive"});break}case xt.AccessHandlePoolVFS:{const{AccessHandlePoolVFS:t}=await import("./AccessHandlePoolVFS-Do8lc5Ck.js");r=n=>t.create(e,n,Ot(s));break}case xt.OPFSCoopSyncVFS:{const{OPFSCoopSyncVFS:t}=await import("./OPFSCoopSyncVFS-CDNBPKfy.js");r=n=>t.create(e,n,Ot(s));break}case xt.OPFSWriteAheadVFS:{const{OPFSWriteAheadVFS:t}=await import("./OPFSWriteAheadVFS-V9yBrLWl.js");r=n=>t.create(e,n,Ot(s));break}case xt.InMemoryVfs:{const{MemoryVFS:t}=await import("./MemoryVFS-DVJL5F8j.js");r=n=>t.create(e,n);break}}const o=await i(n);return{module:o,vfs:await r(o)}}(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=qt(t);n.vfs_register(e,!0);for(const e of["powersync_init_static",...this.options.additionalInitializationFunctions??[]]){const n=t.ccall(e,"int",[]);if(0!==n)throw new Error(`SQLite extension initializer ${e} failed with code ${n}`)}if(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 Dt,Nt;async function $t(t,e,n){const{rawRows:s}=await t.executeRaw("SELECT CAST(powersync_control(?, ?) AS TEXT)",[e,n]);return s[0][0]}function Bt(t,e=null){return $t(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"}(Dt||(Dt={})),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"}(Nt||(Nt={}));const jt="__powersyncError";function zt(t){return"object"==typeof t&&null!==t&&"string"==typeof t.name&&"string"==typeof t.message}function Wt(t,e,n){if(function(t){return"object"==typeof t&&null!==t&&!0===t[jt]}(t))return t;if(!zt(t))return function(t){const e="string"==typeof t||"number"==typeof t||"boolean"==typeof t;return{[jt]:!0,name:"string"==typeof t?"String":"Error",message:e?String(t):"Non-Error rejection",state:"serialized"}}(t);const s=t,r={[jt]:!0,name:s.name||"Error",message:s.message,state:"serialized"},i=s.stack;return"string"==typeof i&&(r.stack=i),"string"!=typeof s.code&&"number"!=typeof s.code||(r.code=s.code),"number"==typeof s.status&&(r.status=s.status),void 0!==s.cause&&(r.cause=function(t,e,n){return zt(t)?e<=0?(n.lossy=!0,"[Max depth reached]"):Wt(t,e,n):null===t||"string"==typeof t||"number"==typeof t||"boolean"==typeof t?String(t):(n.lossy=!0,`[Unserializable ${typeof t}]`)}(s.cause,e-1,n)),n.lossy&&"missing"!==r.state&&(r.state="partial"),r}function Ht(t){try{return null==t?(e=t,{[jt]:!0,name:"PowerSyncMissingRejectionReason",message:`No rejection reason was provided (${e}).`,state:"missing"}):Wt(t,5,{lossy:!1})}catch{return{[jt]:!0,name:"Error",message:"Unable to serialize rejection reason",state:"partial"}}var e}const Vt=2147483647,Jt="9223372036854775807";class Gt{internal;totalOperations;downloadedOperations;downloadedFraction;constructor(t){this.internal=t;const e=this.untilPriority(Vt);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 Kt{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(Vt)?.lastSyncedAt}get hasSynced(){return this.statusForPriority(Vt)?.hasSynced}get syncStreams(){return this.core?.streams.map(t=>new Xt(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 Xt(this,n)}get priorityStatusEntries(){return this.core?.priority_status.map(Yt)}get downloadProgress(){const t=this.core?.downloading;return null==t?null:new Gt(t)}statusForPriority(t){const e=this.core?.priority_status;if(null!=e){for(const n of e)if(n.priority>=t)return Yt(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 Ht(t)}}function Qt(t){return null==t?void 0:new Date(t/1e3)}function Yt(t){return{priority:t.priority,hasSynced:t.has_synced??void 0,lastSyncedAt:Qt(t.last_synced_at)}}class Xt{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:Qt(e.expires_at)??null,hasSynced:null!=e.last_synced_at,lastSyncedAt:Qt(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 Zt extends I{options;connectingPromise;syncStreamInitPromise;disconnectingPromise;pendingConnectionOptions;currentOptions;currentConnector;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.currentConnector=null,this.syncDisposer=null}get connector(){return this.currentConnector??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??q.Buffered,params:t.params??{},includeDefaultStreams:t.includeDefaultStreams??!0,retryDelayMs:t.retryDelayMs??5e3,crudUploadThrottleMs:t.crudUploadThrottleMs??1e3,checkpointMode:t.checkpointMode??"legacy",connectTimeoutMs:t.connectTimeoutMs??3e4,diagnostics:t.diagnostics??!1}}(e,this.options.defaultConnectionMethod),i={connector:t,options:r,schema:n};this.pendingConnectionOptions=i,t.postCheckpointRequest&&"legacy"==r.checkpointMode&&this.logger.log({level:C.warn,message:"The backend connector implements postCheckpointRequest, but connect() was called without checkpoint requests enabled."}),s&&!this.syncStreamImplementation||await this.disconnectInternal();const o=async()=>this.pendingConnectionOptions?this.connectingPromise=this.connectInternal().finally(o):void(this.connectingPromise=null);return this.connectingPromise??=this.connectInternal().finally(o)}async connectInternal(){let t=null;await this.disconnectInternal(),this.syncStreamInitPromise=new Promise(async(e,n)=>{let s=null;try{if(!this.pendingConnectionOptions)return this.logger.log({level:C.debug,message:"No pending connection options found, not creating sync stream implementation"}),void e();if(this.disconnectingPromise)return void e();s=this.pendingConnectionOptions;const{connector:n,options:r,schema:i}=s;t=r,this.currentOptions=r,this.currentConnector=n,this.pendingConnectionOptions=null;const o=this.subscriptionIdentity,{sync:a,onDispose:c}=await this.options.createSyncImplementation(n,{subscriptions:this.activeStreams,serializedSchema:i});this.iterateListeners(t=>t.syncStreamCreated?.(a)),this.syncStreamImplementation=a,this.syncDisposer=c,await this.syncStreamImplementation.waitForReady(),this.subscriptionIdentity!==o&&this.syncStreamImplementation.updateSubscriptions(this.activeStreams),e()}catch(t){n(t)}});try{await this.syncStreamInitPromise}finally{this.syncStreamInitPromise=null}t&&(await this.disconnectingPromise,this.logger.log({level:C.debug,message:"Attempting to connect to PowerSync instance"}),await(this.syncStreamImplementation?.connect(t)))}async disconnect(){this.pendingConnectionOptions=null,this.currentOptions=null,this.currentConnector=null,await this.disconnectInternal()}async disconnectInternal(){if(this.disconnectingPromise)return this.disconnectingPromise;this.disconnectingPromise=this.performDisconnect();try{await this.disconnectingPromise}finally{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 te(e,n,this.logger,r,t),this.locallyActiveSubscriptions.set(i,o),this.subscriptionsMayHaveChanged()}return new ee(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 te{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 ee{subscription;active=!0;constructor(t){this.subscription=t,t.refcount++,ne?.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,ne?.unregister(this),this.subscription.decrementRefCount())}}const ne="FinalizationRegistry"in globalThis?new FinalizationRegistry(t=>{t.logger.log({level:C.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 se{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 re{available;size;firstWaiter;lastWaiter;constructor(t){this.available=new se(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 ie{inner=new re([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 oe{clientId;id;op;opData;previousValues;table;transactionId;metadata;static fromRow(t){const e=JSON.parse(t.data);return new oe(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 ae=Symbol.asyncIterator??Symbol.for("Symbol.asyncIterator"),ce={done:!0,value:void 0};function le(t){return{done:!1,value:t}}function ue(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(ce);if(s)return s({resolve:a,reject:c}),void(s=null);if(i.length){const t=i.shift();return void("fulfilled"===t.status?a(le(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(le(t)):i.push({status:"fulfilled",value:t})},injectError(t){const e=o();null!=e?e.reject(t):i.push({status:"rejected",reason:t})}}}function he(){const t=new de;return{notify(){t.countOutstandingEvents>0||t.notify()},waitForNotification:e=>t.waitForEvent(e)}}class de{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{[ae]:()=>{const n=new de,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?ce:le(t)},return:async()=>(r(),ce)}}}}}async function pe(t,e,n,s){const r=new AbortController,i=new Error(`${n} timed out after ${e}ms`),o=()=>r.abort(t?.reason);t?.aborted?o():t?.addEventListener("abort",o,{once:!0});const a=setTimeout(()=>r.abort(i),e);try{return await s(r.signal)}catch(t){if(r.signal.reason===i)throw i;throw t}finally{clearTimeout(a),t?.removeEventListener("abort",o)}}class ge 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(Dt.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 Bt(t)!=Jt)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:C.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:C.debug,message:`New data uploaded since write checpoint ${n} - need new write checkpoint (sequence updated)`}),!1):(this.logger.log({level:C.debug,message:`Updating target write checkpoint to ${n}`}),await Bt(t,n),!0)})}readCheckpointRequestId(t,e=null){return this.db.writeTransaction(async n=>await $t(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 oe.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(oe.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 Bt(n,e)}else await Bt(n,Jt)})}async writeTransaction(t,e){return this.db.writeTransaction(t,e)}async control(t,e){return await this.writeTransaction(async n=>await $t(n,t,e))}async hasMigratedSubkeys(){const{r:t}=await this.db.get("SELECT EXISTS(SELECT * FROM ps_kv WHERE key = ?) as r",[ge._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 (?, ?);",[ge._subkeyMigrationKey,"1"])})}static _subkeyMigrationKey="powersync_js_migrated_subkeys"}const fe={state:"pending"};class me{currentState=fe;stateChanged=new I;waitingForCheckpointsReady=he();updateState(t){this.currentState=t,this.stateChanged.iterateListeners(t=>t.stateChanged?.())}downloadIterationEnded(){this.updateState(fe),this.waitingForCheckpointsReady=he()}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)=>{if(t.aborted)return void n(!1);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 ye(t,e){const n=t?.internal_last_applied_checkpoint_request_id;return null!=n&&BigInt(n)>=e}class we extends Error{reason;constructor(t){super(t),this.reason=t,Object.setPrototypeOf(this,we.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,we)}}const be=/\/+$/,Se={LogLevels:C,EventQueue:de,AbortOperation:we};class ve{connector;logger;credentials=null;constructor(t,e){this.connector=t,this.logger=e}async getCredentials(t){return this.credentials?this.credentials:this.prefetchCredentials(t)}async prefetchCredentials(t){return this.credentials=await this.fetchCredentials(t),this.credentials}async fetchCredentials(t){const e=this.connector.fetchCredentials;if(!e)throw new Error("No connector configured for downloads");const n=await e(t);if(n?.endpoint.match(be))throw new Error(`A trailing forward slash "/" was found in the fetchCredentials endpoint: "${n.endpoint}". Remove the trailing forward slash "/" to fix this error.`);return n}invalidateCredentials(){this.credentials=null,this.connector.invalidateCredentials?.()}getUserAgent(){return"powersync-js/1.5.0"}async buildRequest(t,e){const n=await this.getCredentials(e);if(null!=n&&(null==n.endpoint||""==n.endpoint))throw new Error("PowerSync endpoint not configured");if(null==n?.token||""==n?.token){const t=new Error("Not signed in");throw t.status=401,t}const s=this.getUserAgent();return{url:n.endpoint+t,headers:{"content-type":"application/json",Authorization:`Token ${n.token}`,"x-user-agent":s},userAgent:s,path:t}}async fetchAndDecodeJson({path:t,method:e="GET",headers:n,body:s,signal:r}){const i=await this.buildRequest(t,r),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(Se),n=await this.buildRequest(t.path,t.abortSignal);n.url=n.url.replace(/^https?:\/\//,function(t){return"https://"===t?"wss://":"ws://"});const{fetchStrategy:s=q.Buffered,abortSignal:r,data:i}=t;return await e.webSocketSyncStream({remote:this,buffered:s==q.Buffered,abortSignal:r,requestPayload:i,request:n})}async fetchStreamRaw(t){const{data:e,path:n,abortSignal:s,connectTimeoutMs:r}=t,i=await this.buildRequest(n,s);if(s.aborted)throw new we("Abort request received before making fetchStreamRaw request");const o=new AbortController;let a,c=null;s.addEventListener("abort",()=>{const t=s.reason??new we("Cancelling network request before it resolves. Abort signal has been received.");null==c?o.abort(t):c.cancel(t).catch(()=>{})});let l=!1;try{const t="application/x-ndjson",s="application/vnd.powersync.bson-stream",c=n=>this.fetch({resource:i.url,request:{method:"POST",headers:{...i.headers,accept:`${s};q=0.9,${t};q=0.8`},body:JSON.stringify(e),signal:n,cache:"no-store"},expectStreamingResponse:!0});if(a=await(null==r?c(o.signal):pe(o.signal,r,"Sync stream connection",c)),!a.ok||!a.body){const t=await a.text(),e=new Error(`HTTP ${a.statusText}: ${t}`);throw e.status=a.status,this.logger.log({level:C.error,message:`Could not POST streaming to ${n} - ${a.status} - ${a.statusText}: ${t}`,error:e}),401===a.status&&this.invalidateCredentials(),e}l=a.headers.get("content-type")==s}catch(t){if("AbortError"==t.name)throw new we(`Pending fetch request to ${i.url} has been aborted.`);throw t}c=a.body.getReader();return{isBson:l,stream:{next:async()=>{if(o.signal.aborted)return ce;try{return await c.read()}catch(t){if(o.signal.aborted)return ce;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 le(e.shift());if(n)return ce;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 ce}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 ce;{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}):ce}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 Ce(t){return"EstablishSyncStream"in t||"CloseSyncStream"in t}var _e;!function(t){t.CRUD="crud",t.SYNC="sync"}(_e||(_e={}));class Ee extends I{options;abortController;crudUpdateListener;streamingSyncPromise;logger;activeStreams;connectionMayHaveChanged=!1;crudUploadNotifier=he();checkpoints=new me;connectTimeoutMs=3e4;notifyCompletedUploads;handleActiveStreamsChange;syncStatus;constructor(t){super(),this.options=t,this.activeStreams=t.subscriptions,this.logger=t.logger,this.syncStatus=new Kt(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}emitDiagnostics(t){}async requestNextCheckpointFromService(t){if(!await this.checkpoints.waitForCheckpointRequestsReady(t))throw t.reason;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})}requestCheckpointFromService(t,e){return pe(t,this.connectTimeoutMs,"Checkpoint request",async t=>{const n=this.options.connector.postCheckpointRequest;if(n){const s=await n(e.client_id,e.checkpoint_request_id,t);if(null!=s)return s}return(await this.options.remote.fetchAndDecodeJson({method:"POST",path:"/sync/checkpoint-request",body:JSON.stringify(e),signal:t})).data.checkpoint_request_id})}async getLegacyWriteCheckpoint(t){let e=`/write-checkpoint2.json?client_id=${await this.options.adapter.getClientId()}`;const n=(await pe(t,this.connectTimeoutMs,"Write checkpoint request",t=>this.options.remote.fetchAndDecodeJson({path:e,signal:t}))).data.write_checkpoint;return this.logger.log({level:C.debug,message:`Created write checkpoint: ${n}`}),n}async crudUploadLoop(t,e){for(this.crudUpdateListener=this.options.adapter.registerListener({crudUpdate:()=>this.triggerCrudUpload()}),t.addEventListener("abort",()=>{this.crudUpdateListener?.(),this.crudUpdateListener=void 0});!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:_e.CRUD,signal:t,callback:async()=>{let n;for(;!t.aborted;)try{const s=await this.options.adapter.nextCrudItem();if(!s){this.options.connector.fetchCredentials&&await this.updateLocalTarget(t,e)||null==n||this.logger.log({level:C.debug,message:"Upload complete, no write checkpoint needed."});break}if(this.updateJsSyncState({uploading:!0}),s.clientId==n?.clientId)throw this.logger.log({level:C.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.connector.uploadCrud(t),this.updateJsSyncState({uploadError:void 0})}catch(s){if(n=void 0,this.updateJsSyncState({uploading:!1,uploadError:s}),await this.delayRetry(t,e.retryDelayMs),this.options.connector.fetchCredentials&&!this.isConnected)break;this.logger.log({level:C.debug,message:"Caught exception when uploading. Upload will retry after a delay.",error:s})}finally{this.updateJsSyncState({uploading:!1})}}})}async updateLocalTarget(t,e){const n=await this.options.adapter.updateLocalTarget(()=>"legacy"===e.checkpointMode?this.getLegacyWriteCheckpoint(t):this.requestNextCheckpointFromService(t));return n&&this.notifyCompletedUploads?.(),n}async connect(t){this.abortController&&await this.disconnect();const e=new AbortController;this.abortController=e,this.connectTimeoutMs=t.connectTimeoutMs;const n=e.signal,s=[],r=this.options.connector;if(r.uploadCrud&&s.push(this.crudUploadLoop(n,t).catch(t=>{n.reason!==t&&this.logger.log({level:C.error,message:"Error in crud upload loop",error:t})})),r.fetchCredentials&&(r.uploadCrud||s.push(this.updateLocalTarget(n,t).then(()=>{}).catch(t=>{n.reason!==t&&this.logger.log({level:C.error,message:"Could not update local target",error:t})})),s.push(this.streamingSync(n,t)),s.push(this.repostUnacknowledgedCheckpointRequests(n,t))),this.streamingSyncPromise=Promise.all(s).finally(()=>{this.checkpoints.disconnected()}),r.fetchCredentials)return new Promise(t=>{let e=!1,s=!1;const r=()=>{s||(s=!0,i(),n.removeEventListener("abort",r),t())},i=this.registerListener({statusChanged:t=>{if(t.connecting&&(e=!0),null!=t.downloadError)this.logger.log({level:C.warn,message:"Initial connect attempt did not successfully connect to server"});else if(!e||t.connecting)return;r()}});n.addEventListener("abort",r,{once:!0})})}async requestCheckpoint(){const t=(new AbortController).signal,e=this.abortController?.signal??t;return BigInt(await this.requestNextCheckpointFromService(e))}async disconnect(){if(this.abortController){this.abortController.signal.aborted||this.abortController.abort(new we("Disconnect has been requested"));try{await this.streamingSyncPromise}catch(t){this.logger.log({level:C.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){let n=new AbortController;for(t.addEventListener("abort",()=>{n.abort(t?.reason??new we("Received command to disconnect from upstream")),this.markAsDisconnected()});;){let s=!0,r=null;try{if(t?.aborted)break;r=await this.streamingSyncIteration(n.signal,e)}catch(e){const n=t.aborted;n?(this.logger.log({level:C.warn,message:"Sync aborted",error:e}),s=!1):this.connectionMayHaveChanged&&e?.message?.includes("No iteration is active")?(this.connectionMayHaveChanged=!1,this.logger.log({level:C.info,message:"Sync error after changed connection, retrying immediately"}),s=!1):this.logger.log({level:C.error,message:"Sync error",error:e}),n||this.updateJsSyncState({downloadError:e})}finally{this.checkpoints.downloadIterationEnded(),this.notifyCompletedUploads=void 0,t.aborted||(n.abort(new we("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:_e.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,connectTimeoutMs:n.connectTimeoutMs}):await this.options.remote.socketStreamRaw({...e,fetchStrategy:n.fetchStrategy});let i,o=!1;return{async next(){if(o)return ce;if(null==i)return i=await r(),le({command:Nt.CONNECTION_STATE,payload:"established"});{const t=await i.next();return t.done?(o=!0,le({command:Nt.CONNECTION_STATE,payload:"end"})):le({command:"string"==typeof t.value?Nt.PROCESS_TEXT_LINE:Nt.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{if(!await this.checkpoints.waitForCheckpointRequestsReady(t,!1))return;const e=await this.options.adapter.readCheckpointRequestId("current");if(await this.delayRetry(t,n),e!=await this.options.adapter.readCheckpointRequestId("current"))continue;if(ye(this.syncStatus?.core,BigInt(e)))continue;if(!await this.checkpoints.waitForCheckpointRequestsReady(t,!1))return;this.logger.log({level:C.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:C.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 willUpload(){return!!this.options.connector.uploadCrud||!await this.options.adapter.hasCrud()}async rustSyncIteration(t,e){const n=this,s=this.options.adapter,r=this.options.remote;let i,o=!1;if(t.aborted)throw new we("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:C.trace,message:`powersync_control(${t}, ${i}) -> ${r}`}),t!=Nt.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:C.debug,message:s});break;case"INFO":n.logger.log({level:C.info,message:s});break;case"WARNING":n.logger.log({level:C.warn,message:s})}}else if("UpdateSyncStatus"in t)n.updateSyncStatus(t.UpdateSyncStatus.status);else if("FetchCredentials"in t)t.FetchCredentials.did_expire?r.invalidateCredentials():(r.invalidateCredentials(),r.fetchCredentials().then(t=>{i?.()},t=>{n.logger.log({level:C.warn,message:"Could not prefetch credentials",error:t})}));else if("FlushFileSystem"in t);else if("DidCompleteSync"in t)n.updateJsSyncState({downloadError:void 0});else if("HandleDiagnostics"in t)n.emitDiagnostics(t.HandleDiagnostics);else if("CheckpointDelayedDueToLocalData"in t&&!await n.willUpload()){const t="Applying checkpoint is blocked on local mutations, but no uploader is set. The sync client cannot proceed.";n.logger.log({level:C.error,message:t}),n.updateJsSyncState({downloadError:new Error(t)})}}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),e.diagnostics&&(t.diagnostics={}),c(Nt.START,JSON.stringify(t))}())if("EstablishSyncStream"in i){const s=i.EstablishSyncStream,o={path:"/sync/stream",abortSignal:t,data:s.request};if(r=ue(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:Nt.NOTIFY_CRUD_UPLOAD_COMPLETED})},this.handleActiveStreamsChange=()=>{r.inject({command:Nt.UPDATE_SUBSCRIPTIONS,payload:JSON.stringify(this.activeStreams)})},i=()=>{r.inject({command:Nt.NOTIFY_TOKEN_REFRESHED})};let u=!1;t:for(;;){const{done:t,value:e}=await r.next();if(t)break;u||e.command!=Nt.PROCESS_TEXT_LINE&&e.command!=Nt.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)}}}catch(e){throw t.aborted||this.updateJsSyncState({downloadError:e}),e}finally{this.notifyCompletedUploads=this.handleActiveStreamsChange=void 0,i=void 0,await async function(){const t=await c(Nt.STOP);for(const e of t)Ce(e)||await l(e)}()}return{immediateRestart:o}}updateSyncStatus(t,e){const n=new Kt(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 ke extends Error{static NAME="ConnectionClosedError";static MATCHES(t){return t instanceof ke||t instanceof Error&&t.name==ke.NAME}constructor(t){super(t),this.name=ke.NAME}}class Ae{inner;leaseMutex;constructor(t,e){this.inner=t,this.leaseMutex=e?null:new ie}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 Te(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 Te{returnMutex;connection;useMutex=new ie;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 Le="open-wasqlite-db";const qe="SharedWorkerGlobalScope"in globalThis;class Pe extends ve{constructor(t,e){super(t,e)}fetch({resource:t,request:e}){return fetch(t,e)}async loadWebSocketSupport(t){if(!xe){const e=await import("./websockets-Dx9ExO-W.js");xe=new e.WebSocketSupport(t)}return xe}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:C.warn,message:"Failed to get user agent info",error:t})}return t.join(" ")}}let xe;class Ie extends Ee{diagnosticsChannel;constructor(t){super(t)}emitDiagnostics(t){this.diagnosticsChannel??=new BroadcastChannel("powersync-diagnostics-events"),this.diagnosticsChannel.postMessage(t)}async dispose(){await super.dispose(),this.diagnosticsChannel?.close(),this.diagnosticsChannel=void 0}get webOptions(){return this.options}async obtainLock(t){const e=`streaming-sync-${t.type}-${this.webOptions.identifier}`;return t.type==_e.SYNC&&this.logger.log({level:C.debug,message:`requesting lock for ${e}`}),N().request(e,{signal:t.signal},t.callback)}}class Oe{clients;inner;currentLevel=C.info;sequence=0;sendBroadcasts=!0;constructor(t,e){this.clients=e,this.inner=_({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(!("error"in t))return t;const e=Ht(t.error);return{...t,error:{...e,relay:{origin:"shared-sync-worker",sequence:this.sequence++,errorState:e.state,relayedAt:(new Date).toISOString()}}}}}class Re 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(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 Ue(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 Ue(this.#u,e=>e.requestAccess(t,n?.timeoutMs));try{return await e(new Me(this.#u,s))}finally{await Ue(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 Me extends M{#u;#g;constructor(t,e){super(),this.#u=t,this.#g=e}async maybeTrace(t,e){if(!this.#u.traceQueries)return Ue(this.#u,t);{const n=performance.now(),s=e();try{const e=await Ue(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.#f(t,e)}async#f(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 Ue(t,e,n=!1){const s=t.notifyRemoteClosed;return s?new Promise((r,i)=>{function o(){i(new ke("Remote peer closed with request in flight"))}function a(t){s.signal.removeEventListener("abort",o),t()}s.signal.aborted&&(i(new ke("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 Fe;!function(t){t.CLOSE_CLIENT="close-client",t.CLOSE_ACK="close-ack"}(Fe||(Fe={}));const De={};class Ne 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 ie,this.isInitialized=new Promise(t=>{const e=this.registerListener({initialized:()=>{t(),e?.()}})}),this.logger=new Oe("shared-sync",this.ports),this.connectionManager=new Zt({createSyncImplementation:async()=>{await this.waitForReady();const t=await 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(),this.syncStatus&&=new Kt(this.syncStatus.core,{})}}},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:C.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:C.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:C.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(De,t??{},e)}async disconnect(){return this.connectionManager.disconnect()}addPort(t,e){return this.portMutex.runExclusive(()=>{if(this.ports.length){!function(t,e){if(t.hasFetchCredentials!=e.hasFetchCredentials||t.hasUploadCrud!=e.hasUploadCrud||t.hasPostCheckpointRequest!=e.hasPostCheckpointRequest)throw new Error("Different tabs connecting in different modes (download-only / upload-only / full, or with and without custom checkpoint requests) is not supported")}(this.ports[0].clientCapabilities,e)}const n={port:t,clientProvider:l(t),currentSubscriptions:[],closeListeners:[],isClosing:!1,clientCapabilities:e};this.ports.push(n);const s=this.syncStatus;return s&&n.clientProvider.statusChanged(s.toJSON()),n})}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:C.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,e=this.ports[0]?.clientCapabilities;if(!e)throw new Error("Cannot create a sync implementation without connected clients");const n={};return e.hasFetchCredentials&&(n.invalidateCredentials=async()=>{const t=await this.getLastWrappedPort();if(!t)throw new Error("No client port found to invalidate credentials");try{this.logger.log({level:C.info,message:"calling the last port client provider to invalidate credentials"}),t.clientProvider.invalidateCredentials()}catch(t){this.logger.log({level:C.error,message:"error invalidating credentials",error:t})}}),e.hasFetchCredentials&&(n.fetchCredentials=t=>this.#m(t=>(this.logger.log({level:C.info,message:"calling the last port client provider for credentials"}),t.clientProvider.fetchCredentials()),"fetchCredentials",t)),e.hasUploadCrud&&(n.uploadCrud=t=>this.#m(t=>t.clientProvider.uploadCrud(),"uploadCrud",t)),e.hasPostCheckpointRequest&&(n.postCheckpointRequest=(t,e,n)=>this.#m(n=>n.clientProvider.postCheckpointRequest(t,e),"postCheckpointRequest",n)),new Ie({adapter:new ge(this.database,this.logger),connector:n,remote:new Pe(n,this.logger),...t.streamOptions,subscriptions:this.subscriptions,logger:this.logger})}async#m(t,e,n){const s=async()=>{const n=await this.getLastWrappedPort();if(!n)throw new Error(`No client port found for ${e}`);return await new Promise((s,r)=>{const i=()=>{r(new Error(`Tab closed while handling ${e}`))};n.closeListeners.push(i),t(n).then(s,r).finally(()=>{const t=n.closeListeners.indexOf(i);t>=0&&n.closeListeners.splice(t,1)})})};return n?$e({signal:n,action:s}):s()}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 $e({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 $e({action:async()=>{const t=await o.connectToExisting({identifier:a,lockName:c});return new Re({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:C.info,message:"Aborting open connection because associated tab closed."}),t(u),u.markRemoteClosed(),u.close().catch(t=>this.logger.log({level:C.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 $e(t){const{action:e,signal:n,cleanupOnAbort:s}=t,r=()=>n.reason instanceof Error?n.reason:new we("Operation aborted by abort controller");return new Promise((t,i)=>{function o(){n.removeEventListener("abort",o),i(r())}function a(t){n.removeEventListener("abort",o),t()}n.aborted?i(r()):(n.addEventListener("abort",o,{once:!0}),e().then(e=>{if(n.aborted)return a(()=>s?.(e));a(()=>t(e))}).catch(t=>a(()=>i(t))))})}class Be{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==Fe.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:Fe.CLOSE_ACK,data:{}}),e?.()}}async initialize(t,e){this.resolvedPort=await this.sync.addPort(this.port,e),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 je=new class{logger;#y=new Map;#w=new ie;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(Le,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:C.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=!(qe||s||r==xt.InMemoryVfs),o=this.#y;async function a(){let s=o.get(n);if(null==s){const r=new Ft(e),a=new Ae(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(Le,a):this.#w.runExclusive(a)}closeAll(){const t=[...this.#y.values()];return Promise.all(t.map(t=>{t.forceClose()}))}}(_({prefix:"db-worker",minLevel:C.trace})),ze={connect:t=>je.handleConnection(t),connectToExisting:({identifier:t,lockName:e})=>je.connectToExisting(t,e)};if(qe){const t=new Ne;self.onconnect=e=>{e.ports[0].onmessage=e=>{const{service:n,port:s}=e.data;"database"===n?a(ze,s):"sync"===n&&new Be(t,s)}}}else a(ze);export{St as A,bt as B,B as C,z as D,yt as E,mt 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,W as d,dt as e,j as f,gt as g,ft 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,_t as x,Ct as y,vt as z};
7
7
  //# sourceMappingURL=worker.js.map