@live-state/sync 0.0.7-pr-4 → 1.0.0-canary-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ var d="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var a;(function(e){e.Base32IncorrectEncoding="B32_ENC_INVALID",e.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",e.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",e.EncodeTimeNegative="ENC_TIME_NEG",e.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",e.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",e.PRNGDetectFailure="PRNG_DETECT",e.ULIDInvalid="ULID_INVALID",e.Unexpected="UNEXPECTED",e.UUIDInvalid="UUID_INVALID";})(a||(a={}));var c=class extends Error{constructor(t,n){super(`${n} (${t})`),this.name="ULIDError",this.code=t;}};function m(e){let t=Math.floor(e()*32);return t===32&&(t=31),d.charAt(t)}function E(e){let t=p(),n=t&&(t.crypto||t.msCrypto)||null;if(typeof(n==null?void 0:n.getRandomValues)=="function")return ()=>{let r=new Uint8Array(1);return n.getRandomValues(r),r[0]/255};if(typeof(n==null?void 0:n.randomBytes)=="function")return ()=>n.randomBytes(1).readUInt8()/255;throw new c(a.PRNGDetectFailure,"Failed to find a reliable PRNG")}function p(){return g()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function N(e,t){let n="";for(;e>0;e--)n=m(t)+n;return n}function I(e,t=10){if(isNaN(e))throw new c(a.EncodeTimeValueMalformed,`Time must be a number: ${e}`);if(e>0xffffffffffff)throw new c(a.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${0xffffffffffff}: ${e}`);if(e<0)throw new c(a.EncodeTimeNegative,`Time must be positive: ${e}`);if(Number.isInteger(e)===false)throw new c(a.EncodeTimeValueMalformed,`Time must be an integer: ${e}`);let n,r="";for(let o=t;o>0;o--)n=e%32,r=d.charAt(n)+r,e=(e-n)/32;return r}function g(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function T(e,t){let n=E(),r=Date.now();return I(r,10)+N(16,n)}var b=()=>T().toLowerCase();var D=(e,t)=>typeof e=="function"?e(t):e;var _=(e,t,n=[])=>new Proxy(e,{get:(r,o)=>{var f,l;if(o==="__isProxy__")return true;let i=(f=t.get)==null?void 0:f.call(t,r,[...n,o]);if(i!==void 0)return i;let s=r,u=o;return (l=s[u])!=null&&l.__isProxy__||(s[u]=_(typeof s[u]=="object"?s[u]:()=>{},t,[...n,o])),s[u]},apply:(r,o,i)=>{var s;return (s=t.apply)==null?void 0:s.call(t,r,n,i)}}),M=(e,t,n)=>{let r=[],o=0;for(let i=0;i<e.length&&(n===void 0||o<n);i++)t(e[i],i)&&(r.push(e[i]),o++);return r};export{b as a,D as b,_ as c,M as d};
package/dist/client.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { B as BootstrapStatusChangeEvent, F as Client, A as ClientBootstrapStatus, E as ClientEvents, C as ClientOptions, a as ClientRouterConstraint, l as ClientState, p as ClientStorageLoadedEvent, o as ConnectionStateChangeEvent, q as DataLoadReplyEvent, D as DataLoadRequestedEvent, M as MessageReceivedEvent, s as MutationReceivedEvent, t as MutationRejectedEvent, r as MutationSentEvent, e as OptimisticHandlerContext, y as OptimisticMutationAppliedEvent, z as OptimisticMutationUndoneEvent, O as OptimisticMutationsConfig, c as OptimisticMutationsRegistry, g as OptimisticOperation, f as OptimisticStorageProxy, Q as QueryExecutedEvent, w as QuerySubscriptionTriggeredEvent, x as StoreStateUpdatedEvent, S as SubscriptionCreatedEvent, v as SubscriptionRemovedEvent, G as createClient, d as defineOptimisticMutations, m as useClientState, u as useLiveQuery, n as useLoadData } from './index-C0Qm5yHg.js';
1
+ export { B as BootstrapStatusChangeEvent, F as Client, A as ClientBootstrapStatus, E as ClientEvents, C as ClientOptions, a as ClientRouterConstraint, l as ClientState, p as ClientStorageLoadedEvent, o as ConnectionStateChangeEvent, q as DataLoadReplyEvent, D as DataLoadRequestedEvent, M as MessageReceivedEvent, s as MutationReceivedEvent, t as MutationRejectedEvent, r as MutationSentEvent, e as OptimisticHandlerContext, y as OptimisticMutationAppliedEvent, z as OptimisticMutationUndoneEvent, O as OptimisticMutationsConfig, c as OptimisticMutationsRegistry, g as OptimisticOperation, f as OptimisticStorageProxy, Q as QueryExecutedEvent, w as QuerySubscriptionTriggeredEvent, x as StoreStateUpdatedEvent, S as SubscriptionCreatedEvent, v as SubscriptionRemovedEvent, G as createClient, d as defineOptimisticMutations, m as useClientState, u as useLiveQuery, n as useLoadData } from './index-DjBla1td.js';
2
2
  import '@standard-schema/spec';
