@powersync/web 2.5.0 → 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.
- package/dist/index.react_native_web.js +80 -21
- package/dist/index.react_native_web.js.map +1 -1
- package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js +2 -0
- package/dist/worker/AccessHandlePoolVFS-Do8lc5Ck.js.map +1 -0
- package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -1
- package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js +2 -0
- package/dist/worker/IDBBatchAtomicVFS-CDb4d4wN.js.map +1 -0
- package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -1
- package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js +2 -0
- package/dist/worker/OPFSCoopSyncVFS-CDNBPKfy.js.map +1 -0
- package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js +2 -0
- package/dist/worker/OPFSWriteAheadVFS-V9yBrLWl.js.map +1 -0
- package/dist/worker/assets/mc-wa-sqlite-Cq3AePIW.wasm +0 -0
- package/dist/worker/assets/{mc-wa-sqlite-async-DdlQmAUV.wasm → mc-wa-sqlite-async-aRcIGeKj.wasm} +0 -0
- package/dist/worker/assets/wa-sqlite-CePoIZt_.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-async-B3FiUnt1.wasm +0 -0
- package/dist/worker/{mc-wa-sqlite-PubB6u8c.js → mc-wa-sqlite-DRR2R_uj.js} +2 -2
- package/dist/worker/mc-wa-sqlite-DRR2R_uj.js.map +1 -0
- package/dist/worker/{mc-wa-sqlite-async-DJG_ANKO.js → mc-wa-sqlite-async-C40l6kIz.js} +2 -2
- package/dist/worker/mc-wa-sqlite-async-C40l6kIz.js.map +1 -0
- package/dist/worker/{wa-sqlite-D1_4mGs8.js → wa-sqlite-_a9CU4MM.js} +2 -2
- package/dist/worker/wa-sqlite-_a9CU4MM.js.map +1 -0
- package/dist/worker/wa-sqlite-async-Da0d0GJg.js +2 -0
- package/dist/worker/wa-sqlite-async-Da0d0GJg.js.map +1 -0
- package/dist/worker/{websockets-Q8W_lerF.js → websockets-Dx9ExO-W.js} +2 -2
- package/dist/worker/{websockets-Q8W_lerF.js.map → websockets-Dx9ExO-W.js.map} +1 -1
- package/dist/worker/worker.js +1 -1
- package/dist/worker/worker.js.map +1 -1
- package/lib/db/PowerSyncDatabase.d.ts +4 -3
- package/lib/db/PowerSyncDatabase.js +3 -0
- package/lib/db/PowerSyncDatabase.js.map +1 -1
- package/lib/db/adapters/options.d.ts +30 -0
- package/lib/db/adapters/options.js.map +1 -1
- package/lib/db/adapters/resolveAndValidateOptions.js +6 -1
- package/lib/db/adapters/resolveAndValidateOptions.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +5 -0
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js +7 -2
- package/lib/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +4 -2
- package/lib/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -1
- package/lib/db/adapters/wa-sqlite/vfs.d.ts +24 -1
- package/lib/db/adapters/wa-sqlite/vfs.js +33 -4
- package/lib/db/adapters/wa-sqlite/vfs.js.map +1 -1
- package/lib/db/sync/SharedWebStreamingSyncImplementation.d.ts +1 -0
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js +28 -11
- package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
- package/lib/db/sync/WebRemote.d.ts +2 -3
- package/lib/db/sync/WebRemote.js +0 -2
- package/lib/db/sync/WebRemote.js.map +1 -1
- package/lib/worker/sync/SharedSyncImplementation.d.ts +9 -2
- package/lib/worker/sync/SharedSyncImplementation.js +66 -37
- package/lib/worker/sync/SharedSyncImplementation.js.map +1 -1
- package/lib/worker/sync/WorkerClient.d.ts +3 -3
- package/lib/worker/sync/WorkerClient.js +3 -3
- package/lib/worker/sync/WorkerClient.js.map +1 -1
- package/package.json +6 -6
- package/src/db/PowerSyncDatabase.ts +6 -3
- package/src/db/adapters/options.ts +32 -0
- package/src/db/adapters/resolveAndValidateOptions.ts +9 -1
- package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +12 -2
- package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +6 -2
- package/src/db/adapters/wa-sqlite/vfs.ts +51 -4
- package/src/db/sync/SharedWebStreamingSyncImplementation.ts +34 -15
- package/src/db/sync/WebRemote.ts +2 -5
- package/src/worker/sync/SharedSyncImplementation.ts +89 -48
- package/src/worker/sync/WorkerClient.ts +4 -3
- package/dist/worker/AccessHandlePoolVFS-B9CKqcQ3.js +0 -2
- package/dist/worker/AccessHandlePoolVFS-B9CKqcQ3.js.map +0 -1
- package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js +0 -2
- package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js.map +0 -1
- package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js +0 -2
- package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js.map +0 -1
- package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.js +0 -2
- package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.js.map +0 -1
- package/dist/worker/assets/mc-wa-sqlite-BHScYYZw.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-CIxTmRHQ.wasm +0 -0
- package/dist/worker/assets/wa-sqlite-async-zc68fxQq.wasm +0 -0
- package/dist/worker/mc-wa-sqlite-PubB6u8c.js.map +0 -1
- package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +0 -1
- package/dist/worker/wa-sqlite-D1_4mGs8.js.map +0 -1
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js +0 -2
- package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +0 -1
package/dist/worker/worker.js
CHANGED
|
@@ -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]=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 _={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,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"}(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 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);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"}(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:_.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,j=5,W=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,ft=4,mt=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={};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 Lt("not a database",21)}const p=new Map;function g(t){if(!p.has(t))throw new Lt("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 Lt(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:qt});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 Lt("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:qt});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:qt});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 Lt(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:qt});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:qt});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 Lt("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;async function Ot(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 Rt(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"}(It||(It={}));class Mt{#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 Ut{options;_sqliteAPI=null;sqlite3_stmt_isexplain;db=0;statementCache;constructor(t){this.options=t,this.statementCache=t.preparedStatementsCache>0?new Mt(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=Rt;switch(t){case xt.IDBBatchAtomicVFS:{r=Ot;const{IDBBatchAtomicVFS:t}=await import("./IDBBatchAtomicVFS-BfRzbRoV.js");s=n=>t.create(e,n,{lockPolicy:"exclusive"});break}case xt.AccessHandlePoolVFS:{const{AccessHandlePoolVFS:t}=await import("./AccessHandlePoolVFS-B9CKqcQ3.js");s=n=>t.create(e,n);break}case xt.OPFSCoopSyncVFS:{const{OPFSCoopSyncVFS:t}=await import("./OPFSCoopSyncVFS-BxXAVpVQ.js");s=n=>t.create(e,n);break}case xt.OPFSWriteAheadVFS:{const{OPFSWriteAheadVFS:t}=await import("./OPFSWriteAheadVFS-DuqXaOct.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=Tt(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,Dt;async function Nt(t,e,n){const{rawRows:s}=await t.executeRaw("SELECT CAST(powersync_control(?, ?) AS TEXT)",[e,n]);return s[0][0]}function $t(t,e=null){return Nt(t,"target_checkpoint_request_id",e)}!function(t){t.DATA="ps_data",t.CRUD="ps_crud",t.BUCKETS="ps_buckets",t.OPLOG="ps_oplog",t.UNTYPED="ps_untyped"}(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"}(Dt||(Dt={}));const Bt="__powersyncError";function jt(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[Bt]}(t))return t;if(!jt(t))return function(t){const e="string"==typeof t||"number"==typeof t||"boolean"==typeof t;return{[Bt]:!0,name:"string"==typeof t?"String":"Error",message:e?String(t):"Non-Error rejection",state:"serialized"}}(t);const s=t,r={[Bt]:!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 jt(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 zt(t){try{return null==t?(e=t,{[Bt]:!0,name:"PowerSyncMissingRejectionReason",message:`No rejection reason was provided (${e}).`,state:"missing"}):Wt(t,5,{lossy:!1})}catch{return{[Bt]:!0,name:"Error",message:"Unable to serialize rejection reason",state:"partial"}}var e}const Ht=2147483647,Vt="9223372036854775807";class Jt{internal;totalOperations;downloadedOperations;downloadedFraction;constructor(t){this.internal=t;const e=this.untilPriority(Ht);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 Gt{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(Ht)?.lastSyncedAt}get hasSynced(){return this.statusForPriority(Ht)?.hasSynced}get syncStreams(){return this.core?.streams.map(t=>new Yt(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 Yt(this,n)}get priorityStatusEntries(){return this.core?.priority_status.map(Qt)}get downloadProgress(){const t=this.core?.downloading;return null==t?null:new Jt(t)}statusForPriority(t){const e=this.core?.priority_status;if(null!=e){for(const n of e)if(n.priority>=t)return Qt(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 zt(t)}}function Kt(t){return null==t?void 0:new Date(t/1e3)}function Qt(t){return{priority:t.priority,hasSynced:t.has_synced??void 0,lastSyncedAt:Kt(t.last_synced_at)}}class Yt{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:Kt(e.expires_at)??null,hasSynced:null!=e.last_synced_at,lastSyncedAt:Kt(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 Xt 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??T.Buffered,params:t.params??{},includeDefaultStreams:t.includeDefaultStreams??!0,retryDelayMs:t.retryDelayMs??5e3,crudUploadThrottleMs:t.crudUploadThrottleMs??1e3,checkpointMode:t.checkpointMode??"legacy",diagnostics:t.diagnostics??!1}}(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.currentConnector=n,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,this.currentConnector=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 Zt(e,n,this.logger,r,t),this.locallyActiveSubscriptions.set(i,o),this.subscriptionsMayHaveChanged()}return new te(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 Zt{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 te{subscription;active=!0;constructor(t){this.subscription=t,t.refcount++,ee?.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,ee?.unregister(this),this.subscription.decrementRefCount())}}const ee="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 ne{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 se{available;size;firstWaiter;lastWaiter;constructor(t){this.available=new ne(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 re{inner=new se([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 ie{clientId;id;op;opData;previousValues;table;transactionId;metadata;static fromRow(t){const e=JSON.parse(t.data);return new ie(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 oe=Symbol.asyncIterator??Symbol.for("Symbol.asyncIterator"),ae={done:!0,value:void 0};function ce(t){return{done:!1,value:t}}function le(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(ae);if(s)return s({resolve:a,reject:c}),void(s=null);if(i.length){const t=i.shift();return void("fulfilled"===t.status?a(ce(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(ce(t)):i.push({status:"fulfilled",value:t})},injectError(t){const e=o();null!=e?e.reject(t):i.push({status:"rejected",reason:t})}}}function ue(){const t=new he;return{notify(){t.countOutstandingEvents>0||t.notify()},waitForNotification:e=>t.waitForEvent(e)}}class he{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{[oe]:()=>{const n=new he,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?ae:ce(t)},return:async()=>(r(),ae)}}}}}class de 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 $t(t)!=Vt)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 $t(t,n),!0)})}readCheckpointRequestId(t,e=null){return this.db.writeTransaction(async n=>await Nt(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 ie.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(ie.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 $t(n,e)}else await $t(n,Vt)})}async writeTransaction(t,e){return this.db.writeTransaction(t,e)}async control(t,e){return await this.writeTransaction(async n=>await Nt(n,t,e))}async hasMigratedSubkeys(){const{r:t}=await this.db.get("SELECT EXISTS(SELECT * FROM ps_kv WHERE key = ?) as r",[de._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 (?, ?);",[de._subkeyMigrationKey,"1"])})}static _subkeyMigrationKey="powersync_js_migrated_subkeys"}const pe={state:"pending"};class ge{currentState=pe;stateChanged=new I;waitingForCheckpointsReady=ue();updateState(t){this.currentState=t,this.stateChanged.iterateListeners(t=>t.stateChanged?.())}downloadIterationEnded(){this.updateState(pe),this.waitingForCheckpointsReady=ue()}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 fe(t,e){const n=t?.internal_last_applied_checkpoint_request_id;return null!=n&&BigInt(n)>=e}class me extends Error{reason;constructor(t){super(t),this.reason=t,Object.setPrototypeOf(this,me.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,me)}}const ye=/\/+$/,we={LogLevels:_,EventQueue:he,AbortOperation:me};class be{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(ye))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.4.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(we),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 me("Abort request received before making fetchStreamRaw request");const i=new AbortController;let o,a=null;s.addEventListener("abort",()=>{const t=s.reason??new me("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 me(`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 ae;try{return await a.read()}catch(t){if(i.signal.aborted)return ae;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 ce(e.shift());if(n)return ae;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 ae}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 ae;{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}):ae}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 Se(t){return"EstablishSyncStream"in t||"CloseSyncStream"in t}var ve;!function(t){t.CRUD="crud",t.SYNC="sync"}(ve||(ve={}));class _e extends I{options;abortController;crudUpdateListener;streamingSyncPromise;logger;activeStreams;connectionMayHaveChanged=!1;crudUploadNotifier=ue();checkpoints=new ge;notifyCompletedUploads;handleActiveStreamsChange;syncStatus;constructor(t){super(),this.options=t,this.activeStreams=t.subscriptions,this.logger=t.logger,this.syncStatus=new Gt(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})}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:ve.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 me("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 me("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 me("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:ve.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 ae;if(null==i)return i=await r(),ce({command:Dt.CONNECTION_STATE,payload:"established"});{const t=await i.next();return t.done?(o=!0,ce({command:Dt.CONNECTION_STATE,payload:"end"})):ce({command:"string"==typeof t.value?Dt.PROCESS_TEXT_LINE:Dt.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(fe(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 me("Connection request has been aborted");const a=this.options.serializedSchema;async function c(t,e){const r=await s.control(t,e??null),i=null==e||"string"==typeof e?e:"<bytes>";return n.logger.log({level:_.trace,message:`powersync_control(${t}, ${i}) -> ${r}`}),t!=Dt.STOP&&(n.connectionMayHaveChanged=!1),JSON.parse(r)}async function l(t){if("LogLine"in t){const{severity:e,line:s}=t.LogLine;switch(e){case"DEBUG":n.logger.log({level:_.debug,message:s});break;case"INFO":n.logger.log({level:_.info,message:s});break;case"WARNING":n.logger.log({level:_.warn,message:s})}}else"UpdateSyncStatus"in t?n.updateSyncStatus(t.UpdateSyncStatus.status):"FetchCredentials"in t?t.FetchCredentials.did_expire?r.invalidateCredentials():(r.invalidateCredentials(),r.fetchCredentials().then(t=>{i?.()},t=>{n.logger.log({level:_.warn,message:"Could not prefetch credentials",error:t})})):"FlushFileSystem"in t||("DidCompleteSync"in t?n.updateJsSyncState({downloadError:void 0}):"HandleDiagnostics"in t&&n.emitDiagnostics(t.HandleDiagnostics))}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(Dt.START,JSON.stringify(t))}())if("EstablishSyncStream"in i){const s=i.EstablishSyncStream,o={path:"/sync/stream",abortSignal:t,data:s.request};if(r=le(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:Dt.NOTIFY_CRUD_UPLOAD_COMPLETED})},this.handleActiveStreamsChange=()=>{r.inject({command:Dt.UPDATE_SUBSCRIPTIONS,payload:JSON.stringify(this.activeStreams)})},i=()=>{r.inject({command:Dt.NOTIFY_TOKEN_REFRESHED})};let u=!1;t:for(;;){const{done:t,value:e}=await r.next();if(t)break;u||e.command!=Dt.PROCESS_TEXT_LINE&&e.command!=Dt.PROCESS_BSON_LINE||(u=!0,this.triggerCrudUpload?.());const n=await c(e.command,e.payload);for(const t of n){if("EstablishSyncStream"in t)throw new Error("Received EstablishSyncStream while already connected.");if("CloseSyncStream"in t){o=t.CloseSyncStream.hide_disconnect;break t}await l(t)}}}finally{this.notifyCompletedUploads=this.handleActiveStreamsChange=void 0,i=void 0,await async function(){const t=await c(Dt.STOP);for(const e of t)Se(e)||await l(e)}()}return{immediateRestart:o}}updateSyncStatus(t,e){const n=new Gt(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 Ce extends Error{static NAME="ConnectionClosedError";static MATCHES(t){return t instanceof Ce||t instanceof Error&&t.name==Ce.NAME}constructor(t){super(t),this.name=Ce.NAME}}class Ee{inner;leaseMutex;constructor(t,e){this.inner=t,this.leaseMutex=e?null:new re}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 ke(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 ke{returnMutex;connection;useMutex=new re;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 Ae="open-wasqlite-db";const Le="SharedWorkerGlobalScope"in globalThis;class qe extends be{connector;constructor(t,e){super(t,e),this.connector=t}fetch({resource:t,request:e}){return fetch(t,e)}async loadWebSocketSupport(t){if(!Te){const e=await import("./websockets-Q8W_lerF.js");Te=new e.WebSocketSupport(t)}return Te}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 Te;class Pe extends _e{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==ve.SYNC&&this.logger.log({level:_.debug,message:`requesting lock for ${e}`}),N().request(e,{signal:t.signal},t.callback)}}class xe{clients;inner;currentLevel=_.info;sequence=0;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(!("error"in t))return t;const e=zt(t.error);return{...t,error:{...e,relay:{origin:"shared-sync-worker",sequence:this.sequence++,errorState:e.state,relayedAt:(new Date).toISOString()}}}}}class Ie 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 Re(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 Re(this.#u,e=>e.requestAccess(t,n?.timeoutMs));try{return await e(new Oe(this.#u,s))}finally{await Re(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 Oe extends M{#u;#g;constructor(t,e){super(),this.#u=t,this.#g=e}async maybeTrace(t,e){if(!this.#u.traceQueries)return Re(this.#u,t);{const n=performance.now(),s=e();try{const e=await Re(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 Re(t,e,n=!1){const s=t.notifyRemoteClosed;return s?new Promise((r,i)=>{function o(){i(new Ce("Remote peer closed with request in flight"))}function a(t){s.signal.removeEventListener("abort",o),t()}s.signal.aborted&&(i(new Ce("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 Me;!function(t){t.CLOSE_CLIENT="close-client",t.CLOSE_ACK="close-ack"}(Me||(Me={}));const Ue={};class Fe 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 re,this.isInitialized=new Promise(t=>{const e=this.registerListener({initialized:()=>{t(),e?.()}})}),this.logger=new xe("shared-sync",this.ports),this.connectionManager=new Xt({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 Gt(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(Ue,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 Pe({adapter:new de(this.database,this.logger),remote:new qe({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.#m(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.#m(t=>t.clientProvider.uploadCrud(),"uploadCrud",t),postCheckpointRequest:(t,e,n)=>this.#m(n=>n.clientProvider.postCheckpointRequest(t,e),"postCheckpointRequest",n),...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?De({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 De({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 De({action:async()=>{const t=await o.connectToExisting({identifier:a,lockName:c});return new Ie({connection:t,source:o,remoteCanCloseUnexpectedly:!0},this.syncParams.dbParams)},signal:s.signal,cleanupOnAbort:t=>{t.close()}}).finally(()=>{i()});return clearTimeout(n),e.closeListeners.push(async()=>{this.logger.log({level:_.info,message:"Aborting open connection because associated tab closed."}),t(u),u.markRemoteClosed(),u.close().catch(t=>this.logger.log({level:_.warn,message:"error closing database connection",error:t}))}),u}generateReconnectableDatabase(){const t=this.syncParams,e=this;return new class extends U{connectionState=null;get name(){return t?.dbParams.dbFilename}async connect(){if(null==this.connectionState){const t=this.handleClientClosed.bind(this);this.connectionState=(async()=>{try{const n=await e.openInternalDB(t);return n.registerListener({tablesUpdated:t=>{this.iterateListeners(e=>e.tablesUpdated?.(t))}}),this.connectionState=n,n}catch(t){throw this.connectionState=null,t}})()}return await this.connectionState}async close(){null!=this.connectionState&&await(await this.connectionState).close()}handleClientClosed(t){if(t===this.connectionState){this.connectionState=null;const t=e.connectionManager.syncStreamImplementation;t?.triggerCrudUpload(),t?.markConnectionMayHaveChanged()}}async readLock(t,e){return(await this.connect()).readLock(t,e)}async writeLock(t,e){return(await this.connect()).writeLock(t,e)}async refreshSchema(){}}}}function De(t){const{action:e,signal:n,cleanupOnAbort:s}=t,r=()=>n.reason instanceof Error?n.reason:new me("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 Ne{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==Me.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:Me.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 $e=new class{logger;#y=new Map;#w=new re;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(Ae,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=!(Le||s||r==xt.InMemoryVfs),o=this.#y;async function a(){let s=o.get(n);if(null==s){const r=new Ut(e),a=new Ee(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(Ae,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})),Be={connect:t=>$e.handleConnection(t),connectToExisting:({identifier:t,lockName:e})=>$e.connectToExisting(t,e)};if(Le){const t=new Fe;self.onconnect=e=>{e.ports[0].onmessage=e=>{const{service:n,port:s}=e.data;"database"===n?a(Be,s):"sync"===n&&new Ne(t,s)}}}else a(Be);export{St as A,bt as B,B as C,W 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,z 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,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
|