← Public packages
@kentcdodds/world-builder
Build a shared 3D voxel world with friends and your AI agents, live.
public/powersync/IDBBatchAtomicVFS-DbkDb777.js
2 lines · 12.9 KB · JavaScriptimport{F as e}from"./FacadeVFS-d1ZDvud7.js";import{S as t,a as s,b as a,c as r,d as n,e as i,f as o,g as c,h as l,i as h,j as d,k as u,l as p,m as y,n as g,o as f,p as b,q as w,r as m,s as k,t as v,u as x,v as I,w as S,x as E,y as q,z as j,A as T,B as O,C as P,D as C,E as R,F as L}from"./worker.js";const F={mode:"shared"},M={ifAvailable:!0,mode:"shared"},D={ifAvailable:!0,mode:"exclusive"},z=["exclusive","shared","shared+hint"],B=e=>class extends e{#e={lockPolicy:"exclusive",lockTimeout:1/0};#t=new Map;constructor(e,t,s){if(super(e,t,s),Object.assign(this.#e,s),-1===z.indexOf(this.#e.lockPolicy))throw new Error(`WebLocksMixin: invalid lock mode: ${s.lockPolicy}`)}async jLock(e,a){try{const s=this.#s(e);if(a<=s.type)return t;switch(this.#e.lockPolicy){case"exclusive":return await this.#a(s,a);case"shared":case"shared+hint":return await this.#r(s,a)}}catch(e){return console.error("WebLocksMixin: lock error",e),s}}async jUnlock(e,s){try{const a=this.#s(e);if(!(s<a.type))return t;switch(this.#e.lockPolicy){case"exclusive":return await this.#n(a,s);case"shared":case"shared+hint":return await this.#i(a,s)}}catch(e){return console.error("WebLocksMixin: unlock error",e),a}}async jCheckReservedLock(e,s){try{const t=this.#s(e);switch(this.#e.lockPolicy){case"exclusive":return this.#o(t,s);case"shared":case"shared+hint":return await this.#c(t,s)}}catch(e){return console.error("WebLocksMixin: check reserved lock error",e),r}return s.setInt32(0,0,!0),t}jFileControl(e,t,s){if(t===B.WRITE_HINT_OP_CODE&&"shared+hint"===this.#e.lockPolicy){this.#s(e).writeHint=!0}return n}#s(e){let t=this.#t.get(e);if(!t){t={baseName:this.getFilename(e),type:i,writeHint:!1},this.#t.set(e,t)}return t}async#a(e,s){if(!e.access){if(!await this.#l(e,"access"))return o;console.assert(!!e.access)}return e.type=s,t}#n(e,s){return s===i&&(e.access?.(),console.assert(!e.access)),e.type=s,t}#o(e,s){return s.setInt32(0,0,!0),t}async#r(e,s){switch(e.type){case i:if(s!==h)throw new Error("unsupported lock transition");if(e.writeHint&&!await this.#l(e,"hint"))return o;if(!await this.#l(e,"gate",F))return e.hint?.(),o;await this.#l(e,"access",F),e.gate(),console.assert(!e.gate),console.assert(!!e.access),console.assert(!e.reserved);break;case h:switch(s){case c:if("shared+hint"===this.#e.lockPolicy&&!e.hint&&!await this.#l(e,"hint",D))return o;if(!await this.#l(e,"reserved",D))return e.hint?.(),o;e.access(),console.assert(!e.gate),console.assert(!e.access),console.assert(!!e.reserved);break;case l:if(!await this.#l(e,"gate"))return o;if(e.access(),!await this.#l(e,"access"))return e.gate(),o;console.assert(!!e.gate),console.assert(!!e.access),console.assert(!e.reserved);break;default:throw new Error("unsupported lock transition")}break;case c:if(s!==l)throw new Error("unsupported lock transition");if(!await this.#l(e,"gate"))return o;if(!await this.#l(e,"access"))return e.gate(),o;console.assert(!!e.gate),console.assert(!!e.access),console.assert(!!e.reserved)}return e.type=s,t}async#i(e,s){if(s===i)e.access?.(),e.gate?.(),e.reserved?.(),e.hint?.(),e.writeHint=!1,console.assert(!e.access),console.assert(!e.gate),console.assert(!e.reserved),console.assert(!e.hint);else switch(e.type){case l:e.access(),await this.#l(e,"access",F),e.gate(),e.reserved?.(),e.hint?.(),console.assert(!!e.access),console.assert(!e.gate),console.assert(!e.reserved);break;case c:await this.#l(e,"access",F),e.reserved(),e.hint?.(),console.assert(!!e.access),console.assert(!e.gate),console.assert(!e.reserved)}return e.type=s,t}async#c(e,s){return await this.#l(e,"reserved",M)?(e.reserved(),s.setInt32(0,0,!0)):s.setInt32(0,1,!0),t}#l(e,t,s={}){return console.assert(!e[t]),new Promise(a=>{if(!s.ifAvailable&&this.#e.lockTimeout<1/0){const e=new AbortController;s=Object.assign({},s,{signal:e.signal}),setTimeout(()=>{e.abort(),a?.(!1)},this.#e.lockTimeout)}const r=`lock##${e.baseName}##${t}`;navigator.locks.request(r,s,s=>{if(s)return new Promise(s=>{e[t]=()=>{s(),e[t]=null},a(!0),a=null});e[t]=null,a(!1),a=null}).catch(e=>{if("AbortError"!==e.name)throw e})})}};B.WRITE_HINT_OP_CODE=-9999;const _=new Set(["TransactionInactiveError","InvalidStateError"]);class A{path;flags;metadata;fileSize=0;needsMetadataSync=!1;rollback=null;changedPages=new Set;synchronous="full";txOptions={durability:"strict"};constructor(e,t,s){this.path=e,this.flags=t,this.metadata=s}}class W extends(B(e)){mapIdToFile=new Map;lastError=null;log=null;#h;#d;static async create(e,t,s){const a=new W(e,t,s);return await a.isReady(),a}constructor(e,t,s={}){super(e,t,s),this.#h=this.#u(s.idbName??e)}async#u(e){this.#d=await U.create(e)}close(){this.#d.close()}async isReady(){await super.isReady(),await this.#h}getFilename(e){const t=this.mapIdToFile.get(e).path;return`IDB(${this.name}):${t}`}async jOpen(e,s,a,r){try{const n=new URL(e||Math.random().toString(36).slice(2),"file://").pathname;let i=await this.#d.q(({metadata:e})=>e.get(n));if(!i&&a&d&&(i={name:n,fileSize:0,version:0},await this.#d.q(({metadata:e})=>e.put(i),"rw")),!i)throw new Error(`File ${n} not found`);const o=new A(n,a,i);return this.mapIdToFile.set(s,o),r.setInt32(0,a,!0),t}catch(e){return this.lastError=e,u}}async jDelete(e,s){try{const a=new URL(e,"file://").pathname;return this.#d.q(({metadata:e,blocks:t})=>{const s=IDBKeyRange.bound([a,-1/0],[a,1/0]);t.delete(s),e.delete(a)},"rw"),s&&await this.#d.sync(!1),t}catch(e){return this.lastError=e,p}}async jAccess(e,s,a){try{const s=new URL(e,"file://").pathname,r=await this.#d.q(({metadata:e})=>e.get(s));return a.setInt32(0,r?1:0,!0),t}catch(e){return this.lastError=e,y}}async jClose(e){try{const s=this.mapIdToFile.get(e);return this.mapIdToFile.delete(e),s.flags&g&&await this.#d.q(({metadata:e,blocks:t})=>{e.delete(s.path),t.delete(IDBKeyRange.bound([s.path,0],[s.path,1/0]))},"rw"),s.needsMetadataSync&&this.#d.q(({metadata:e})=>e.put(s.metadata),"rw"),await this.#d.sync("full"===s.synchronous),t}catch(e){return this.lastError=e,f}}async jRead(e,s,a){try{const r=this.mapIdToFile.get(e);let n=0;for(;n<s.byteLength;){const e=a+n,t=await this.#d.q(({blocks:t})=>{const s=IDBKeyRange.bound([r.path,-e],[r.path,1/0]);return t.get(s)});if(!t||t.data.byteLength-t.offset<=e)return s.fill(0,n),b;const i=s.subarray(n),o=e+t.offset,c=Math.min(Math.max(t.data.byteLength-o,0),i.byteLength);i.set(t.data.subarray(o,o+c)),n+=c}return t}catch(e){return this.lastError=e,w}}jWrite(e,s,a){try{const r=this.mapIdToFile.get(e);if(r.flags&m&&!r.rollback){const e=Object.assign({pendingVersion:r.metadata.version-1},r.metadata);this.#d.q(({metadata:t})=>t.put(e),"rw",r.txOptions),r.rollback=Object.assign({},r.metadata),r.metadata.version--}r.flags&m&&r.changedPages.add(a);const n=s.slice(),i=r.metadata.version;if(!(a<r.metadata.fileSize)||r.flags&m||r.flags&k){const e={path:r.path,offset:-a,version:i,data:s.slice()};this.#d.q(({blocks:t})=>{t.put(e),r.changedPages.add(a)},"rw",r.txOptions)}else this.#d.q(async({blocks:e})=>{const t=IDBKeyRange.bound([r.path,-a],[r.path,1/0]),s=await e.get(t);s.data.subarray(a+s.offset).set(n),e.put(s)},"rw",r.txOptions);return r.metadata.fileSize<a+s.length&&(r.metadata.fileSize=a+s.length,r.needsMetadataSync=!0),t}catch(e){return this.lastError=e,v}}jTruncate(e,s){try{const a=this.mapIdToFile.get(e);return s<a.metadata.fileSize&&(this.#d.q(({blocks:e})=>{const t=IDBKeyRange.bound([a.path,-1/0],[a.path,-s,1/0]);e.delete(t)},"rw",a.txOptions),a.metadata.fileSize=s,a.needsMetadataSync=!0),t}catch(e){return this.lastError=e,x}}async jSync(e,s){try{const s=this.mapIdToFile.get(e);return s.needsMetadataSync&&(this.#d.q(({metadata:e})=>e.put(s.metadata),"rw",s.txOptions),s.needsMetadataSync=!1),s.flags&m?"full"===s.synchronous&&await this.#d.sync(!0):await this.#d.sync("full"===s.synchronous),t}catch(e){return this.lastError=e,I}}jFileSize(e,s){try{const a=this.mapIdToFile.get(e);return s.setBigInt64(0,BigInt(a.metadata.fileSize),!0),t}catch(e){return this.lastError=e,S}}async jLock(e,t){const s=this.mapIdToFile.get(e),a=await super.jLock(e,t);return t===h&&(s.metadata=await this.#d.q(async({metadata:e,blocks:t})=>{const a=await e.get(s.path);return a.pendingVersion&&(console.warn(`removing failed transaction ${a.pendingVersion}`),await new Promise((e,s)=>{const r=IDBKeyRange.bound([a.name,-1/0],[a.name,1/0]),n=t.openCursor(r);n.onsuccess=()=>{const t=n.result;if(t){t.value.version<a.version&&t.delete(),t.continue()}else e()},n.onerror=()=>s(n.error)}),delete a.pendingVersion,e.put(a)),a},"rw",s.txOptions)),a}async jUnlock(e,t){if(t===i){const t=this.mapIdToFile.get(e);await this.#d.sync("full"===t.synchronous)}return super.jUnlock(e,t)}jFileControl(e,s,a){try{const r=this.mapIdToFile.get(e);switch(s){case O:const s=N(a,4),n=N(a,8);this.log?.("xFileControl",r.path,"PRAGMA",s,n);switch(s.toLowerCase()){case"page_size":if(r.flags&m&&n&&r.metadata.fileSize)return P;break;case"synchronous":if(n)switch(n.toLowerCase()){case"0":case"off":r.synchronous="off",r.txOptions={durability:"relaxed"};break;case"1":case"normal":r.synchronous="normal",r.txOptions={durability:"relaxed"};break;case"2":case"3":case"full":case"extra":r.synchronous="full",r.txOptions={durability:"strict"}}break;case"write_hint":return super.jFileControl(e,B.WRITE_HINT_OP_CODE,null)}break;case T:if(this.log?.("xFileControl",r.path,"SYNC"),r.rollback){const e=Object.assign({},r.metadata),t=r.rollback.fileSize;this.#d.q(({metadata:s,blocks:a})=>{s.put(e);for(const s of r.changedPages)if(s<t){const t=IDBKeyRange.bound([r.path,-s,e.version],[r.path,-s,1/0],!0);a.delete(t)}r.changedPages.clear()},"rw",r.txOptions),r.needsMetadataSync=!1,r.rollback=null}break;case j:return this.log?.("xFileControl",r.path,"BEGIN_ATOMIC_WRITE"),t;case q:return this.log?.("xFileControl",r.path,"COMMIT_ATOMIC_WRITE"),t;case E:this.log?.("xFileControl",r.path,"ROLLBACK_ATOMIC_WRITE"),r.metadata=r.rollback;const i=Object.assign({},r.metadata);return this.#d.q(({metadata:e,blocks:t})=>{e.put(i);for(const e of r.changedPages)t.delete([r.path,-e,i.version-1]);r.changedPages.clear()},"rw",r.txOptions),r.needsMetadataSync=!1,r.rollback=null,t}}catch(e){return this.lastError=e,C}return super.jFileControl(e,s,a)}jDeviceCharacteristics(e){return 0|R|L}jGetLastError(e){if(this.lastError){console.error(this.lastError);const t=e.subarray(0,e.byteLength-1),{written:s}=(new TextEncoder).encodeInto(this.lastError.message,t);e[s]=0}return t}}function N(e,t){const s=e.getUint32(t,!0);if(s){const t=new Uint8Array(e.buffer,s);return(new TextDecoder).decode(t.subarray(0,t.indexOf(0)))}return null}class U{#p;#y=null;#g=Promise.resolve();#f=null;#b=new WeakSet;log=null;static async create(e){const t=await new Promise((t,s)=>{const a=indexedDB.open(e,6);a.onupgradeneeded=async e=>{const t=a.result;switch(e.oldVersion&&console.log(`Upgrading IndexedDB from version ${e.oldVersion}`),e.oldVersion){case 0:t.createObjectStore("blocks",{keyPath:["path","offset","version"]}).createIndex("version",["path","version"]);case 5:const e=a.transaction;e.objectStore("blocks").deleteIndex("version");const s=t.createObjectStore("metadata",{keyPath:"name"});await new Promise((t,a)=>{let r={};const n=e.objectStore("blocks").openCursor();n.onsuccess=()=>{const e=n.result;if(e){const t=e.value;"number"!=typeof t.offset||t.path===r.path&&t.offset===r.offset?e.delete():0===t.offset&&(s.put({name:t.path,fileSize:t.fileSize,version:t.version}),delete t.fileSize,e.update(t)),r=t,e.continue()}else t()},n.onerror=()=>a(n.error)})}},a.onsuccess=()=>t(a.result),a.onerror=()=>s(a.error)});return new U(t)}constructor(e){this.#p=e}close(){this.#p.close()}q(e,t="ro",s={}){const a="ro"===t?"readonly":"readwrite",r=Object.assign({durability:"default"},s);return this.#y=(this.#y||Promise.resolve()).then(()=>this.#w(e,a,r)),this.#y}async#w(e,t,s){let a;this.#f&&this.#b.has(this.#f.transaction)&&this.#f.transaction.mode>=t&&this.#f.transaction.durability===s.durability&&(a=this.#f.transaction,"pending"===this.#f.readyState&&await new Promise(e=>{this.#f.addEventListener("success",e,{once:!0}),this.#f.addEventListener("error",e,{once:!0})}));for(let r=0;r<2;++r){a||(await this.#g,a=this.#p.transaction(this.#p.objectStoreNames,t,s),this.log?.("IDBTransaction open",t),this.#b.add(a),this.#g=new Promise((e,t)=>{a.addEventListener("complete",()=>{this.log?.("IDBTransaction complete"),this.#b.delete(a),e()}),a.addEventListener("abort",()=>{this.#b.delete(a),t(new Error("transaction aborted"))})}));try{const t=[...a.objectStoreNames].map(e=>[e,this.proxyStoreOrIndex(a.objectStore(e))]);return await e(Object.fromEntries(t))}catch(e){if(!r&&_.has(e.name)){this.log?.(`${e.name}, retrying`),a=null;continue}throw e}}}proxyStoreOrIndex(e){return new Proxy(e,{get:(e,t,s)=>{const a=Reflect.get(e,t,s);return"function"==typeof a?(...s)=>{const r=Reflect.apply(a,e,s);return r instanceof IDBRequest&&!t.endsWith("Cursor")?(this.#f=r,r.addEventListener("error",()=>{console.error(r.error),r.transaction.abort()},{once:!0}),n=r,new Promise((e,t)=>{n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})):r;var n}:a}})}async sync(e){this.#y&&(await this.#y,e&&await this.#g,this.reset())}reset(){this.#y=null,this.#g=Promise.resolve(),this.#f=null}}export{W as IDBBatchAtomicVFS,U as IDBContext};
//# sourceMappingURL=IDBBatchAtomicVFS-DbkDb777.js.map