3
3
  import 'zod';
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import {d,a,b as b$1,f,e,c}from'./chunk-LSAVBBUS.js';import {a as a$1}from'./chunk-RSSRYEM3.js';export{b as defineOptimisticMutations}from'./chunk-RSSRYEM3.js';import {useSyncExternalStore,useMemo,useEffect}from'react';import {xxHash32}from'js-xxhash';import {z}from'zod';import {stringify}from'qs';import Te from'fast-deep-equal';import {openDB}from'idb';var b=l=>xxHash32(JSON.stringify(l)).toString(32);var E=(l,e,t=false)=>Object.entries(e).every(([i,s])=>{if(i==="$and")return s.every(n=>E(l,n,t));if(i==="$or")return s.some(n=>E(l,n,t));let o=(s==null?void 0:s.$eq)!==void 0?s==null?void 0:s.$eq:s;if(typeof s=="object"&&s!==null&&(s==null?void 0:s.$eq)===void 0){if(s.$in!==void 0){let r=l[i];return r===void 0?false:t?!s.$in.includes(r):s.$in.includes(r)}if(s.$not!==void 0&&!t)return E(l,{[i]:s.$not},true);if(s.$gt!==void 0){let r=l[i];return typeof r!="number"?false:t?r<=s.$gt:r>s.$gt}if(s.$gte!==void 0){let r=l[i];return typeof r!="number"?false:t?r<s.$gte:r>=s.$gte}if(s.$lt!==void 0){let r=l[i];return typeof r!="number"?false:t?r>=s.$lt:r<s.$lt}if(s.$lte!==void 0){let r=l[i];return typeof r!="number"?false:t?r>s.$lte:r<=s.$lte}let n=l[i];return !n||typeof n!="object"&&!Array.isArray(n)?false:Array.isArray(n)?t?!n.some(r=>E(r,s,false)):n.some(r=>E(r,s,false)):E(n,s,t)}return t?l[i]!==o:l[i]===o}),I=l=>{if(typeof l!="object"||l===null)return false;let e=l;return "where"in e||"limit"in e||"orderBy"in e||"include"in e},T={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},U=class{level;prefix;constructor(e={}){this.level=e.level??T.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=T.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=T.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=T.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=T.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=T.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},F=l=>new U(l);var _=class{subscriptions=new Map;getOrStoreSubscription(e){let t=e.buildQueryRequest(),i=b(t);if(this.subscriptions.has(i))return this.subscriptions.get(i).subscribe;let s={subscribe:o=>{let n=this.subscriptions.get(i);return n.callbacks.add(o),n.unsubscribe||(n.unsubscribe=()=>{},n.unsubscribe=e.subscribe(()=>{n.callbacks.forEach(r=>{r();});})),()=>{var r;(r=this.subscriptions.get(i))==null||r.callbacks.delete(o),setTimeout(()=>{var c;let a=this.subscriptions.get(i);a&&a.callbacks.size===0&&((c=a.unsubscribe)==null||c.call(a),this.subscriptions.delete(i));},10);}},callbacks:new Set,unsubscribe:void 0};return this.subscriptions.set(i,s),this.subscriptions.get(i).subscribe}},pe=new _,we=l=>useSyncExternalStore(pe.getOrStoreSubscription(l),l.get),Ae=l=>{let{subscribe:e,getSnapshot:t}=useMemo(()=>{let i={bootstrapStatus:l.bootstrapStatus,connected:l.ws.connected()},s=()=>{let o={bootstrapStatus:l.bootstrapStatus,connected:l.ws.connected()};(o.bootstrapStatus!==i.bootstrapStatus||o.connected!==i.connected)&&(i=o);};return {subscribe:o=>l.addEventListener(n=>{(n.type==="BOOTSTRAP_STATUS_CHANGE"||n.type==="CONNECTION_STATE_CHANGE")&&(s(),o());}),getSnapshot:()=>i}},[l]);return useSyncExternalStore(e,t,t)},xe=(l,e)=>{useEffect(()=>{let t=l.load(e.buildQueryRequest());return ()=>{t();}},[e,l.load]);};var X=z.object({resource:z.string(),where:z.record(z.string(),z.any()).optional(),include:z.record(z.string(),z.any()).optional(),lastSyncedAt:z.string().optional(),limit:z.coerce.number().optional(),sort:z.array(z.object({key:z.string(),direction:z.enum(["asc","desc"])})).optional()}),Q=z.record(z.string(),z.object({value:z.any().nullable(),_meta:z.object({timestamp:z.string().optional().nullable()}).optional()})),he=Q.superRefine((l,e)=>{l.id&&e.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Z=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string(),resourceId:z.string().optional()}),ee=z.object({timestamp:z.string().optional(),originMutationId:z.string().optional()}).optional(),N=Z.extend({procedure:z.string(),payload:z.any().optional(),meta:ee}),B=Z.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:he,meta:ee});z.union([B,N]);var te=z.object({resource:z.string(),procedure:z.string(),input:z.any().optional()});var O=z.string(),W=z.union([te,X]),ye=z.object({id:O,type:z.literal("SUBSCRIBE")}).and(W),me=z.object({id:O,type:z.literal("UNSUBSCRIBE")}).and(W),ge=z.object({id:O,type:z.literal("QUERY")}).and(W),fe=z.object({id:O,type:z.literal("CUSTOM_QUERY"),resource:z.string(),procedure:z.string(),input:z.any().optional()}),ie=B.extend({id:O}),be=N.extend({id:O}),Me=z.union([be,ie]);z.union([ye,ge,fe,Me,me]);var Se=z.object({id:O,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),ve=z.object({id:O,type:z.literal("REPLY"),data:z.any()}),se=z.union([Se,ve,ie]),ne=z.object({resource:z.string(),data:z.array(Q)});var x=class{ws=null;url;autoConnect;autoReconnect;reconnectTimeout;reconnectLimit;reconnectAttempts=0;eventListeners=new Map;reconnectTimer=null;intentionallyDisconnected=false;credentials;constructor(e){this.url=e.url,this.autoConnect=e.autoConnect??false,this.autoReconnect=e.autoReconnect??false,this.reconnectTimeout=e.reconnectTimeout??5e3,this.reconnectLimit=e.reconnectLimit,this.credentials=e.credentials,this.autoConnect&&this.connect();}connected(){var e;return ((e=this.ws)==null?void 0:e.readyState)===WebSocket.OPEN}async connect(){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;this.intentionallyDisconnected=false;let e=await c(this.credentials);this.ws=new WebSocket(this.url+(e?`?${stringify(e)}`:"")),this.ws.addEventListener("open",this.handleOpen.bind(this)),this.ws.addEventListener("close",this.handleClose.bind(this)),this.ws.addEventListener("error",this.handleError.bind(this)),this.ws.addEventListener("message",this.handleMessage.bind(this));}disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.intentionallyDisconnected=true,this.ws&&(this.ws.close(),this.ws=null);}addEventListener(e,t){var i;this.eventListeners.has(e)||this.eventListeners.set(e,new Set),(i=this.eventListeners.get(e))==null||i.add(t);}removeEventListener(e,t){var i;this.eventListeners.has(e)&&((i=this.eventListeners.get(e))==null||i.delete(t));}send(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e);else throw new Error("WebSocket is not open")}handleOpen(e){this.reconnectAttempts=0,this.dispatchEvent("open",e),this.dispatchEvent("connectionChange",{open:true});}handleClose(e){this.dispatchEvent("close",e),this.dispatchEvent("connectionChange",{open:false}),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect();}handleError(e){var t,i;this.dispatchEvent("error",e),this.dispatchEvent("connectionChange",{open:false}),(i=(t=e.error)==null?void 0:t.message)!=null&&i.includes("non-101")&&(this.ws&&(this.ws.close(),this.ws=null),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect());}handleMessage(e){this.dispatchEvent("message",e);}scheduleReconnect(){this.reconnectLimit&&this.reconnectAttempts>=this.reconnectLimit||(this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.connect();},this.reconnectTimeout));}dispatchEvent(e,t){var i;(i=this.eventListeners.get(e))==null||i.forEach(s=>{s(t);});}};var k=class{constructor(e){this.logger=e;this.nodes=new Map;}nodes;createNode(e,t,i){if(this.nodes.has(e))throw new Error(`Node with id ${e} already exists`);let s={id:e,type:t,referencedBy:new Map(i.map(o=>[o,new Set])),references:new Map,subscriptions:new Set};return this.nodes.set(e,s),s}getNode(e){return this.nodes.get(e)}hasNode(e){return this.nodes.has(e)}createLink(e,t){let i=this.nodes.get(e),s=this.nodes.get(t);if(!i)throw new Error(`Source node with id ${e} does not exist`);if(!s)throw new Error(`Target node with id ${t} does not exist`);i.references.set(s.type,t);let o=s.referencedBy.get(i.type);o&&o instanceof Set?o.add(e):s.referencedBy.set(i.type,e),this.notifySubscribers(t);}removeLink(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);let s=i.references.get(t);if(!s)return;i.references.delete(t);let o=this.nodes.get(s);if(!o)return;let n=o.referencedBy.get(i.type);n&&(n instanceof Set?n.delete(e):o.referencedBy.delete(i.type),this.notifySubscribers(s)),this.notifySubscribers(e);}subscribe(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);return i.subscriptions.add(t),()=>{i.subscriptions.delete(t);}}removeNode(e){let t=this.nodes.get(e);t&&(Array.from(t.referencedBy.entries()).forEach(([i,s])=>{(s instanceof Set?Array.from(s.values()):[s]).forEach(n=>{let r=this.nodes.get(n);!r||!r.references.get(i)||(r.references.delete(i),this.notifySubscribers(n));});}),this.nodes.delete(e));}updateNode(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);t(i),this.notifySubscribers(e);}notifySubscribers(e){let t=this.nodes.get(e);t&&Array.from(t.subscriptions).forEach(i=>{var s;try{i(e);}catch(o){(s=this.logger)==null||s.error(`Error in node subscription for node ${e}:`,o);}});}getAllNodes(){return Array.from(this.nodes.values())}};var q="__meta",L="databases",j=class{db;async init(e,t){var c,p;if(typeof window>"u")return;let s=((c=(await window.indexedDB.databases()).find(u=>u.name===t))==null?void 0:c.version)??1,o=await b(e),n=Object.fromEntries(await Promise.all(Object.entries(e).map(async([u,d])=>[u,await b(d)]))),r=await openDB("live-state-databases",1,{upgrade(u){u.objectStoreNames.contains(L)||u.createObjectStore(L);}}),a=(p=await this.getAll(r,L))==null?void 0:p[t];(a==null?void 0:a.schemaHash)!==o&&s++,this.db=await openDB(t,s,{async upgrade(u){[...Object.keys(e),q].forEach(d=>{(a==null?void 0:a.objectHashes[d])!==n[d]&&u.objectStoreNames.contains(d)&&u.deleteObjectStore(d),u.objectStoreNames.contains(d)||u.createObjectStore(d);}),await r.put(L,{schemaHash:o,objectHashes:n},t);},blocking(){window.location.reload();},blocked(){window.location.reload();}});}async get(e){return await this.getAll(this.db,e)??{}}getOne(e,t){return this.db?this.db.get(e,t):new Promise(i=>i(void 0))}set(e,t,i){var s;return (s=this.db)==null?void 0:s.put(e,i,t)}delete(e,t){var i;return (i=this.db)==null?void 0:i.delete(e,t)}getMeta(e){return this.db?this.db.get(q,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(q,t,e)}async getAll(e,t){if(!e)return;if(e.getAllRecords)return e.getAllRecords(t);let[i,s]=await Promise.all([e.getAll(t),e.getAllKeys(t)]);return Object.fromEntries(i.map((o,n)=>[s[n],o]))}};var P=class{constructor(e,t,i,s,o,n){this.schema=e;this.logger=i,this.optimisticObjGraph=new k(i),this.kvStorage=new j,this.onQuerySubscriptionTriggered=n,t!==false&&this.kvStorage.init(this.schema,t.name).then(()=>{Promise.all([this.kvStorage.getMeta("mutationStack"),this.kvStorage.getMeta("customMutationStack"),this.kvStorage.getMeta("customMutationIndex")]).then(([r,a,c])=>{r&&Object.keys(r).length>0&&(this.optimisticMutationStack=r),a&&a.length>0&&(this.customMutationStack=a),c&&Object.keys(c).length>0&&(this.customMutationIndex=c),s==null||s(this.optimisticMutationStack,this.customMutationStack,this.customMutationIndex);}).then(()=>{Object.entries(this.schema).forEach(([r])=>{this.kvStorage.get(r).then(a=>{if(!a||Object.keys(a).length===0){o==null||o(r,0);return}let c=Object.entries(a).map(([p,u])=>({...u,id:{value:p}}));o==null||o(r,c.length),this.loadConsolidatedState(r,c);});});}).catch(r=>{i.debug("Storage initialization failed (may not be available in this environment):",r);});});}rawObjPool={};optimisticMutationStack={};customMutationStack=[];optimisticObjGraph;optimisticRawObjPool={};logger;onQuerySubscriptionTriggered;customMutationIndex={};collectionSubscriptions=new Map;querySnapshots={};kvStorage;get(e$1,t,i=false){var a;let s=t??b(e$1);if(this.querySnapshots[s]&&!i){let c=this.querySnapshots[s];if(c)return c}let o,n=(a=e$1.where)==null?void 0:a.id;n===void 0?o=Object.keys(this.optimisticRawObjPool[e$1.resource]??{}):typeof n=="string"?o=[n]:typeof n=="object"&&n!==null?"$in"in n&&Array.isArray(n.$in)?o=n.$in:"$eq"in n&&typeof n.$eq=="string"?o=[n.$eq]:o=Object.keys(this.optimisticRawObjPool[e$1.resource]??{}):o=Object.keys(this.optimisticRawObjPool[e$1.resource]??{});let r=o.flatMap(c=>{let p=f(this.materializeOneWithInclude(c,e$1.include));return p?[p]:[]});if(e$1.sort&&e$1.sort.length>0){let c=(p,u)=>{for(let d of e$1.sort){let y=p[d.key],g=u[d.key];if(y<g)return d.direction==="asc"?-1:1;if(y>g)return d.direction==="asc"?1:-1}return 0};r.sort(c);}if(e$1.where||e$1.limit){let c=e$1.where?p=>E(p,e$1.where):()=>true;r=e(r,c,e$1.limit);}return !i&&this.collectionSubscriptions.has(s)&&(this.querySnapshots[s]=r),r}subscribe(e,t){var o;let i=b(e);return this.collectionSubscriptions.get(i)||this.collectionSubscriptions.set(i,{callbacks:new Set,query:e,flatInclude:e.include?this.flattenIncludes(e.include,e.resource):void 0}),(o=this.collectionSubscriptions.get(i))==null||o.callbacks.add(t),()=>{var n,r;(n=this.collectionSubscriptions.get(i))==null||n.callbacks.delete(t),((r=this.collectionSubscriptions.get(i))==null?void 0:r.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var n,r,a,c,p,u,d;let s=this.schema[e];if(this.logger.debug("Adding mutation",t),!s)throw new Error("Schema not found");let o=(n=this.optimisticRawObjPool[e])==null?void 0:n[t.resourceId];if(i)this.optimisticMutationStack[e]??=[],this.optimisticMutationStack[e].push(t);else {this.optimisticMutationStack[e]=((a=(r=this.optimisticMutationStack)==null?void 0:r[e])==null?void 0:a.filter(M=>M.id!==t.id))??[];let y=(c=t.meta)==null?void 0:c.originMutationId;if(this.logger.debug("Broadcast mutation received",{mutationId:t.id,resource:e,resourceId:t.resourceId,procedure:t.procedure,originMutationId:y??"(none)",customMutationIndexKeys:Object.keys(this.customMutationIndex),optimisticStackSize:((p=this.optimisticMutationStack[e])==null?void 0:p.length)??0}),y&&this.customMutationIndex[y]){let w=this.customMutationIndex[y].filter(S=>S.resource===e),C=false;for(let S of w){let R=(u=this.optimisticMutationStack[e])==null?void 0:u.find(A=>A.id===S.mutationId);if(R&&R.resourceId===t.resourceId&&R.procedure===t.procedure){this.logger.debug("Removing optimistic mutation (resourceId match)",{optimisticMutationId:S.mutationId,resourceId:t.resourceId}),this.undoMutation(e,S.mutationId),C=true;break}}if(!C)for(let S of w){let R=(d=this.optimisticMutationStack[e])==null?void 0:d.find(A=>A.id===S.mutationId&&A.procedure===t.procedure);if(R){this.logger.debug("Removing optimistic mutation (resource+procedure fallback)",{optimisticMutationId:S.mutationId,optimisticResourceId:R.resourceId,broadcastResourceId:t.resourceId}),this.undoMutation(e,S.mutationId),C=true;break}}}this.rawObjPool[e]??={};let g={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=g;let f=g.value;delete f.id,this.kvStorage.set(e,t.resourceId,f);}this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,t.resourceId,t.payload,o);}undoMutation(e,t){var n,r;if(!this.optimisticMutationStack[e])return;let i=(n=this.optimisticMutationStack[e])==null?void 0:n.findIndex(a=>a.id===t);if(i===-1)return;let s=this.optimisticMutationStack[e][i];this.logger.debug("Removing mutation",s);let o=(r=this.optimisticRawObjPool[e])==null?void 0:r[s.resourceId];this.optimisticMutationStack[e].splice(i,1),this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,s.resourceId,Object.fromEntries(Object.entries(s.payload).map(([a])=>[a,{value:null,_meta:{}}])),o);}addCustomMutationMessage(e){this.customMutationStack.push(e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack);}registerCustomMutation(e,t){this.customMutationIndex[e]=t,this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex);}confirmCustomMutation(e){var i;let t=this.customMutationIndex[e];if(this.logger.debug("confirmCustomMutation called",{messageId:e,hasIndex:!!t,mutations:t??[]}),!!t){for(let{resource:s,mutationId:o}of t){let n=!!((i=this.optimisticMutationStack[s])!=null&&i.find(r=>r.id===o));this.logger.debug("confirmCustomMutation: undoing mutation",{resource:s,mutationId:o,stillInStack:n}),this.undoMutation(s,o);}delete this.customMutationIndex[e],this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex),this.customMutationStack=this.customMutationStack.filter(s=>s.id!==e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack);}}undoCustomMutation(e){var s;let t=this.customMutationIndex[e];if(!t)return [];let i=[];for(let{resource:o,mutationId:n}of t){let r=(s=this.optimisticMutationStack[o])==null?void 0:s.find(a=>a.id===n);this.undoMutation(o,n),r&&i.push({resource:o,mutationId:n,resourceId:r.resourceId});}return delete this.customMutationIndex[e],this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex),this.customMutationStack=this.customMutationStack.filter(o=>o.id!==e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack),i}getCustomMutationMutationIds(){let e=new Set;for(let t of Object.values(this.customMutationIndex))for(let{mutationId:i}of t)e.add(i);return e}loadConsolidatedState(e,t){t.forEach(i=>{var r;let s=(r=i.id)==null?void 0:r.value;if(!s)return;let{cleanedPayload:o,nestedMutations:n}=this.extractNestedRelations(e,i);n.forEach(a=>{this.addMutation(a.resource,a);}),this.addMutation(e,{id:s,type:"MUTATE",resource:e,resourceId:s,procedure:"INSERT",payload:o});});}extractNestedRelations(e,t){let i=this.schema[e],s={...t},o=[];return i!=null&&i.relations?(Object.entries(t).forEach(([n,r])=>{var u;let a=i.relations[n];if(!a)return;let c=a.entity.name,p=r==null?void 0:r.value;if(a.type==="one"){if(p&&typeof p=="object"&&!Array.isArray(p)&&((u=p.id)!=null&&u.value)){let d=p.id.value,y={...p},{cleanedPayload:g,nestedMutations:f}=this.extractNestedRelations(c,y);o.push(...f),o.push({id:d,type:"MUTATE",resource:c,resourceId:d,procedure:"INSERT",payload:g}),delete s[n];}}else a.type==="many"&&Array.isArray(p)&&(p.forEach(d=>{var y,g;if(d&&typeof d=="object"&&!Array.isArray(d)&&((g=(y=d.value)==null?void 0:y.id)!=null&&g.value)){let f=d.value.id.value,M={...d.value},{cleanedPayload:w,nestedMutations:C}=this.extractNestedRelations(c,M);o.push(...C),o.push({id:f,type:"MUTATE",resource:c,resourceId:f,procedure:"INSERT",payload:w});}}),delete s[n]);}),{cleanedPayload:s,nestedMutations:o}):{cleanedPayload:s,nestedMutations:o}}updateRawObjPool(e,t,i,s){var r;if(!this.schema[e])return;let o=(r=this.rawObjPool[e])==null?void 0:r[t],n=(this.optimisticMutationStack[e]??[]).reduce((a,c)=>c.resourceId!==t?a:this.schema[e].mergeMutation("set",c.payload,a)[0],o);if(this.optimisticRawObjPool[e]??={},n?this.optimisticRawObjPool[e][t]={value:{...n.value,id:{value:t}}}:delete this.optimisticRawObjPool[e][t],!(!this.optimisticObjGraph.hasNode(t)&&!n)){if(this.optimisticObjGraph.hasNode(t)||this.optimisticObjGraph.createNode(t,e,Object.values(this.schema[e].relations).flatMap(a=>a.type==="many"?[a.entity.name]:[])),Object.keys(this.schema[e].relations).length>0){let a=Object.fromEntries(Object.entries(this.schema[e].relations).flatMap(([c,p])=>p.type==="one"?[[p.relationalColumn,c]]:[]));Object.entries(i).forEach(([c,p])=>{let u=this.schema[e].relations[a[c]];if(!a[c])return;let d=s==null?void 0:s.value[c],[,y]=u.mergeMutation("set",p,d);if(y){if(!this.optimisticObjGraph.hasNode(y.value)){let g=u.entity.name;this.optimisticObjGraph.createNode(y.value,g,Object.values(this.schema[g].relations).flatMap(f=>f.type==="many"?[f.entity.name]:[]));}d!=null&&d.value&&this.optimisticObjGraph.removeLink(t,u.entity.name),this.optimisticObjGraph.createLink(t,y.value);}});}this.notifyCollectionSubscribers(e),this.optimisticObjGraph.notifySubscribers(t);}}materializeOneWithInclude(e,t={}){var a;if(!e)return;let i=this.optimisticObjGraph.getNode(e);if(!i)return;let s=i.type,o=(a=this.optimisticRawObjPool[s])==null?void 0:a[e];if(!o)return;let[n,r]=Object.entries(t).reduce((c,[p,u])=>{let d=this.schema[s].relations[p];return d&&(d.type==="one"?c[0].push([p,d.entity.name,u??true]):d.type==="many"&&c[1].push([p,d.entity.name,u??true])),c},[[],[]]);return {value:{...o.value,...Object.fromEntries(n.map(([c,p,u])=>[c,this.materializeOneWithInclude(i.references.get(p),I(u)?u.include??{}:typeof u=="object"&&u!==null?u:{})])),...Object.fromEntries(r.map(([c,p,u])=>{let d=i.referencedBy.get(p),y=d instanceof Set;return [c,y?{value:Array.from(d.values()).map(g=>this.materializeOneWithInclude(g,I(u)?u.include??{}:typeof u=="object"&&u!==null?u:{}))}:this.materializeOneWithInclude(d,I(u)?u.include??{}:typeof u=="object"&&u!==null?u:{})]}))}}}notifyCollectionSubscribers(e){this.collectionSubscriptions.forEach(t=>{var i,s;if(t.query.resource===e||(i=t.flatInclude)!=null&&i.includes(e)){let o=b(t.query),n=this.querySnapshots[o],r=this.get(t.query,void 0,true);if(Te(r,n))return;this.querySnapshots[o]=r,(s=this.onQuerySubscriptionTriggered)==null||s.call(this,t.query),t.callbacks.forEach(a=>{a(r);});}});}flattenIncludes(e,t){let i=[];return Object.entries(e).forEach(([s,o])=>{var a;let n=(a=this.schema[t])==null?void 0:a.relations[s];if(!n)return;let r=n.entity.name;if(i.push(r),typeof o=="object"&&o!==null){let c=I(o)?o.include??{}:o;i.push(...this.flattenIncludes(c,r));}}),Array.from(new Set(i))}};var re=l=>{if(l instanceof Error&&l.message.includes("Unknown procedure"))return true;if(l instanceof Error&&typeof l.cause=="object"&&l.cause!==null&&"message"in l.cause){let e=l.cause.message;return typeof e=="string"&&e.includes("Unknown procedure")}return false},ae={pending:0,local:1,remote:2},D=class{constructor(e,t){this.client=e;this.query=t;}buildQueryRequest(){return this.query}then(e,t){return this.client.genericQuery(this.query.resource,this.query.procedure,this.query.input).then(e,t)}},$=class{url;ws;store;logger;optimisticMutations;remoteSubscriptions=new Map;eventListeners=new Set;replyHandlers={};_bootstrapStatus="pending";storageLoadedCount=0;expectedStorageLoads;constructor(e){var t,i,s,o;this.url=e.url,this.logger=F({level:e.logLevel??T.INFO}),this.optimisticMutations=e.optimisticMutations,this.expectedStorageLoads=e.storage===false?0:Object.keys(e.schema).length,this.store=new P(e.schema,e.storage,this.logger,(n,r,a)=>{var p,u;let c=new Set;if(a)for(let d of Object.values(a))for(let{mutationId:y}of d)c.add(y);(u=(p=Object.values(n))==null?void 0:p.flat())==null||u.forEach(d=>{c.has(d.id)||this.sendWsMessage(d);}),this.replayCustomMutationStack();},(n,r)=>{this.emitEvent({type:"CLIENT_STORAGE_LOADED",resource:n,itemCount:r}),this.storageLoadedCount+=1,this.expectedStorageLoads>0&&this.storageLoadedCount>=this.expectedStorageLoads&&this.setBootstrapStatus("local");},n=>{this.emitEvent({type:"QUERY_SUBSCRIPTION_TRIGGERED",query:n});}),this.ws=new x({url:e.url,autoConnect:((t=e.connection)==null?void 0:t.autoConnect)??true,autoReconnect:((i=e.connection)==null?void 0:i.autoReconnect)??true,reconnectTimeout:((s=e.connection)==null?void 0:s.reconnectTimeout)??5e3,reconnectLimit:(o=e.connection)==null?void 0:o.maxReconnectAttempts,credentials:e.credentials}),this.ws.addEventListener("message",n=>{this.handleServerMessage(n.data);}),this.ws.addEventListener("connectionChange",n=>{if(this.emitEvent({type:"CONNECTION_STATE_CHANGE",open:n.open}),n.open){Array.from(this.remoteSubscriptions.values()).forEach(({query:a})=>{this.sendWsMessage({id:b$1(),type:"SUBSCRIBE",...a});});let r=this.store.getCustomMutationMutationIds();Object.values(this.store.optimisticMutationStack).forEach(a=>{a&&a.forEach(c=>{r.has(c.id)||(this.emitEvent({type:"MUTATION_SENT",mutationId:c.id,resource:c.resource,resourceId:c.resourceId,procedure:c.procedure??"UNKNOWN",optimistic:true}),this.sendWsMessage(c));});}),this.replayCustomMutationStack();}});}get(e){let t=this.store.get(e);return this.emitEvent({type:"QUERY_EXECUTED",query:e,resultCount:Array.isArray(t)?t.length:t?1:0}),t}handleServerMessage(e){var t,i,s,o;try{this.logger.debug("Message received from the server:",e);let n=se.parse(JSON.parse(e));if(this.logger.debug("Parsed message:",n),this.emitEvent({type:"MESSAGE_RECEIVED",message:n}),n.type==="MUTATE"){let{resource:r,id:a,resourceId:c,procedure:p}=n;this.emitEvent({type:"MUTATION_RECEIVED",mutationId:a,resource:r,resourceId:c,procedure:p??"UNKNOWN"});try{this.store.addMutation(r,n);}catch(u){this.logger.error("Error merging mutation from the server:",u);}}else if(n.type==="REJECT"){if(this.replyHandlers[n.id]){clearTimeout(this.replyHandlers[n.id].timeoutHandle),this.emitUndoEvents(this.store.undoCustomMutation(n.id));let c=n.message??"Mutation rejected";(i=(t=this.replyHandlers[n.id]).reject)==null||i.call(t,new Error(c)),delete this.replyHandlers[n.id];}let r=((s=this.store.optimisticMutationStack[n.resource])==null?void 0:s.length)??0,a=(o=this.store.optimisticMutationStack[n.resource])==null?void 0:o.find(c=>c.id===n.id);this.store.undoMutation(n.resource,n.id),this.emitEvent({type:"MUTATION_REJECTED",mutationId:n.id,resource:n.resource}),a&&this.emitEvent({type:"OPTIMISTIC_MUTATION_UNDONE",mutationId:n.id,resource:n.resource,resourceId:a.resourceId,pendingMutations:r-1});}else if(n.type==="REPLY"){let{id:r,data:a}=n;if(this.replyHandlers[r]){clearTimeout(this.replyHandlers[r].timeoutHandle),this.replyHandlers[r].handler(a);return}let c=ne.parse(a);this.emitEvent({type:"DATA_LOAD_REPLY",resource:c.resource,itemCount:c.data.length}),this.store.loadConsolidatedState(c.resource,c.data),this.emitEvent({type:"STORE_STATE_UPDATED",resource:c.resource,itemCount:c.data.length}),this.setBootstrapStatus("remote");}}catch(n){this.logger.error("Error parsing message from the server:",n);}}load(e){let t=b$1(),i=b(e);this.emitEvent({type:"DATA_LOAD_REQUESTED",query:e,subscriptionId:t}),this.sendWsMessage({id:t,type:"SUBSCRIBE",...e});let s=!this.remoteSubscriptions.has(i);return this.remoteSubscriptions.has(i)?this.remoteSubscriptions.get(i).subCounter+=1:this.remoteSubscriptions.set(i,{query:e,subCounter:1}),s&&this.emitEvent({type:"SUBSCRIPTION_CREATED",query:e,subscriptionKey:i,subscriberCount:1}),()=>{if(this.remoteSubscriptions.has(i)){let o=this.remoteSubscriptions.get(i);o.subCounter-=1,this.remoteSubscriptions.get(i).subCounter<=0&&(this.remoteSubscriptions.delete(i),this.sendWsMessage({id:b$1(),type:"UNSUBSCRIBE",...e}),this.emitEvent({type:"SUBSCRIPTION_REMOVED",query:e,subscriptionKey:i}));}}}subscribe(e,t){return this.store.subscribe(e,t)}mutate(e,t,i,s){var r,a;let o={id:b$1(),type:"MUTATE",resource:e,payload:this.store.schema[e].encodeMutation("set",s,new Date().toISOString()),resourceId:t,procedure:i},n=(((r=this.store.optimisticMutationStack[e])==null?void 0:r.length)??0)+1;(a=this.store)==null||a.addMutation(e,o,true),this.emitEvent({type:"OPTIMISTIC_MUTATION_APPLIED",mutationId:o.id,resource:e,resourceId:t,procedure:i,pendingMutations:n}),this.emitEvent({type:"MUTATION_SENT",mutationId:o.id,resource:e,resourceId:t,procedure:i,optimistic:true}),this.sendWsMessage(o);}genericMutate(e,t,i){var c,p,u,d;let s=(c=this.ws)==null?void 0:c.connected(),o=(p=this.optimisticMutations)==null?void 0:p.getHandler(e,t),r=(t==="insert"||t==="update")&&!o&&this.store.schema[e]?(()=>{let y=i??{},{id:g,...f}=y;if(typeof g=="string")try{let M=this.store.schema[e].encodeMutation("set",f,new Date().toISOString());return {id:g,input:f,encoded:M}}catch{return}})():void 0;if(!s&&!o&&!r)throw new Error("WebSocket not connected");let a={id:b$1(),type:"MUTATE",resource:e,procedure:t,payload:i,meta:{timestamp:new Date().toISOString()}};if(r){let y={id:a.id,type:"MUTATE",resource:e,resourceId:r.id,procedure:t==="insert"?"INSERT":"UPDATE",payload:r.encoded};(u=this.store)==null||u.addMutation(e,y,true),this.emitEvent({type:"OPTIMISTIC_MUTATION_APPLIED",mutationId:a.id,resource:e,resourceId:r.id,procedure:y.procedure,pendingMutations:((d=this.store.optimisticMutationStack[e])==null?void 0:d.length)??0}),this.emitEvent({type:"MUTATION_SENT",mutationId:a.id,resource:e,resourceId:r.id,procedure:t,optimistic:true});}else if(o)try{let{proxy:y,getOperations:g}=a$1(this.store,this.store.schema);o({input:i,storage:y});let f=g(),M=this.applyOptimisticOperations(f);this.store.registerCustomMutation(a.id,M),this.emitEvent({type:"MUTATION_SENT",mutationId:a.id,resource:e,resourceId:"",procedure:t,optimistic:!0});}catch(y){throw this.logger.error("Error executing optimistic handler:",y),this.emitUndoEvents(this.store.undoCustomMutation(a.id)),y}else this.emitEvent({type:"MUTATION_SENT",mutationId:a.id,resource:e,resourceId:"",procedure:t,optimistic:false});return s?(this.sendWsMessage(a),new Promise((y,g)=>{this.replyHandlers[a.id]={timeoutHandle:setTimeout(()=>{var f;if(delete this.replyHandlers[a.id],r){let M=((f=this.store.optimisticMutationStack[e])==null?void 0:f.length)??0;this.store.undoMutation(e,a.id),this.emitEvent({type:"OPTIMISTIC_MUTATION_UNDONE",mutationId:a.id,resource:e,resourceId:r.id,pendingMutations:Math.max(M-1,0)});}else this.emitUndoEvents(this.store.undoCustomMutation(a.id));g(new Error("Reply timeout"));},5e3),handler:f=>{delete this.replyHandlers[a.id],r||this.store.confirmCustomMutation(a.id),y(f);},reject:g};})):(this.store.addCustomMutationMessage(a),Promise.resolve(void 0))}applyOptimisticOperations(e){var i;let t=[];try{for(let s of e){let o=b$1(),n=new Date().toISOString(),r={id:o,type:"MUTATE",resource:s.resource,resourceId:s.id,procedure:s.type==="insert"?"INSERT":"UPDATE",payload:this.store.schema[s.resource].encodeMutation("set",s.data,n)},a=(((i=this.store.optimisticMutationStack[s.resource])==null?void 0:i.length)??0)+1;this.store.addMutation(s.resource,r,!0),t.push({resource:s.resource,mutationId:o}),this.emitEvent({type:"OPTIMISTIC_MUTATION_APPLIED",mutationId:o,resource:s.resource,resourceId:s.id,procedure:s.type==="insert"?"INSERT":"UPDATE",pendingMutations:a});}return t}catch(s){for(let{resource:o,mutationId:n}of t)this.store.undoMutation(o,n);throw s}}emitUndoEvents(e){var t;for(let{resource:i,mutationId:s,resourceId:o}of e){let n=((t=this.store.optimisticMutationStack[i])==null?void 0:t.length)??0;this.emitEvent({type:"OPTIMISTIC_MUTATION_UNDONE",mutationId:s,resource:i,resourceId:o,pendingMutations:n});}}genericQuery(e,t,i){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let s={id:b$1(),type:"CUSTOM_QUERY",resource:e,procedure:t,input:i};return this.sendWsMessage(s),new Promise((o,n)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],n(new Error("Reply timeout"));},5e3),handler:r=>{delete this.replyHandlers[s.id],o(r);},reject:n};})}get bootstrapStatus(){return this._bootstrapStatus}setBootstrapStatus(e){ae[e]<=ae[this._bootstrapStatus]||(this._bootstrapStatus=e,this.emitEvent({type:"BOOTSTRAP_STATUS_CHANGE",bootstrapStatus:e}));}addEventListener(e){return this.eventListeners.add(e),()=>{this.eventListeners.delete(e);}}replayCustomMutationStack(){var e;if((e=this.ws)!=null&&e.connected())for(let t of this.store.customMutationStack)this.sendWsMessage(t),!this.replyHandlers[t.id]&&(this.replyHandlers[t.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[t.id],this.emitUndoEvents(this.store.undoCustomMutation(t.id));},5e3),handler:()=>{delete this.replyHandlers[t.id],this.store.confirmCustomMutation(t.id);}});}sendWsMessage(e){var t;(t=this.ws)!=null&&t.connected()&&this.ws.send(JSON.stringify(e));}emitEvent(e){this.eventListeners.forEach(t=>{t(e);});}},at=l=>{let e=new $(l),t=(i,s)=>new Proxy(s,{get(o,n,r){if(n in o)return Reflect.get(o,n,r);if(typeof n=="string")return a=>new D(e,{resource:i,procedure:n,input:a})}});return {client:{ws:e.ws,get bootstrapStatus(){return e.bootstrapStatus},load:i=>e.load(i),addEventListener:i=>e.addEventListener(i)},store:{query:new Proxy({},{get(i,s){if(typeof s=="string")return Object.hasOwn(l.schema,s)?t(s,a._init(l.schema[s],e)):new Proxy({},{get(o,n){if(typeof n=="string")return r=>new D(e,{resource:s,procedure:n,input:r})}})},has(i,s){return typeof s=="string"}}),mutate:d(()=>{},{apply:(i,s,o)=>{if(s.length<2)return;if(s.length>2)throw new Error("Trying to access an invalid path");let[n,r]=s;if(r==="insert")return e.genericMutate(n,r,o[0]).catch(a=>{if(!re(a))throw a;let{id:c,...p}=o[0]??{};return e.mutate(n,c,"INSERT",p)});if(r==="update"){let a=o.length>1&&typeof o[0]=="string"&&typeof o[1]=="object"&&o[1]!==null?{id:o[0],...o[1]}:o[0];return e.genericMutate(n,r,a).catch(c=>{var d;if(!re(c))throw c;let[p,u]=o.length>1?o:[(d=o[0])==null?void 0:d.id,o[0]];return e.mutate(n,p,"UPDATE",u)})}return e.genericMutate(n,r,o[0])}})}}};export{at as createClient,Ae as useClientState,we as useLiveQuery,xe as useLoadData};
1
+ import {c,a,d,b}from'./chunk-YPTDCIAN.js';import {a as a$1}from'./chunk-RSSRYEM3.js';export{b as defineOptimisticMutations}from'./chunk-RSSRYEM3.js';import {useSyncExternalStore,useMemo,useEffect}from'react';import {xxHash32}from'js-xxhash';import {z as z$1}from'zod';import {stringify}from'qs';import Ge from'fast-deep-equal';import {openDB}from'idb';var T=o=>xxHash32(JSON.stringify(o)).toString(32);var R=(o,e,t=false)=>Object.entries(e).every(([i,n])=>{if(i==="$and")return n.every(s=>R(o,s,t));if(i==="$or")return n.some(s=>R(o,s,t));let r=(n==null?void 0:n.$eq)!==void 0?n==null?void 0:n.$eq:n;if(typeof n=="object"&&n!==null&&(n==null?void 0:n.$eq)===void 0){if(n.$in!==void 0){let a=o[i];return a===void 0?false:t?!n.$in.includes(a):n.$in.includes(a)}if(n.$not!==void 0&&!t)return R(o,{[i]:n.$not},true);if(n.$gt!==void 0){let a=o[i];return typeof a!="number"?false:t?a<=n.$gt:a>n.$gt}if(n.$gte!==void 0){let a=o[i];return typeof a!="number"?false:t?a<n.$gte:a>=n.$gte}if(n.$lt!==void 0){let a=o[i];return typeof a!="number"?false:t?a>=n.$lt:a<n.$lt}if(n.$lte!==void 0){let a=o[i];return typeof a!="number"?false:t?a>n.$lte:a<=n.$lte}let s=o[i];return !s||typeof s!="object"&&!Array.isArray(s)?false:Array.isArray(s)?t?!s.some(a=>R(a,n,false)):s.some(a=>R(a,n,false)):R(s,n,t)}return t?o[i]!==r:o[i]===r}),j=o=>{if(typeof o!="object"||o===null)return false;let e=o;return "where"in e||"limit"in e||"orderBy"in e||"include"in e},C={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},J=class{level;prefix;constructor(e={}){this.level=e.level??C.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=C.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=C.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=C.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=C.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=C.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},de=o=>new J(o);var Y=class{subscriptions=new Map;getOrStoreSubscription(e){let t=e.buildQueryRequest(),i=T(t);if(this.subscriptions.has(i))return this.subscriptions.get(i).subscribe;let n={subscribe:r=>{let s=this.subscriptions.get(i);return s.callbacks.add(r),s.unsubscribe||(s.unsubscribe=()=>{},s.unsubscribe=e.subscribe(()=>{s.callbacks.forEach(a=>{a();});})),()=>{var a;(a=this.subscriptions.get(i))==null||a.callbacks.delete(r),setTimeout(()=>{var u;let l=this.subscriptions.get(i);l&&l.callbacks.size===0&&((u=l.unsubscribe)==null||u.call(l),this.subscriptions.delete(i));},10);}},callbacks:new Set,unsubscribe:void 0};return this.subscriptions.set(i,n),this.subscriptions.get(i).subscribe}},Ce=new Y,Xe=o=>useSyncExternalStore(Ce.getOrStoreSubscription(o),o.get),Ze=o=>{let{subscribe:e,getSnapshot:t}=useMemo(()=>{let i={bootstrapStatus:o.bootstrapStatus,connected:o.ws.connected()},n=()=>{let r={bootstrapStatus:o.bootstrapStatus,connected:o.ws.connected()};(r.bootstrapStatus!==i.bootstrapStatus||r.connected!==i.connected)&&(i=r);};return {subscribe:r=>o.addEventListener(s=>{(s.type==="BOOTSTRAP_STATUS_CHANGE"||s.type==="CONNECTION_STATE_CHANGE")&&(n(),r());}),getSnapshot:()=>i}},[o]);return useSyncExternalStore(e,t,t)},et=(o,e)=>{useEffect(()=>{let t=o.load(e.buildQueryRequest());return ()=>{t();}},[e,o.load]);};var k=class o{_collection;_client;_where;_include;_limit;_single;_sort;_shouldAwait;constructor(e,t,i,n,r,s,a,l){this._collection=e,this._client=t,this._where=i??{},this._include=n??{},this._limit=r,this._single=s,this._sort=a,this._shouldAwait=l,this.get=this.get.bind(this),this.subscribe=this.subscribe.bind(this);}where(e){return new o(this._collection,this._client,{...this._where,...e},this._include,this._limit,this._single,this._sort,this._shouldAwait)}include(e){return new o(this._collection,this._client,this._where,{...this._include,...e},this._limit,this._single,this._sort,this._shouldAwait)}limit(e){return new o(this._collection,this._client,this._where,this._include,e,this._single,this._sort,this._shouldAwait)}one(e){return this.first({id:e})}first(e){return new o(this._collection,this._client,e??this._where,this._include,1,true,this._sort,this._shouldAwait)}orderBy(e,t="asc"){let i=[...this._sort??[],{key:e,direction:t}];return new o(this._collection,this._client,this._where,this._include,this._limit,this._single,i,this._shouldAwait)}toJSON(){return {resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort}}buildQueryRequest(){return {resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort}}get(){let e=this._client.get(this.buildQueryRequest());return this._shouldAwait?Promise.resolve(e).then(t=>this._single?t[0]:t):this._single?e[0]:e}subscribe(e){return this._client.subscribe(this.buildQueryRequest(),t=>{if(this._single)return e(t[0]);e(t);})}static _init(e,t,i){return new o(e,t,void 0,void 0,void 0,void 0,void 0,i??false)}};z$1.object({resource:z$1.string(),where:z$1.record(z$1.string(),z$1.any()).optional(),include:z$1.record(z$1.string(),z$1.any()).optional(),limit:z$1.coerce.number().optional(),sort:z$1.array(z$1.object({key:z$1.string(),direction:z$1.enum(["asc","desc"])})).optional()});var X=z$1.record(z$1.string(),z$1.object({value:z$1.any().nullable(),_meta:z$1.object({timestamp:z$1.string().optional().nullable()}).optional()})),xe=X.superRefine((o,e)=>{o.id&&e.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Le=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string(),resourceId:z$1.string().optional()}),ye=z$1.object({timestamp:z$1.string().optional(),originMutationId:z$1.string().optional()}).optional(),he=Le.extend({procedure:z$1.string(),payload:z$1.any().optional(),meta:ye}),Z=z$1.object({id:z$1.string().optional(),type:z$1.literal("SYNC"),resource:z$1.string(),resourceId:z$1.string(),op:z$1.enum(["INSERT","UPDATE","DELETE"]),payload:xe,meta:ye}),ee=(o,e)=>{o.op==="DELETE"&&Object.keys(o.payload).length>0&&e.addIssue({code:z$1.ZodIssueCode.custom,message:"DELETE delta payload must be empty"});};Z.superRefine(ee);var me=z$1.object({resource:z$1.string(),procedure:z$1.string(),input:z$1.any().optional()});var x=z$1.string(),te=me,Ee=z$1.object({id:x,type:z$1.literal("SUBSCRIBE")}).and(te),Ie=z$1.object({id:x,type:z$1.literal("UNSUBSCRIBE")}).and(te),we=z$1.object({id:x,type:z$1.literal("QUERY")}).and(te),Ae=z$1.object({id:x,type:z$1.literal("CUSTOM_QUERY"),resource:z$1.string(),procedure:z$1.string(),input:z$1.any().optional()}),Oe=he.extend({id:x}),je=Oe;z$1.union([Ee,we,Ae,je,Ie]);var _e=z$1.object({id:x,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),De=z$1.object({id:x,type:z$1.literal("REPLY"),data:z$1.any()}),Ve=Z.extend({id:x}).superRefine(ee),fe=z$1.union([_e,De,Ve]),Te=z$1.object({resource:z$1.string(),data:z$1.array(X)});var N=class{ws=null;url;autoConnect;autoReconnect;reconnectTimeout;reconnectLimit;reconnectAttempts=0;eventListeners=new Map;reconnectTimer=null;intentionallyDisconnected=false;credentials;constructor(e){this.url=e.url,this.autoConnect=e.autoConnect??false,this.autoReconnect=e.autoReconnect??false,this.reconnectTimeout=e.reconnectTimeout??5e3,this.reconnectLimit=e.reconnectLimit,this.credentials=e.credentials,this.autoConnect&&this.connect();}connected(){var e;return ((e=this.ws)==null?void 0:e.readyState)===WebSocket.OPEN}async connect(){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;this.intentionallyDisconnected=false;let e=await b(this.credentials);this.ws=new WebSocket(this.url+(e?`?${stringify(e)}`:"")),this.ws.addEventListener("open",this.handleOpen.bind(this)),this.ws.addEventListener("close",this.handleClose.bind(this)),this.ws.addEventListener("error",this.handleError.bind(this)),this.ws.addEventListener("message",this.handleMessage.bind(this));}disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.intentionallyDisconnected=true,this.ws&&(this.ws.close(),this.ws=null);}addEventListener(e,t){var i;this.eventListeners.has(e)||this.eventListeners.set(e,new Set),(i=this.eventListeners.get(e))==null||i.add(t);}removeEventListener(e,t){var i;this.eventListeners.has(e)&&((i=this.eventListeners.get(e))==null||i.delete(t));}send(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e);else throw new Error("WebSocket is not open")}handleOpen(e){this.reconnectAttempts=0,this.dispatchEvent("open",e),this.dispatchEvent("connectionChange",{open:true});}handleClose(e){this.dispatchEvent("close",e),this.dispatchEvent("connectionChange",{open:false}),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect();}handleError(e){var t,i;this.dispatchEvent("error",e),this.dispatchEvent("connectionChange",{open:false}),(i=(t=e.error)==null?void 0:t.message)!=null&&i.includes("non-101")&&(this.ws&&(this.ws.close(),this.ws=null),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect());}handleMessage(e){this.dispatchEvent("message",e);}scheduleReconnect(){this.reconnectLimit&&this.reconnectAttempts>=this.reconnectLimit||(this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.connect();},this.reconnectTimeout));}dispatchEvent(e,t){var i;(i=this.eventListeners.get(e))==null||i.forEach(n=>{n(t);});}};var ie=o=>typeof o=="object"&&o!==null&&"value"in o&&!Array.isArray(o),O=o=>o?Array.isArray(o.value)?o.value.map(t=>ie(t)?O(t):t):typeof o.value!="object"||o.value===null||o.value instanceof Date?o.value:Object.fromEntries(Object.entries(o.value).map(([t,i])=>Array.isArray(i)?[t,i.map(n=>ie(n)?O(n):n)]:ie(i)?[t,O(i)]:[t,i])):void 0;var W=class{constructor(e){this.logger=e;this.nodes=new Map;}nodes;createNode(e,t,i){if(this.nodes.has(e))throw new Error(`Node with id ${e} already exists`);let n={id:e,type:t,referencedBy:new Map(i.map(r=>[r,new Set])),references:new Map,subscriptions:new Set};return this.nodes.set(e,n),n}getNode(e){return this.nodes.get(e)}hasNode(e){return this.nodes.has(e)}createLink(e,t){let i=this.nodes.get(e),n=this.nodes.get(t);if(!i)throw new Error(`Source node with id ${e} does not exist`);if(!n)throw new Error(`Target node with id ${t} does not exist`);i.references.set(n.type,t);let r=n.referencedBy.get(i.type);r&&r instanceof Set?r.add(e):n.referencedBy.set(i.type,e),this.notifySubscribers(t);}removeLink(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);let n=i.references.get(t);if(!n)return;i.references.delete(t);let r=this.nodes.get(n);if(!r)return;let s=r.referencedBy.get(i.type);s&&(s instanceof Set?s.delete(e):r.referencedBy.delete(i.type),this.notifySubscribers(n)),this.notifySubscribers(e);}subscribe(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);return i.subscriptions.add(t),()=>{i.subscriptions.delete(t);}}removeNode(e){let t=this.nodes.get(e);t&&(Array.from(t.referencedBy.entries()).forEach(([i,n])=>{(n instanceof Set?Array.from(n.values()):[n]).forEach(s=>{let a=this.nodes.get(s);!a||!a.references.get(i)||(a.references.delete(i),this.notifySubscribers(s));});}),this.nodes.delete(e));}updateNode(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);t(i),this.notifySubscribers(e);}notifySubscribers(e){let t=this.nodes.get(e);t&&Array.from(t.subscriptions).forEach(i=>{var n;try{i(e);}catch(r){(n=this.logger)==null||n.error(`Error in node subscription for node ${e}:`,r);}});}getAllNodes(){return Array.from(this.nodes.values())}};var ne="__meta",B="databases",$=class{db;async init(e,t){var u,d;if(typeof window>"u")return;let n=((u=(await window.indexedDB.databases()).find(c=>c.name===t))==null?void 0:u.version)??1,r=await T(e),s=Object.fromEntries(await Promise.all(Object.entries(e).map(async([c,p])=>[c,await T(p)]))),a=await openDB("live-state-databases",1,{upgrade(c){c.objectStoreNames.contains(B)||c.createObjectStore(B);}}),l=(d=await this.getAll(a,B))==null?void 0:d[t];(l==null?void 0:l.schemaHash)!==r&&n++,this.db=await openDB(t,n,{async upgrade(c){[...Object.keys(e),ne].forEach(p=>{(l==null?void 0:l.objectHashes[p])!==s[p]&&c.objectStoreNames.contains(p)&&c.deleteObjectStore(p),c.objectStoreNames.contains(p)||c.createObjectStore(p);}),await a.put(B,{schemaHash:r,objectHashes:s},t);},blocking(){window.location.reload();},blocked(){window.location.reload();}});}async get(e){return await this.getAll(this.db,e)??{}}getOne(e,t){return this.db?this.db.get(e,t):new Promise(i=>i(void 0))}set(e,t,i){var n;return (n=this.db)==null?void 0:n.put(e,i,t)}delete(e,t){var i;return (i=this.db)==null?void 0:i.delete(e,t)}getMeta(e){return this.db?this.db.get(ne,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(ne,t,e)}async getAll(e,t){if(!e)return;if(e.getAllRecords)return e.getAllRecords(t);let[i,n]=await Promise.all([e.getAll(t),e.getAllKeys(t)]);return Object.fromEntries(i.map((r,s)=>[n[s],r]))}};var G=class{constructor(e,t,i,n,r,s){this.schema=e;this.logger=i,this.optimisticObjGraph=new W(i),this.kvStorage=new $,this.onQuerySubscriptionTriggered=s,t!==false&&this.kvStorage.init(this.schema,t.name).then(()=>{Promise.all([this.kvStorage.getMeta("mutationStack"),this.kvStorage.getMeta("customMutationStack"),this.kvStorage.getMeta("customMutationIndex")]).then(([a,l,u])=>{a&&Object.keys(a).length>0&&(this.optimisticMutationStack=a),l&&l.length>0&&(this.customMutationStack=l),u&&Object.keys(u).length>0&&(this.customMutationIndex=u),n==null||n(this.optimisticMutationStack,this.customMutationStack,this.customMutationIndex);}).then(()=>{Object.entries(this.schema).forEach(([a])=>{this.kvStorage.get(a).then(l=>{if(!l||Object.keys(l).length===0){r==null||r(a,0);return}let u=Object.entries(l).map(([d,c])=>({...c,id:{value:d}}));r==null||r(a,u.length),this.loadConsolidatedState(a,u);});});}).catch(a=>{i.debug("Storage initialization failed (may not be available in this environment):",a);});});}rawObjPool={};optimisticMutationStack={};customMutationStack=[];optimisticObjGraph;optimisticRawObjPool={};logger;onQuerySubscriptionTriggered;customMutationIndex={};collectionSubscriptions=new Map;querySnapshots={};kvStorage;get(e,t,i=false){var l;let n=t??T(e);if(this.querySnapshots[n]&&!i){let u=this.querySnapshots[n];if(u)return u}let r,s=(l=e.where)==null?void 0:l.id;s===void 0?r=Object.keys(this.optimisticRawObjPool[e.resource]??{}):typeof s=="string"?r=[s]:typeof s=="object"&&s!==null?"$in"in s&&Array.isArray(s.$in)?r=s.$in:"$eq"in s&&typeof s.$eq=="string"?r=[s.$eq]:r=Object.keys(this.optimisticRawObjPool[e.resource]??{}):r=Object.keys(this.optimisticRawObjPool[e.resource]??{});let a=r.flatMap(u=>{let d=O(this.materializeOneWithInclude(u,e.include));return d?[d]:[]});if(e.sort&&e.sort.length>0){let u=(d,c)=>{for(let p of e.sort){let m=d[p.key],f=c[p.key];if(m<f)return p.direction==="asc"?-1:1;if(m>f)return p.direction==="asc"?1:-1}return 0};a.sort(u);}if(e.where||e.limit){let u=e.where?d=>R(d,e.where):()=>true;a=d(a,u,e.limit);}return !i&&this.collectionSubscriptions.has(n)&&(this.querySnapshots[n]=a),a}subscribe(e,t){var r;let i=T(e);return this.collectionSubscriptions.get(i)||this.collectionSubscriptions.set(i,{callbacks:new Set,query:e,flatInclude:e.include?this.flattenIncludes(e.include,e.resource):void 0}),(r=this.collectionSubscriptions.get(i))==null||r.callbacks.add(t),()=>{var s,a;(s=this.collectionSubscriptions.get(i))==null||s.callbacks.delete(t),((a=this.collectionSubscriptions.get(i))==null?void 0:a.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var l,u,d,c,p,m,f,g;let n=this.schema[e];if(this.logger.debug("Adding mutation",t),!n)throw new Error("Schema not found");if(t.op==="DELETE"){this.removeFromPool(e,t.resourceId);return}let r=(l=this.optimisticRawObjPool[e])==null?void 0:l[t.resourceId],s=false;if(i)this.optimisticMutationStack[e]??=[],this.optimisticMutationStack[e].push(t);else {this.optimisticMutationStack[e]=((d=(u=this.optimisticMutationStack)==null?void 0:u[e])==null?void 0:d.filter(re=>re.id!==t.id))??[];let E=(c=t.meta)==null?void 0:c.originMutationId;if(this.logger.debug("Broadcast mutation received",{mutationId:t.id,resource:e,resourceId:t.resourceId,op:t.op,originMutationId:E??"(none)",customMutationIndexKeys:Object.keys(this.customMutationIndex),optimisticStackSize:((p=this.optimisticMutationStack[e])==null?void 0:p.length)??0}),E&&this.customMutationIndex[E]){let oe=this.customMutationIndex[E].filter(S=>S.resource===e),H=false;for(let S of oe){let I=(m=this.optimisticMutationStack[e])==null?void 0:m.find(V=>V.id===S.mutationId);if(I&&I.resourceId===t.resourceId&&I.op===t.op){this.logger.debug("Removing optimistic mutation (resourceId match)",{optimisticMutationId:S.mutationId,resourceId:t.resourceId}),this.undoMutation(e,S.mutationId),s=true,H=true;break}}if(!H)for(let S of oe){let I=(f=this.optimisticMutationStack[e])==null?void 0:f.find(V=>V.id===S.mutationId&&V.op===t.op);if(I){this.logger.debug("Removing optimistic mutation (resource+procedure fallback)",{optimisticMutationId:S.mutationId,optimisticResourceId:I.resourceId,broadcastResourceId:t.resourceId}),this.undoMutation(e,S.mutationId),s=true,H=true;break}}}this.rawObjPool[e]??={};let _={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=_;let D=_.value;delete D.id,this.kvStorage.set(e,t.resourceId,D);}this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack);let a=s?(g=this.optimisticRawObjPool[e])==null?void 0:g[t.resourceId]:r;this.updateRawObjPool(e,t.resourceId,t.payload,a);}undoMutation(e,t){var s,a;if(!this.optimisticMutationStack[e])return;let i=(s=this.optimisticMutationStack[e])==null?void 0:s.findIndex(l=>l.id===t);if(i===-1)return;let n=this.optimisticMutationStack[e][i];this.logger.debug("Removing mutation",n);let r=(a=this.optimisticRawObjPool[e])==null?void 0:a[n.resourceId];this.optimisticMutationStack[e].splice(i,1),this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,n.resourceId,Object.fromEntries(Object.entries(n.payload).map(([l])=>[l,{value:null,_meta:{}}])),r);}addCustomMutationMessage(e){this.customMutationStack.push(e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack);}registerCustomMutation(e,t){this.customMutationIndex[e]=t,this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex);}confirmCustomMutation(e){var i;let t=this.customMutationIndex[e];if(this.logger.debug("confirmCustomMutation called",{messageId:e,hasIndex:!!t,mutations:t??[]}),!!t){for(let{resource:n,mutationId:r}of t){let s=!!((i=this.optimisticMutationStack[n])!=null&&i.find(a=>a.id===r));this.logger.debug("confirmCustomMutation: undoing mutation",{resource:n,mutationId:r,stillInStack:s}),this.undoMutation(n,r);}delete this.customMutationIndex[e],this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex),this.customMutationStack=this.customMutationStack.filter(n=>n.id!==e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack);}}undoCustomMutation(e){var n;let t=this.customMutationIndex[e];if(!t)return [];let i=[];for(let{resource:r,mutationId:s}of t){let a=(n=this.optimisticMutationStack[r])==null?void 0:n.find(l=>l.id===s);this.undoMutation(r,s),a&&i.push({resource:r,mutationId:s,resourceId:a.resourceId});}return delete this.customMutationIndex[e],this.kvStorage.setMeta("customMutationIndex",this.customMutationIndex),this.customMutationStack=this.customMutationStack.filter(r=>r.id!==e),this.kvStorage.setMeta("customMutationStack",this.customMutationStack),i}getCustomMutationMutationIds(){let e=new Set;for(let t of Object.values(this.customMutationIndex))for(let{mutationId:i}of t)e.add(i);return e}loadConsolidatedState(e,t){t.forEach(i=>{var a;let n=(a=i.id)==null?void 0:a.value;if(!n)return;let{cleanedPayload:r,nestedMutations:s}=this.extractNestedRelations(e,i);s.forEach(l=>{this.addMutation(l.resource,l);}),this.addMutation(e,{id:n,type:"SYNC",resource:e,resourceId:n,op:"INSERT",payload:r});});}extractNestedRelations(e,t){let i=this.schema[e],n={...t},r=[];return i!=null&&i.relations?(Object.entries(t).forEach(([s,a])=>{var c;let l=i.relations[s];if(!l)return;let u=l.entity.name,d=a==null?void 0:a.value;if(l.type==="one"){if(d&&typeof d=="object"&&!Array.isArray(d)&&((c=d.id)!=null&&c.value)){let p=d.id.value,m={...d},{cleanedPayload:f,nestedMutations:g}=this.extractNestedRelations(u,m);r.push(...g),r.push({id:p,type:"SYNC",resource:u,resourceId:p,op:"INSERT",payload:f}),delete n[s];}}else l.type==="many"&&Array.isArray(d)&&(d.forEach(p=>{var m,f;if(p&&typeof p=="object"&&!Array.isArray(p)&&((f=(m=p.value)==null?void 0:m.id)!=null&&f.value)){let g=p.value.id.value,E={...p.value},{cleanedPayload:_,nestedMutations:D}=this.extractNestedRelations(u,E);r.push(...D),r.push({id:g,type:"SYNC",resource:u,resourceId:g,op:"INSERT",payload:_});}}),delete n[s]);}),{cleanedPayload:n,nestedMutations:r}):{cleanedPayload:n,nestedMutations:r}}removeFromPool(e,t){var i,n;this.schema[e]&&((i=this.rawObjPool[e])==null||delete i[t],(n=this.optimisticRawObjPool[e])==null||delete n[t],this.kvStorage.delete(e,t),this.optimisticObjGraph.removeNode(t),this.notifyCollectionSubscribers(e),this.optimisticObjGraph.notifySubscribers(t));}updateRawObjPool(e,t,i,n){var a;if(!this.schema[e])return;let r=(a=this.rawObjPool[e])==null?void 0:a[t],s=(this.optimisticMutationStack[e]??[]).reduce((l,u)=>u.resourceId!==t?l:this.schema[e].mergeMutation("set",u.payload,l)[0],r);if(this.optimisticRawObjPool[e]??={},s?this.optimisticRawObjPool[e][t]={value:{...s.value,id:{value:t}}}:delete this.optimisticRawObjPool[e][t],!(!this.optimisticObjGraph.hasNode(t)&&!s)){if(this.optimisticObjGraph.hasNode(t)||this.optimisticObjGraph.createNode(t,e,Object.values(this.schema[e].relations).flatMap(l=>l.type==="many"?[l.entity.name]:[])),Object.keys(this.schema[e].relations).length>0){let l=Object.fromEntries(Object.entries(this.schema[e].relations).flatMap(([u,d])=>d.type==="one"?[[d.relationalColumn,u]]:[]));Object.entries(i).forEach(([u,d])=>{let c=this.schema[e].relations[l[u]];if(!l[u])return;let p=n==null?void 0:n.value[u],[,m]=c.mergeMutation("set",d,p);if(m){if(!this.optimisticObjGraph.hasNode(m.value)){let f=c.entity.name;this.optimisticObjGraph.createNode(m.value,f,Object.values(this.schema[f].relations).flatMap(g=>g.type==="many"?[g.entity.name]:[]));}p!=null&&p.value&&this.optimisticObjGraph.removeLink(t,c.entity.name),this.optimisticObjGraph.createLink(t,m.value);}});}this.notifyCollectionSubscribers(e),this.optimisticObjGraph.notifySubscribers(t);}}materializeOneWithInclude(e,t={}){var l;if(!e)return;let i=this.optimisticObjGraph.getNode(e);if(!i)return;let n=i.type,r=(l=this.optimisticRawObjPool[n])==null?void 0:l[e];if(!r)return;let[s,a]=Object.entries(t).reduce((u,[d,c])=>{let p=this.schema[n].relations[d];return p&&(p.type==="one"?u[0].push([d,p.entity.name,c??true]):p.type==="many"&&u[1].push([d,p.entity.name,c??true])),u},[[],[]]);return {value:{...r.value,...Object.fromEntries(s.map(([u,d,c])=>[u,this.materializeOneWithInclude(i.references.get(d),j(c)?c.include??{}:typeof c=="object"&&c!==null?c:{})])),...Object.fromEntries(a.map(([u,d,c])=>{let p=i.referencedBy.get(d),m=p instanceof Set;return [u,m?{value:Array.from(p.values()).map(f=>this.materializeOneWithInclude(f,j(c)?c.include??{}:typeof c=="object"&&c!==null?c:{}))}:this.materializeOneWithInclude(p,j(c)?c.include??{}:typeof c=="object"&&c!==null?c:{})]}))}}}notifyCollectionSubscribers(e){this.collectionSubscriptions.forEach(t=>{var i,n;if(t.query.resource===e||(i=t.flatInclude)!=null&&i.includes(e)){let r=T(t.query),s=this.querySnapshots[r],a=this.get(t.query,void 0,true);if(Ge(a,s))return;this.querySnapshots[r]=a,(n=this.onQuerySubscriptionTriggered)==null||n.call(this,t.query),t.callbacks.forEach(l=>{l(a);});}});}flattenIncludes(e,t){let i=[];return Object.entries(e).forEach(([n,r])=>{var l;let s=(l=this.schema[t])==null?void 0:l.relations[n];if(!s)return;let a=s.entity.name;if(i.push(a),typeof r=="object"&&r!==null){let u=j(r)?r.include??{}:r;i.push(...this.flattenIncludes(u,a));}}),Array.from(new Set(i))}};var ve={pending:0,local:1,remote:2},z=class{constructor(e,t){this.client=e;this.query=t;}buildQueryRequest(){return this.query}then(e,t){return this.client.genericQuery(this.query.resource,this.query.procedure,this.query.input).then(e,t)}},se=class{url;ws;store;logger;optimisticMutations;remoteSubscriptions=new Map;eventListeners=new Set;replyHandlers={};_bootstrapStatus="pending";storageLoadedCount=0;expectedStorageLoads;constructor(e){var t,i,n,r;this.url=e.url,this.logger=de({level:e.logLevel??C.INFO}),this.optimisticMutations=e.optimisticMutations,this.expectedStorageLoads=e.storage===false?0:Object.keys(e.schema).length,this.store=new G(e.schema,e.storage,this.logger,()=>{this.replayCustomMutationStack();},(s,a)=>{this.emitEvent({type:"CLIENT_STORAGE_LOADED",resource:s,itemCount:a}),this.storageLoadedCount+=1,this.expectedStorageLoads>0&&this.storageLoadedCount>=this.expectedStorageLoads&&this.setBootstrapStatus("local");},s=>{this.emitEvent({type:"QUERY_SUBSCRIPTION_TRIGGERED",query:s});}),this.ws=new N({url:e.url,autoConnect:((t=e.connection)==null?void 0:t.autoConnect)??true,autoReconnect:((i=e.connection)==null?void 0:i.autoReconnect)??true,reconnectTimeout:((n=e.connection)==null?void 0:n.reconnectTimeout)??5e3,reconnectLimit:(r=e.connection)==null?void 0:r.maxReconnectAttempts,credentials:e.credentials}),this.ws.addEventListener("message",s=>{this.handleServerMessage(s.data);}),this.ws.addEventListener("connectionChange",s=>{this.emitEvent({type:"CONNECTION_STATE_CHANGE",open:s.open}),s.open&&(Array.from(this.remoteSubscriptions.values()).forEach(({query:a$1})=>{this.sendWsMessage({id:a(),type:"SUBSCRIBE",...a$1});}),this.replayCustomMutationStack());});}get(e){let t=this.store.get(e);return this.emitEvent({type:"QUERY_EXECUTED",query:e,resultCount:Array.isArray(t)?t.length:t?1:0}),t}handleServerMessage(e){var t,i,n,r;try{this.logger.debug("Message received from the server:",e);let s=fe.parse(JSON.parse(e));if(this.logger.debug("Parsed message:",s),this.emitEvent({type:"MESSAGE_RECEIVED",message:s}),s.type==="SYNC"){let{resource:a,id:l,resourceId:u,op:d}=s;this.emitEvent({type:"MUTATION_RECEIVED",mutationId:l,resource:a,resourceId:u,procedure:d??"UNKNOWN"});try{this.store.addMutation(a,s);}catch(c){this.logger.error("Error merging sync delta from the server:",c);}}else if(s.type==="REJECT"){if(this.replyHandlers[s.id]){clearTimeout(this.replyHandlers[s.id].timeoutHandle),this.emitUndoEvents(this.store.undoCustomMutation(s.id));let u=s.message??"Mutation rejected";(i=(t=this.replyHandlers[s.id]).reject)==null||i.call(t,new Error(u)),delete this.replyHandlers[s.id];}let a=((n=this.store.optimisticMutationStack[s.resource])==null?void 0:n.length)??0,l=(r=this.store.optimisticMutationStack[s.resource])==null?void 0:r.find(u=>u.id===s.id);this.store.undoMutation(s.resource,s.id),this.emitEvent({type:"MUTATION_REJECTED",mutationId:s.id,resource:s.resource}),l&&this.emitEvent({type:"OPTIMISTIC_MUTATION_UNDONE",mutationId:s.id,resource:s.resource,resourceId:l.resourceId,pendingMutations:a-1});}else if(s.type==="REPLY"){let{id:a,data:l}=s;if(this.replyHandlers[a]){clearTimeout(this.replyHandlers[a].timeoutHandle),this.replyHandlers[a].handler(l);return}let u=Te.parse(l);this.emitEvent({type:"DATA_LOAD_REPLY",resource:u.resource,itemCount:u.data.length}),this.store.loadConsolidatedState(u.resource,u.data),this.emitEvent({type:"STORE_STATE_UPDATED",resource:u.resource,itemCount:u.data.length}),this.setBootstrapStatus("remote");}}catch(s){this.logger.error("Error parsing message from the server:",s);}}load(e){let t=a(),i=T(e);this.emitEvent({type:"DATA_LOAD_REQUESTED",query:e,subscriptionId:t}),this.sendWsMessage({id:t,type:"SUBSCRIBE",...e});let n=!this.remoteSubscriptions.has(i);return this.remoteSubscriptions.has(i)?this.remoteSubscriptions.get(i).subCounter+=1:this.remoteSubscriptions.set(i,{query:e,subCounter:1}),n&&this.emitEvent({type:"SUBSCRIPTION_CREATED",query:e,subscriptionKey:i,subscriberCount:1}),()=>{if(this.remoteSubscriptions.has(i)){let r=this.remoteSubscriptions.get(i);r.subCounter-=1,this.remoteSubscriptions.get(i).subCounter<=0&&(this.remoteSubscriptions.delete(i),this.sendWsMessage({id:a(),type:"UNSUBSCRIBE",...e}),this.emitEvent({type:"SUBSCRIPTION_REMOVED",query:e,subscriptionKey:i}));}}}subscribe(e,t){return this.store.subscribe(e,t)}genericMutate(e,t,i){var a$2,l;let n=(a$2=this.ws)==null?void 0:a$2.connected(),r=(l=this.optimisticMutations)==null?void 0:l.getHandler(e,t);if(!n&&!r)throw new Error("WebSocket not connected");let s={id:a(),type:"MUTATE",resource:e,procedure:t,payload:i,meta:{timestamp:new Date().toISOString()}};if(r)try{let{proxy:u,getOperations:d}=a$1(this.store,this.store.schema);r({input:i,storage:u});let c=d(),p=this.applyOptimisticOperations(c);this.store.registerCustomMutation(s.id,p),this.emitEvent({type:"MUTATION_SENT",mutationId:s.id,resource:e,resourceId:"",procedure:t,optimistic:!0});}catch(u){throw this.logger.error("Error executing optimistic handler:",u),this.emitUndoEvents(this.store.undoCustomMutation(s.id)),u}else this.emitEvent({type:"MUTATION_SENT",mutationId:s.id,resource:e,resourceId:"",procedure:t,optimistic:false});return n?(this.sendWsMessage(s),new Promise((u,d)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],this.emitUndoEvents(this.store.undoCustomMutation(s.id)),d(new Error("Reply timeout"));},5e3),handler:c=>{delete this.replyHandlers[s.id],this.store.confirmCustomMutation(s.id),u(c);},reject:d};})):(this.store.addCustomMutationMessage(s),Promise.resolve(void 0))}applyOptimisticOperations(e){var i;let t=[];try{for(let n of e){let r=a(),s=new Date().toISOString(),a$1={id:r,type:"SYNC",resource:n.resource,resourceId:n.id,op:n.type==="insert"?"INSERT":"UPDATE",payload:this.store.schema[n.resource].encodeMutation("set",n.data,s)},l=(((i=this.store.optimisticMutationStack[n.resource])==null?void 0:i.length)??0)+1;this.store.addMutation(n.resource,a$1,!0),t.push({resource:n.resource,mutationId:r}),this.emitEvent({type:"OPTIMISTIC_MUTATION_APPLIED",mutationId:r,resource:n.resource,resourceId:n.id,procedure:n.type==="insert"?"INSERT":"UPDATE",pendingMutations:l});}return t}catch(n){for(let{resource:r,mutationId:s}of t)this.store.undoMutation(r,s);throw n}}emitUndoEvents(e){var t;for(let{resource:i,mutationId:n,resourceId:r}of e){let s=((t=this.store.optimisticMutationStack[i])==null?void 0:t.length)??0;this.emitEvent({type:"OPTIMISTIC_MUTATION_UNDONE",mutationId:n,resource:i,resourceId:r,pendingMutations:s});}}genericQuery(e,t,i){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let n={id:a(),type:"CUSTOM_QUERY",resource:e,procedure:t,input:i};return this.sendWsMessage(n),new Promise((r,s)=>{this.replyHandlers[n.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[n.id],s(new Error("Reply timeout"));},5e3),handler:a=>{delete this.replyHandlers[n.id],r(a);},reject:s};})}get bootstrapStatus(){return this._bootstrapStatus}setBootstrapStatus(e){ve[e]<=ve[this._bootstrapStatus]||(this._bootstrapStatus=e,this.emitEvent({type:"BOOTSTRAP_STATUS_CHANGE",bootstrapStatus:e}));}addEventListener(e){return this.eventListeners.add(e),()=>{this.eventListeners.delete(e);}}replayCustomMutationStack(){var e;if((e=this.ws)!=null&&e.connected())for(let t of this.store.customMutationStack)this.sendWsMessage(t),!this.replyHandlers[t.id]&&(this.replyHandlers[t.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[t.id],this.emitUndoEvents(this.store.undoCustomMutation(t.id));},5e3),handler:()=>{delete this.replyHandlers[t.id],this.store.confirmCustomMutation(t.id);}});}sendWsMessage(e){var t;(t=this.ws)!=null&&t.connected()&&this.ws.send(JSON.stringify(e));}emitEvent(e){this.eventListeners.forEach(t=>{t(e);});}},ei=o=>{let e=new se(o),t=(i,n)=>new Proxy(n,{get(r,s,a){if(s in r)return Reflect.get(r,s,a);if(typeof s=="string")return l=>new z(e,{resource:i,procedure:s,input:l})}});return {client:{ws:e.ws,get bootstrapStatus(){return e.bootstrapStatus},load:i=>e.load(i),addEventListener:i=>e.addEventListener(i)},store:{query:new Proxy({},{get(i,n){if(typeof n=="string")return Object.hasOwn(o.schema,n)?t(n,k._init(o.schema[n],e)):new Proxy({},{get(r,s){if(typeof s=="string")return a=>new z(e,{resource:n,procedure:s,input:a})}})},has(i,n){return typeof n=="string"}}),mutate:c(()=>{},{apply:(i,n,r)=>{if(n.length<2)return;if(n.length>2)throw new Error("Trying to access an invalid path");let[s,a]=n;return e.genericMutate(s,a,r[0])}})}}};export{ei as createClient,Ze as useClientState,Xe as useLiveQuery,et as useLoadData};
@@ -1,4 +1,4 @@
1
- import { C as ClientOptions, a as ClientRouterConstraint, b as Client } from './index-C0Qm5yHg.js';
1
+ import { C as ClientOptions, a as ClientRouterConstraint, b as Client } from './index-DjBla1td.js';
2
2
  import '@standard-schema/spec';
