@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.
- package/dist/chunk-YPTDCIAN.js +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +1 -1
- package/dist/fetch-client.js +1 -1
- package/dist/{index-C0Qm5yHg.d.ts → index-DjBla1td.d.ts} +75 -75
- package/dist/optimistic-client.d.ts +1 -1
- package/dist/server.cjs +6 -6
- package/dist/server.d.cts +183 -240
- package/dist/server.d.ts +183 -240
- package/dist/server.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-LSAVBBUS.js +0 -1
|
@@ -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-
|
|
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};
|
package/dist/fetch-client.d.ts
CHANGED
package/dist/fetch-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
|
560
|
-
*
|
|
561
|
-
*
|
|
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
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
|
579
|
-
[K2 in keyof TRoute[
|
|
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
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
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[
|
|
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[
|
|
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
|
|
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
|
|
729
|
-
|
|
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.
|
|
732
|
-
|
|
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
|
|
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<"
|
|
751
|
+
type: z.ZodLiteral<"SYNC">;
|
|
760
752
|
resource: z.ZodString;
|
|
761
|
-
resourceId: z.
|
|
762
|
-
|
|
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,
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
954
|
+
query: CustomQueryRequest;
|
|
955
955
|
subscriptionKey: string;
|
|
956
956
|
subscriberCount: number;
|
|
957
957
|
};
|
|
958
958
|
type SubscriptionRemovedEvent = {
|
|
959
959
|
type: "SUBSCRIPTION_REMOVED";
|
|
960
|
-
query:
|
|
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:
|
|
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: () =>
|
|
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-
|
|
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';
|