3
3
  import 'zod';
4
4
 
@@ -1 +1 @@
1
- import {d,c,a,f}from'./chunk-LSAVBBUS.js';import {stringify}from'qs';var l=async(e,c,u)=>{let s=o=>{if(!o)return {};if(o instanceof Headers){let y={};return o.forEach((f,d)=>{y[d]=f;}),y}return Array.isArray(o)?Object.fromEntries(o):o},i=s(u==null?void 0:u.headers),n=s(c==null?void 0:c.headers),a={...u,...c,headers:{...i,...n}},r=await fetch(e,a),t;try{t=await r.json();}catch{t=await r.text().catch(()=>{});}if(!r.ok)throw new Error(`Failed to fetch: ${r.status} ${r.statusText}`,{cause:t});return t},b=e=>{if(e instanceof Error&&e.message.includes("Unknown procedure"))return true;if(e instanceof Error&&typeof e.cause=="object"&&e.cause!==null&&("message"in e.cause||"code"in e.cause)){let c=e.cause,u=c.message,s=c.code==="UNKNOWN_PROCEDURE"||c.code==="unknown_procedure",i=typeof u=="string"&&u.includes("Unknown procedure");return s||i}return false},p=e=>{if(e===null)return "null";if(Array.isArray(e))return e.map(p);if(typeof e=="object"&&e!==null&&e.constructor===Object){let c={};for(let[u,s]of Object.entries(e))c[u]=p(s);return c}return e},E=e=>{let c$1={get:async s=>{let i=p(s),n=stringify(i),a=await c(e.credentials)??{},r=await l(`${e.url}/${s.resource}${n?`?${n}`:""}`,{headers:{...a,"Content-Type":"application/json"}},e.fetchOptions);return !r||typeof r!="object"?[]:Array.isArray(r)?r.map(t=>{var f$1,d;let o=f(t),y=((d=(f$1=t==null?void 0:t.value)==null?void 0:f$1.id)==null?void 0:d.value)??(t==null?void 0:t.id);return {...o,id:y}}):Object.entries(r).map(([t,o])=>({...f(o),id:t}))},subscribe:()=>{throw new Error("Fetch client does not support subscriptions")}},u=(s,i)=>new Proxy(i,{get(n,a,r){if(a in n)return Reflect.get(n,a,r);if(typeof a=="string")return async t=>{let o=await c(e.credentials)??{};return await l(`${e.url}/${s}/query/${a}`,{method:"POST",headers:{...o,"Content-Type":"application/json"},body:JSON.stringify({input:t})},e.fetchOptions)}}});return {query:new Proxy({},{get(s,i){if(typeof i=="string")return Object.hasOwn(e.schema,i)?u(i,a._init(e.schema[i],c$1,true)):new Proxy({},{get(n,a){if(typeof a=="string")return async r=>{let t=await c(e.credentials)??{};return await l(`${e.url}/${i}/query/${a}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({input:r})},e.fetchOptions)}}})},has(s,i){return typeof i=="string"}}),mutate:d(()=>{},{apply:async(s,i,n)=>{var o;if(i.length<2)return;if(i.length>2)throw new Error("Trying to access an invalid path");let[a,r]=i,t=await c(e.credentials)??{};if(r==="insert"){try{return await l(`${e.url}/${a}/${r}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({payload:n[0],meta:{timestamp:new Date().toISOString()}})},e.fetchOptions)}catch(d){if(!b(d))throw d}let{id:y,...f}=n[0]??{};return await l(`${e.url}/${a}/insert`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:y,payload:e.schema[a].encodeMutation("set",f,new Date().toISOString())})},e.fetchOptions)}if(r==="update"){let y=n.length>1&&typeof n[0]=="string"&&typeof n[1]=="object"&&n[1]!==null?{id:n[0],...n[1]}:n[0];try{return await l(`${e.url}/${a}/${r}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({payload:y,meta:{timestamp:new Date().toISOString()}})},e.fetchOptions)}catch(w){if(!b(w))throw w}let[f,d]=n.length>1?n:[(o=n[0])==null?void 0:o.id,n[0]],{id:C,...$}=d??{};return await l(`${e.url}/${a}/update`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:f,payload:e.schema[a].encodeMutation("set",$,new Date().toISOString())})},e.fetchOptions)}return await l(`${e.url}/${a}/${r}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({payload:n[0],meta:{timestamp:new Date().toISOString()}})},e.fetchOptions)}})}};export{E as createClient};
1
+ import {c,b}from'./chunk-YPTDCIAN.js';var y=async(r,n,i)=>{let t=s=>{if(!s)return {};if(s instanceof Headers){let f={};return s.forEach((g,m)=>{f[m]=g;}),f}return Array.isArray(s)?Object.fromEntries(s):s},c=t(i==null?void 0:i.headers),a=t(n==null?void 0:n.headers),o={...i,...n,headers:{...c,...a}},e=await fetch(r,o),u;try{u=await e.json();}catch{u=await e.text().catch(()=>{});}if(!e.ok)throw new Error(`Failed to fetch: ${e.status} ${e.statusText}`,{cause:u});return u},w=r=>{let n=r.url.replace(/\/+$/,"");return {query:new Proxy({},{get(i,t){if(typeof t=="string")return new Proxy({},{get(c,a){if(typeof a=="string")return async o=>{let e=await b(r.credentials)??{};return await y(`${n}/${t}/query/${a}`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify({input:o})},r.fetchOptions)}}})},has(i,t){return typeof t=="string"}}),mutate:c(()=>{},{apply:async(i,t,c)=>{if(t.length<2)return;if(t.length>2)throw new Error("Trying to access an invalid path");let[a,o]=t,e=await b(r.credentials)??{};return await y(`${n}/${a}/${o}`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify({payload:c[0],meta:{timestamp:new Date().toISOString()}})},r.fetchOptions)}})}};export{w as createClient};
@@ -471,11 +471,17 @@ type ConditionalPromise<T, P extends boolean> = P extends true ? Promise<T> : T;
471
471
  type PromiseOrSync<T> = T | Promise<T>;
472
472
  type Generatable<T, Arg = never> = T | ((arg: Arg) => T);
473
473
 
474
+ /**
475
+ * Internal Tracked Query representation. A Custom Query handler returns an
476
+ * unresolved query builder; the server mints a `RawQueryRequest` from it via
477
+ * `buildQueryRequest()`, which the query engine subscribes and resolves against
478
+ * storage. This is **not** an inbound client→server message — clients can only
479
+ * invoke named Custom Query procedures (see ADR-0002).
480
+ */
474
481
  declare const querySchema: z.ZodObject<{
475
482
  resource: z.ZodString;
476
483
  where: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
477
484
  include: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
478
- lastSyncedAt: z.ZodOptional<z.ZodString>;
479
485
  limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
480
486
  sort: z.ZodOptional<z.ZodArray<z.ZodObject<{
481
487
  key: z.ZodString;
@@ -532,7 +538,7 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
532
538
  * Supports Standard Schema (via ~standard property) and Zod schemas (via _output property for backward compatibility).
533
539
  */
534
540
  type InferSchema$1<T> = T extends {
535
- "~standard": {
541
+ '~standard': {
536
542
  types?: {
537
543
  output: infer U;
538
544
  };
@@ -556,46 +562,52 @@ type CustomQueryLoadable<TOutput> = PromiseLike<TOutput> & {
556
562
  type CustomQueryResult<TOutput, TShouldAwait extends boolean = false> = UnwrapPromise<TOutput> extends QueryBuilder<infer TCollection, infer TInclude, infer TSingle, any> ? TShouldAwait extends true ? TSingle extends true ? Promise<Simplify<InferLiveObject<TCollection, TInclude>> | undefined> : Promise<Simplify<InferLiveObject<TCollection, TInclude>>[]> : TSingle extends true ? CustomQueryLoadable<Simplify<InferLiveObject<TCollection, TInclude>> | undefined> : CustomQueryLoadable<Simplify<InferLiveObject<TCollection, TInclude>>[]> : Promisify<UnwrapPromise<TOutput>>;
557
563
  type CustomQueryFunction<TInput, TOutput, TShouldAwait extends boolean = false> = [TInput] extends [never] | [undefined] ? () => CustomQueryResult<TOutput, TShouldAwait> : (input: TInput) => CustomQueryResult<TOutput, TShouldAwait>;
558
564
  /**
559
- * Simplified router constraint for client-side usage.
560
- * This avoids importing server-internal types like Storage and Hooks,
561
- * which can cause type incompatibilities when the package is bundled.
565
+ * Simplified, client-safe view of a route. Routes are now procedure-only
566
+ * (decoupled from the schema, see ADR-0002); a resource is queryable by virtue
567
+ * of being in the `schema`, not because a route is declared for it.
562
568
  */
563
- type ClientRouterConstraint = {
564
- routes: Record<string, {
565
- resourceSchema: LiveObjectAny | undefined;
566
- customMutations: Record<string, {
567
- _type: "mutation";
568
- inputValidator: StandardSchemaV1<any, any>;
569
- handler: (...args: any[]) => any;
570
- }>;
571
- customQueries: Record<string, {
572
- _type: "query";
573
- inputValidator: StandardSchemaV1<any, any>;
574
- handler: (...args: any[]) => any;
575
- }>;
569
+ type ClientRouteConstraint = {
570
+ customMutations: Record<string, {
571
+ _type: 'mutation';
572
+ inputValidator: StandardSchemaV1<any, any>;
573
+ handler: (...args: any[]) => any;
576
574
  }>;
575
+ customQueries: Record<string, {
576
+ _type: 'query';
577
+ inputValidator: StandardSchemaV1<any, any>;
578
+ handler: (...args: any[]) => any;
579
+ }>;
580
+ };
581
+ type ClientRouterConstraint = {
582
+ schema: Record<string, LiveObjectAny>;
583
+ routes: Record<string, ClientRouteConstraint>;
577
584
  };
578
- type CollectionQueryType<TRoute extends ClientRouterConstraint["routes"][string], TShouldAwait extends boolean> = TRoute["resourceSchema"] extends LiveObjectAny ? QueryBuilder<TRoute["resourceSchema"], {}, false, TShouldAwait> & {
579
- [K2 in keyof TRoute["customQueries"]]: CustomQueryFunction<InferSchema$1<TRoute["customQueries"][K2]["inputValidator"]>, ReturnType<TRoute["customQueries"][K2]["handler"]>, TShouldAwait>;
580
- } : {
581
- [K2 in keyof TRoute["customQueries"]]: CustomQueryFunction<InferSchema$1<TRoute["customQueries"][K2]["inputValidator"]>, ReturnType<TRoute["customQueries"][K2]["handler"]>, TShouldAwait>;
585
+ type CustomQueryMethods<TRoute extends ClientRouteConstraint, TShouldAwait extends boolean> = {
586
+ [K2 in keyof TRoute['customQueries']]: CustomQueryFunction<InferSchema$1<TRoute['customQueries'][K2]['inputValidator']>, ReturnType<TRoute['customQueries'][K2]['handler']>, TShouldAwait>;
582
587
  };
583
- type CollectionMutateType<TRoute extends ClientRouterConstraint["routes"][string], TShouldAwait extends boolean> = TRoute["resourceSchema"] extends LiveObjectAny ? Omit<{
584
- /** @deprecated Use custom mutations instead. Default insert will be removed in a future version. */
585
- insert: (input: Simplify<InferInsert<TRoute["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
586
- /** @deprecated Use custom mutations instead. Default update will be removed in a future version. */
587
- update: (id: string, value: Simplify<InferUpdate<TRoute["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
588
- }, Extract<keyof TRoute["customMutations"], "insert" | "update">> & {
589
- [K2 in keyof TRoute["customMutations"]]: CustomMutationFunction<InferSchema$1<TRoute["customMutations"][K2]["inputValidator"]>, ReturnType<TRoute["customMutations"][K2]["handler"]>>;
590
- } : {
591
- [K2 in keyof TRoute["customMutations"]]: CustomMutationFunction<InferSchema$1<TRoute["customMutations"][K2]["inputValidator"]>, ReturnType<TRoute["customMutations"][K2]["handler"]>>;
588
+ /**
589
+ * The client `store.query.<resource>` surface, asymmetric by client (ADR-0002):
590
+ *
591
+ * - **Websocket** (`TShouldAwait = false`): every resource in the `schema`
592
+ * exposes a `QueryBuilder` **Local Query** `.where()/.get()/.subscribe()`
593
+ * read the optimistic store with no server round-trip (consumed by
594
+ * `useLiveQuery`) merged with the declared **Custom Query** procedures of a
595
+ * route of the same name (if any).
596
+ * - **Fetch** (`TShouldAwait = true`): no optimistic store to back a Local
597
+ * Query, so only the declared Custom Query procedures are exposed.
598
+ */
599
+ type WsQueryType<TRouter extends ClientRouterConstraint, K> = (K extends keyof TRouter['schema'] ? TRouter['schema'][K] extends LiveObjectAny ? QueryBuilder<TRouter['schema'][K], {}, false, false> : unknown : unknown) & (K extends keyof TRouter['routes'] ? CustomQueryMethods<TRouter['routes'][K], false> : unknown);
600
+ type CollectionMutateType<TRoute extends ClientRouteConstraint> = {
601
+ [K2 in keyof TRoute['customMutations']]: CustomMutationFunction<InferSchema$1<TRoute['customMutations'][K2]['inputValidator']>, ReturnType<TRoute['customMutations'][K2]['handler']>>;
592
602
  };
593
603
  type Client$1<TRouter extends ClientRouterConstraint, TShouldAwait extends boolean = false> = {
594
- query: {
595
- [K in keyof TRouter["routes"]]: CollectionQueryType<TRouter["routes"][K], TShouldAwait>;
604
+ query: TShouldAwait extends true ? {
605
+ [K in keyof TRouter['routes']]: CustomQueryMethods<TRouter['routes'][K], true>;
606
+ } : {
607
+ [K in keyof TRouter['schema'] | keyof TRouter['routes']]: WsQueryType<TRouter, K>;
596
608
  };
597
609
  mutate: {
598
- [K in keyof TRouter["routes"]]: CollectionMutateType<TRouter["routes"][K], TShouldAwait>;
610
+ [K in keyof TRouter['routes']]: CollectionMutateType<TRouter['routes'][K]>;
599
611
  };
600
612
  };
601
613
 
@@ -691,30 +703,7 @@ type OptimisticMutationsRegistry<TSchema extends Schema<any>> = {
691
703
  getHandler: (route: string, procedure: string) => OptimisticMutationHandler<TSchema, any> | undefined;
692
704
  };
693
705
 
694
- declare const defaultMutationMsgSchema: z.ZodObject<{
695
- type: z.ZodLiteral<"MUTATE">;
696
- resource: z.ZodString;
697
- resourceId: z.ZodOptional<z.ZodString>;
698
- procedure: z.ZodEnum<{
699
- INSERT: "INSERT";
700
- UPDATE: "UPDATE";
701
- }>;
702
- payload: z.ZodRecord<z.ZodString, z.ZodObject<{
703
- value: z.ZodNullable<z.ZodAny>;
704
- _meta: z.ZodOptional<z.ZodObject<{
705
- timestamp: z.ZodNullable<z.ZodOptional<z.ZodString>>;
706
- }, z.core.$strip>>;
707
- }, z.core.$strip>>;
708
- meta: z.ZodOptional<z.ZodObject<{
709
- timestamp: z.ZodOptional<z.ZodString>;
710
- originMutationId: z.ZodOptional<z.ZodString>;
711
- }, z.core.$strip>>;
712
- id: z.ZodString;
713
- }, z.core.$strip>;
714
- type DefaultMutationMessage = Omit<z.infer<typeof defaultMutationMsgSchema>, 'resourceId'> & {
715
- resourceId: string;
716
- };
717
- declare const mutationMsgSchema: z.ZodUnion<readonly [z.ZodObject<{
706
+ declare const mutationMsgSchema: z.ZodObject<{
718
707
  type: z.ZodLiteral<"MUTATE">;
719
708
  resource: z.ZodString;
720
709
  resourceId: z.ZodOptional<z.ZodString>;
@@ -725,13 +714,16 @@ declare const mutationMsgSchema: z.ZodUnion<readonly [z.ZodObject<{
725
714
  originMutationId: z.ZodOptional<z.ZodString>;
726
715
  }, z.core.$strip>>;
727
716
  id: z.ZodString;
728
- }, z.core.$strip>, z.ZodObject<{
729
- type: z.ZodLiteral<"MUTATE">;
717
+ }, z.core.$strip>;
718
+ type MutationMessage = z.infer<typeof mutationMsgSchema>;
719
+ declare const syncDeltaMsgSchema: z.ZodObject<{
720
+ type: z.ZodLiteral<"SYNC">;
730
721
  resource: z.ZodString;
731
- resourceId: z.ZodOptional<z.ZodString>;
732
- procedure: z.ZodEnum<{
722
+ resourceId: z.ZodString;
723
+ op: z.ZodEnum<{
733
724
  INSERT: "INSERT";
734
725
  UPDATE: "UPDATE";
726
+ DELETE: "DELETE";
735
727
  }>;
736
728
  payload: z.ZodRecord<z.ZodString, z.ZodObject<{
737
729
  value: z.ZodNullable<z.ZodAny>;
@@ -744,8 +736,8 @@ declare const mutationMsgSchema: z.ZodUnion<readonly [z.ZodObject<{
744
736
  originMutationId: z.ZodOptional<z.ZodString>;
745
737
  }, z.core.$strip>>;
746
738
  id: z.ZodString;
747
- }, z.core.$strip>]>;
748
- type MutationMessage = z.infer<typeof mutationMsgSchema>;
739
+ }, z.core.$strip>;
740
+ type SyncDeltaMessage = z.infer<typeof syncDeltaMsgSchema>;
749
741
  declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
750
742
  id: z.ZodString;
751
743
  type: z.ZodLiteral<"REJECT">;
@@ -756,12 +748,13 @@ declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
756
748
  type: z.ZodLiteral<"REPLY">;
757
749
  data: z.ZodAny;
758
750
  }, z.core.$strip>, z.ZodObject<{
759
- type: z.ZodLiteral<"MUTATE">;
751
+ type: z.ZodLiteral<"SYNC">;
760
752
  resource: z.ZodString;
761
- resourceId: z.ZodOptional<z.ZodString>;
762
- procedure: z.ZodEnum<{
753
+ resourceId: z.ZodString;
754
+ op: z.ZodEnum<{
763
755
  INSERT: "INSERT";
764
756
  UPDATE: "UPDATE";
757
+ DELETE: "DELETE";
765
758
  }>;
766
759
  payload: z.ZodRecord<z.ZodString, z.ZodObject<{
767
760
  value: z.ZodNullable<z.ZodAny>;
@@ -780,7 +773,7 @@ type ServerMessage = z.infer<typeof serverMessageSchema>;
780
773
  declare class OptimisticStore {
781
774
  readonly schema: Schema<any>;
782
775
  private rawObjPool;
783
- optimisticMutationStack: Record<string, DefaultMutationMessage[]>;
776
+ optimisticMutationStack: Record<string, SyncDeltaMessage[]>;
784
777
  customMutationStack: MutationMessage[];
785
778
  private optimisticObjGraph;
786
779
  private optimisticRawObjPool;
@@ -796,7 +789,7 @@ declare class OptimisticStore {
796
789
  constructor(schema: Schema<any>, storage: ClientOptions["storage"], logger: Logger, afterLoadMutations?: (stack: typeof this.optimisticMutationStack, customStack: MutationMessage[], customIndex: typeof this.customMutationIndex) => void, onStorageLoaded?: (resource: string, itemCount: number) => void, onQuerySubscriptionTriggered?: (query: RawQueryRequest) => void);
797
790
  get(query: RawQueryRequest, _queryKey?: string, force?: boolean): any;
798
791
  subscribe(query: RawQueryRequest, listener: (v: any[]) => void): () => void;
799
- addMutation(routeName: string, mutation: DefaultMutationMessage, optimistic?: boolean): void;
792
+ addMutation(routeName: string, mutation: SyncDeltaMessage, optimistic?: boolean): void;
800
793
  undoMutation(routeName: string, mutationId: string): void;
801
794
  addCustomMutationMessage(message: MutationMessage): void;
802
795
  registerCustomMutation(messageId: string, mutations: Array<{
@@ -810,8 +803,15 @@ declare class OptimisticStore {
810
803
  resourceId: string;
811
804
  }>;
812
805
  getCustomMutationMutationIds(): Set<string>;
813
- loadConsolidatedState(resourceType: string, data: DefaultMutationMessage["payload"][]): void;
806
+ loadConsolidatedState(resourceType: string, data: SyncDeltaMessage["payload"][]): void;
814
807
  private extractNestedRelations;
808
+ /**
809
+ * Drop a row from every local store surface in response to a scope-out
810
+ * (`DELETE`) delta, then notify subscribers so windowed queries re-derive.
811
+ * Any pending optimistic mutation for the row is left untouched — it is
812
+ * reconciled through its own reply/reject path.
813
+ */
814
+ private removeFromPool;
815
815
  private updateRawObjPool;
816
816
  private materializeOneWithInclude;
817
817
  private notifyCollectionSubscribers;
@@ -920,7 +920,7 @@ type ClientStorageLoadedEvent = {
920
920
  };
921
921
  type DataLoadRequestedEvent = {
922
922
  type: "DATA_LOAD_REQUESTED";
923
- query: RawQueryRequest | CustomQueryRequest;
923
+ query: CustomQueryRequest;
924
924
  subscriptionId: string;
925
925
  };
926
926
  type DataLoadReplyEvent = {
@@ -951,13 +951,13 @@ type MutationRejectedEvent = {
951
951
  };
952
952
  type SubscriptionCreatedEvent = {
953
953
  type: "SUBSCRIPTION_CREATED";
954
- query: RawQueryRequest | CustomQueryRequest;
954
+ query: CustomQueryRequest;
955
955
  subscriptionKey: string;
956
956
  subscriberCount: number;
957
957
  };
958
958
  type SubscriptionRemovedEvent = {
959
959
  type: "SUBSCRIPTION_REMOVED";
960
- query: RawQueryRequest | CustomQueryRequest;
960
+ query: CustomQueryRequest;
961
961
  subscriptionKey: string;
962
962
  };
963
963
  type QueryExecutedEvent = {
@@ -1000,7 +1000,7 @@ type Client<TRouter extends ClientRouterConstraint> = {
1000
1000
  ws: WebSocketClient;
1001
1001
  readonly bootstrapStatus: ClientBootstrapStatus;
1002
1002
  addEventListener: (listener: (event: ClientEvents) => void) => () => void;
1003
- load: (query: RawQueryRequest | CustomQueryRequest) => () => void;
1003
+ load: (query: CustomQueryRequest) => () => void;
1004
1004
  };
1005
1005
  store: Client$1<TRouter>;
1006
1006
  };
@@ -1016,7 +1016,7 @@ type ClientState = {
1016
1016
  };
1017
1017
  declare const useClientState: (client: Client<ClientRouterConstraint>["client"]) => ClientState;
1018
1018
  declare const useLoadData: (client: Client<ClientRouterConstraint>["client"], query: {
1019
- buildQueryRequest: () => RawQueryRequest | CustomQueryRequest;
1019
+ buildQueryRequest: () => CustomQueryRequest;
1020
1020
  }) => void;
1021
1021
 
1022
1022
  type ClientOptions<TSchema extends Schema<any> = Schema<any>> = {
@@ -1,3 +1,3 @@
1
- export { e as OptimisticHandlerContext, h as OptimisticInsertOperation, j as OptimisticMutationHandler, O as OptimisticMutationsConfig, c as OptimisticMutationsRegistry, g as OptimisticOperation, f as OptimisticStorageProxy, i as OptimisticUpdateOperation, k as createOptimisticStorageProxy, d as defineOptimisticMutations } from './index-C0Qm5yHg.js';
1
+ export { e as OptimisticHandlerContext, h as OptimisticInsertOperation, j as OptimisticMutationHandler, O as OptimisticMutationsConfig, c as OptimisticMutationsRegistry, g as OptimisticOperation, f as OptimisticStorageProxy, i as OptimisticUpdateOperation, k as createOptimisticStorageProxy, d as defineOptimisticMutations } from './index-DjBla1td.js';
2
2
  import '@standard-schema/spec';
3
3
  import 'zod';