@live-state/sync 0.0.6-canary-14 → 0.0.6-canary-15
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/client.d.ts +1 -3
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +2 -4
- package/dist/fetch-client.js +1 -1
- package/dist/{index-DixUPrmV.d.ts → index-DgP3OR1v.d.ts} +40 -183
- package/dist/server.d.cts +12 -12
- package/dist/server.d.ts +12 -12
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { f as Client, e as ClientEvents, C as ClientOptions, a as ClientRouterConstraint, d as ConnectionStateChangeEvent, M as MessageReceivedEvent, g as createClient, u as useLiveQuery, c as useLoadData } from './index-DgP3OR1v.js';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import 'zod/v3';
|
|
4
|
-
import 'zod/v4/core';
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {d,c,a,f,e,b as b$1}from'./chunk-AHF6GNMI.js';import {useSyncExternalStore,useEffect}from'react';import {xxHash32}from'js-xxhash';import {z}from'zod';import {stringify}from'qs';import le from'fast-deep-equal';import {openDB}from'idb';var g=u=>xxHash32(JSON.stringify(u)).toString(32);var b=(u,e,t=false)=>Object.entries(e).every(([i,s])=>{if(i==="$and")return s.every(o=>b(u,o,t));if(i==="$or")return s.some(o=>b(u,o,t));let r=(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 n=u[i];return n===void 0?false:t?!s.$in.includes(n):s.$in.includes(n)}if(s.$not!==void 0&&!t)return b(u,{[i]:s.$not},true);if(s.$gt!==void 0){let n=u[i];return typeof n!="number"?false:t?n<=s.$gt:n>s.$gt}if(s.$gte!==void 0){let n=u[i];return typeof n!="number"?false:t?n<s.$gte:n>=s.$gte}if(s.$lt!==void 0){let n=u[i];return typeof n!="number"?false:t?n>=s.$lt:n<s.$lt}if(s.$lte!==void 0){let n=u[i];return typeof n!="number"?false:t?n>s.$lte:n<=s.$lte}let o=u[i];return !o||typeof o!="object"&&!Array.isArray(o)?false:Array.isArray(o)?t?!o.some(n=>b(n,s,false)):o.some(n=>b(n,s,false)):b(o,s,t)}return t?u[i]!==r:u[i]===r}),v={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},j=class{level;prefix;constructor(e={}){this.level=e.level??v.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=v.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=v.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=v.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=v.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=v.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},G=u=>new j(u);var x=class{subscriptions=new Map;getOrStoreSubscription(e){let t=g(e);return this.subscriptions.has(t)?this.subscriptions.get(t).subscribe:(this.subscriptions.set(t,{subscribe:i=>{var r;(r=this.subscriptions.get(t))==null||r.callbacks.add(i);let s=e.subscribe(()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.forEach(n=>{n();});});return ()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.delete(i),setTimeout(()=>{var n;((n=this.subscriptions.get(t))==null?void 0:n.callbacks.size)===0&&(this.subscriptions.delete(t),s());},10);}},callbacks:new Set}),this.subscriptions.get(t).subscribe)}},X=new x,ye=u=>useSyncExternalStore(X.getOrStoreSubscription(u),u.get),fe=(u,e)=>{useEffect(()=>{let t=u.load(e.buildQueryRequest());return ()=>{t();}},[e,u.load]);};var w=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()}),A=z.record(z.string(),z.object({value:z.any().nullable(),_meta:z.object({timestamp:z.string().optional().nullable()}).optional()})),ee=A.superRefine((u,e)=>{u.id&&e.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),U=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string(),resourceId:z.string().optional()}),k=U.extend({procedure:z.string(),payload:z.any().optional()}),P=U.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:ee});z.union([P,k]);var M=z.string(),te=w.extend({id:M,type:z.literal("SUBSCRIBE")}),ie=w.extend({id:M,type:z.literal("UNSUBSCRIBE")}),se=w.extend({id:M,type:z.literal("QUERY")}),Q=P.extend({id:M}),ne=k.extend({id:M}),re=z.union([ne,Q]);z.union([te,se,re,ie]);var oe=z.object({id:M,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),ae=z.object({id:M,type:z.literal("REPLY"),data:z.any()}),H=z.union([oe,ae,Q]),q=z.object({resource:z.string(),data:z.array(A)});var O=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$1(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 R=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(r=>[r,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 r=s.referencedBy.get(i.type);r&&r instanceof Set?r.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 r=this.nodes.get(s);if(!r)return;let o=r.referencedBy.get(i.type);o&&(o instanceof Set?o.delete(e):r.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(o=>{let n=this.nodes.get(o);!n||!n.references.get(i)||(n.references.delete(i),this.notifySubscribers(o));});}),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(r){(s=this.logger)==null||s.error(`Error in node subscription for node ${e}:`,r);}});}getAllNodes(){return Array.from(this.nodes.values())}};var W="__meta",L="databases",C=class{db;async init(e,t){var p,d;if(typeof window>"u")return;let s=((p=(await window.indexedDB.databases()).find(c=>c.name===t))==null?void 0:p.version)??1,r=await g(e),o=Object.fromEntries(await Promise.all(Object.entries(e).map(async([c,l])=>[c,await g(l)]))),n=await openDB("live-state-databases",1,{upgrade(c){c.objectStoreNames.contains(L)||c.createObjectStore(L);}}),a=(d=await this.getAll(n,L))==null?void 0:d[t];(a==null?void 0:a.schemaHash)!==r&&s++,this.db=await openDB(t,s,{async upgrade(c){[...Object.keys(e),W].forEach(l=>{(a==null?void 0:a.objectHashes[l])!==o[l]&&c.objectStoreNames.contains(l)&&c.deleteObjectStore(l),c.objectStoreNames.contains(l)||c.createObjectStore(l);}),await n.put(L,{schemaHash:r,objectHashes:o},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(W,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(W,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((r,o)=>[s[o],r]))}};var T=class{constructor(e,t,i,s){this.schema=e;this.logger=i,this.optimisticObjGraph=new R(i),this.kvStorage=new C,t!==false&&this.kvStorage.init(this.schema,t.name).then(()=>{this.kvStorage.getMeta("mutationStack").then(r=>{!r||Object.keys(r).length===0||(this.optimisticMutationStack=r,s==null||s(this.optimisticMutationStack));}).then(()=>{Object.entries(this.schema).forEach(([r])=>{this.kvStorage.get(r).then(o=>{if(!o||Object.keys(o).length===0)return;let n=Object.values(o);this.loadConsolidatedState(r,n);});});}).catch(r=>{i.debug("Storage initialization failed (may not be available in this environment):",r);});});}rawObjPool={};optimisticMutationStack={};optimisticObjGraph;optimisticRawObjPool={};logger;collectionSubscriptions=new Map;querySnapshots={};kvStorage;get(e$1,t,i=false){var o;let s=t??g(e$1);if(this.querySnapshots[s]&&!i){let n=this.querySnapshots[s];if(n)return n}let r=((o=e$1.where)!=null&&o.id?[e$1.where.id]:Object.keys(this.optimisticRawObjPool[e$1.resource]??{})).flatMap(n=>{let a=f(this.materializeOneWithInclude(n,e$1.include));return a?[a]:[]});if(e$1.sort&&e$1.sort.length>0){let n=(a,p)=>{for(let d of e$1.sort){let c=a[d.key],l=p[d.key];if(c<l)return d.direction==="asc"?-1:1;if(c>l)return d.direction==="asc"?1:-1}return 0};r.sort(n);}if(e$1.where||e$1.limit){let n=e$1.where?a=>b(a,e$1.where):()=>true;r=e(r,n,e$1.limit);}return i||(this.querySnapshots[s]=r),r}subscribe(e,t){var r;let i=g(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 o,n;(o=this.collectionSubscriptions.get(i))==null||o.callbacks.delete(t),((n=this.collectionSubscriptions.get(i))==null?void 0:n.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var o,n,a;let s=this.schema[e];if(this.logger.debug("Adding mutation",t),!s)throw new Error("Schema not found");let r=(o=this.optimisticRawObjPool[e])==null?void 0:o[t.resourceId];if(i)this.optimisticMutationStack[e]??=[],this.optimisticMutationStack[e].push(t);else {this.optimisticMutationStack[e]=((a=(n=this.optimisticMutationStack)==null?void 0:n[e])==null?void 0:a.filter(c=>c.id!==t.id))??[],this.rawObjPool[e]??={};let p={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=p;let d=p.value;delete d.id,this.kvStorage.set(e,t.resourceId,d);}this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,t.resourceId,t.payload,r);}undoMutation(e,t){var o,n;if(!this.optimisticMutationStack[e])return;let i=(o=this.optimisticMutationStack[e])==null?void 0:o.findIndex(a=>a.id===t);if(i===-1)return;let s=this.optimisticMutationStack[e][i];this.logger.debug("Removing mutation",s);let r=(n=this.optimisticRawObjPool[e])==null?void 0:n[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:{}}])),r);}loadConsolidatedState(e,t){t.forEach(i=>{var n;let s=(n=i.id)==null?void 0:n.value;if(!s)return;let{cleanedPayload:r,nestedMutations:o}=this.extractNestedRelations(e,i);o.forEach(a=>{this.addMutation(a.resource,a);}),this.addMutation(e,{id:s,type:"MUTATE",resource:e,resourceId:s,procedure:"INSERT",payload:r});});}extractNestedRelations(e,t){let i=this.schema[e],s={...t},r=[];return i!=null&&i.relations?(Object.entries(t).forEach(([o,n])=>{var c;let a=i.relations[o];if(!a)return;let p=a.entity.name,d=n==null?void 0:n.value;if(a.type==="one"){if(d&&typeof d=="object"&&!Array.isArray(d)&&((c=d.id)!=null&&c.value)){let l=d.id.value,f={...d},{cleanedPayload:m,nestedMutations:S}=this.extractNestedRelations(p,f);r.push(...S),r.push({id:l,type:"MUTATE",resource:p,resourceId:l,procedure:"INSERT",payload:m}),delete s[o];}}else a.type==="many"&&Array.isArray(d)&&(d.forEach(l=>{var f,m;if(l&&typeof l=="object"&&!Array.isArray(l)&&((m=(f=l.value)==null?void 0:f.id)!=null&&m.value)){let S=l.value.id.value,_={...l.value},{cleanedPayload:F,nestedMutations:V}=this.extractNestedRelations(p,_);r.push(...V),r.push({id:S,type:"MUTATE",resource:p,resourceId:S,procedure:"INSERT",payload:F});}}),delete s[o]);}),{cleanedPayload:s,nestedMutations:r}):{cleanedPayload:s,nestedMutations:r}}updateRawObjPool(e,t,i,s){var n;if(!this.schema[e])return;let r=(n=this.rawObjPool[e])==null?void 0:n[t],o=(this.optimisticMutationStack[e]??[]).reduce((a,p)=>p.resourceId!==t?a:this.schema[e].mergeMutation("set",p.payload,a)[0],r);if(this.optimisticRawObjPool[e]??={},o?this.optimisticRawObjPool[e][t]={value:{...o.value,id:{value:t}}}:delete this.optimisticRawObjPool[e][t],!(!this.optimisticObjGraph.hasNode(t)&&!o)){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(([p,d])=>d.type==="one"?[[d.relationalColumn,p]]:[]));Object.entries(i).forEach(([p,d])=>{let c=this.schema[e].relations[a[p]];if(!a[p])return;let l=s==null?void 0:s.value[p],[,f]=c.mergeMutation("set",d,l);if(f){if(!this.optimisticObjGraph.hasNode(f.value)){let m=c.entity.name;this.optimisticObjGraph.createNode(f.value,m,Object.values(this.schema[m].relations).flatMap(S=>S.type==="many"?[S.entity.name]:[]));}l!=null&&l.value&&this.optimisticObjGraph.removeLink(t,c.entity.name),this.optimisticObjGraph.createLink(t,f.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,r=(a=this.optimisticRawObjPool[s])==null?void 0:a[e];if(!r)return;let[o,n]=Object.entries(t).reduce((p,[d,c])=>{let l=this.schema[s].relations[d];return l&&(l.type==="one"?p[0].push([d,l.entity.name,c??true]):l.type==="many"&&p[1].push([d,l.entity.name,c??true])),p},[[],[]]);return {value:{...r.value,...Object.fromEntries(o.map(([p,d,c])=>[p,this.materializeOneWithInclude(i.references.get(d),typeof c=="object"&&c!==null?c:{})])),...Object.fromEntries(n.map(([p,d,c])=>{let l=i.referencedBy.get(d),f=l instanceof Set;return [p,f?{value:Array.from(l.values()).map(m=>this.materializeOneWithInclude(m,typeof c=="object"&&c!==null?c:{}))}:this.materializeOneWithInclude(l,typeof c=="object"&&c!==null?c:{})]}))}}}notifyCollectionSubscribers(e){this.collectionSubscriptions.forEach(t=>{if(t.query.resource===e||t.flatInclude&&t.flatInclude.includes(e)){let i=g(t.query),s=this.querySnapshots[i],r=this.get(t.query,void 0,true);if(le(r,s))return;this.querySnapshots[i]=r,t.callbacks.forEach(o=>{o(r);});}});}flattenIncludes(e,t){let i=[];return Object.entries(e).forEach(([s,r])=>{var a;let o=(a=this.schema[t])==null?void 0:a.relations[s];if(!o)return;let n=o.entity.name;i.push(n),typeof r=="object"&&r!==null&&i.push(...this.flattenIncludes(r,n));}),Array.from(new Set(i))}};var D=class{url;ws;store;logger;remoteSubscriptions=new Map;eventListeners=new Set;replyHandlers={};constructor(e){var t,i,s,r;this.url=e.url,this.logger=G({level:e.logLevel??v.INFO}),this.store=new T(e.schema,e.storage,this.logger,o=>{var n,a;(a=(n=Object.values(o))==null?void 0:n.flat())==null||a.forEach(p=>{this.sendWsMessage(p);});}),this.ws=new O({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:(r=e.connection)==null?void 0:r.maxReconnectAttempts,credentials:e.credentials}),this.ws.addEventListener("message",o=>{this.handleServerMessage(o.data);}),this.ws.addEventListener("connectionChange",o=>{this.emitEvent({type:"CONNECTION_STATE_CHANGE",open:o.open}),o.open&&(Array.from(this.remoteSubscriptions.values()).forEach(({query:n})=>{this.sendWsMessage({id:a(),type:"SUBSCRIBE",...n});}),Object.values(this.store.optimisticMutationStack).forEach(n=>{n&&n.forEach(a=>{this.sendWsMessage(a);});}));});}get(e){return this.store.get(e)}handleServerMessage(e){try{this.logger.debug("Message received from the server:",e);let t=H.parse(JSON.parse(e));if(this.logger.debug("Parsed message:",t),this.emitEvent({type:"MESSAGE_RECEIVED",message:t}),t.type==="MUTATE"){let{resource:i}=t;try{this.store.addMutation(i,t);}catch(s){this.logger.error("Error merging mutation from the server:",s);}}else if(t.type==="REJECT")this.store.undoMutation(t.resource,t.id);else if(t.type==="REPLY"){let{id:i,data:s}=t;if(this.replyHandlers[i]){clearTimeout(this.replyHandlers[i].timeoutHandle),this.replyHandlers[i].handler(s);return}let r=q.parse(s);this.store.loadConsolidatedState(r.resource,r.data);}}catch(t){this.logger.error("Error parsing message from the server:",t);}}load(e){this.sendWsMessage({id:a(),type:"SUBSCRIBE",...e});let t=g(e);return this.remoteSubscriptions.has(t)?this.remoteSubscriptions.get(t).subCounter+=1:this.remoteSubscriptions.set(t,{query:e,subCounter:1}),()=>{this.remoteSubscriptions.has(t)&&(this.remoteSubscriptions.get(t).subCounter-=1,this.remoteSubscriptions.get(t).subCounter<=0&&(this.remoteSubscriptions.delete(t),this.sendWsMessage({id:a(),type:"UNSUBSCRIBE",...e})));}}subscribe(e,t){return this.store.subscribe(e,t)}mutate(e,t,i,s){var o;let r={id:a(),type:"MUTATE",resource:e,payload:this.store.schema[e].encodeMutation("set",s,new Date().toISOString()),resourceId:t,procedure:i};(o=this.store)==null||o.addMutation(e,r,true),this.sendWsMessage(r);}genericMutate(e,t,i){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let s={id:a(),type:"MUTATE",resource:e,procedure:t,payload:i};return this.sendWsMessage(s),new Promise((r,o)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],o(new Error("Reply timeout"));},5e3),handler:n=>{delete this.replyHandlers[s.id],r(n);}};})}addEventListener(e){return this.eventListeners.add(e),()=>{this.eventListeners.delete(e);}}sendWsMessage(e){var t;(t=this.ws)!=null&&t.connected()&&this.ws.send(JSON.stringify(e));}emitEvent(e){this.eventListeners.forEach(t=>{t(e);});}},qe=u=>{let e=new D(u);return {client:{ws:e.ws,load:t=>e.load(t),addEventListener:t=>e.addEventListener(t)},store:{query:Object.entries(u.schema).reduce((t,[i,s])=>(t[i]=c._init(s,e),t),{}),mutate:d(()=>{},{apply:(t,i,s)=>{if(i.length<2)return;if(i.length>2)throw new Error("Trying to access an invalid path");let[r,o]=i;if(o==="insert"){let{id:n,...a}=s[0];return e.mutate(r,n,"INSERT",a)}if(o==="update"){let[n,a]=s;return e.mutate(r,n,"UPDATE",a)}return e.genericMutate(r,o,s[0])}})}}};export{qe as createClient,ye as useLiveQuery,fe as useLoadData};
|
|
1
|
+
import {d,c,a,f,e,b as b$1}from'./chunk-AHF6GNMI.js';import {useSyncExternalStore,useEffect}from'react';import {xxHash32}from'js-xxhash';import {z}from'zod';import {stringify}from'qs';import le from'fast-deep-equal';import {openDB}from'idb';var g=u=>xxHash32(JSON.stringify(u)).toString(32);var b=(u,e,t=false)=>Object.entries(e).every(([i,s])=>{if(i==="$and")return s.every(o=>b(u,o,t));if(i==="$or")return s.some(o=>b(u,o,t));let r=(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 n=u[i];return n===void 0?false:t?!s.$in.includes(n):s.$in.includes(n)}if(s.$not!==void 0&&!t)return b(u,{[i]:s.$not},true);if(s.$gt!==void 0){let n=u[i];return typeof n!="number"?false:t?n<=s.$gt:n>s.$gt}if(s.$gte!==void 0){let n=u[i];return typeof n!="number"?false:t?n<s.$gte:n>=s.$gte}if(s.$lt!==void 0){let n=u[i];return typeof n!="number"?false:t?n>=s.$lt:n<s.$lt}if(s.$lte!==void 0){let n=u[i];return typeof n!="number"?false:t?n>s.$lte:n<=s.$lte}let o=u[i];return !o||typeof o!="object"&&!Array.isArray(o)?false:Array.isArray(o)?t?!o.some(n=>b(n,s,false)):o.some(n=>b(n,s,false)):b(o,s,t)}return t?u[i]!==r:u[i]===r}),v={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},j=class{level;prefix;constructor(e={}){this.level=e.level??v.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=v.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=v.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=v.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=v.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=v.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},G=u=>new j(u);var x=class{subscriptions=new Map;getOrStoreSubscription(e){let t=g(e);return this.subscriptions.has(t)?this.subscriptions.get(t).subscribe:(this.subscriptions.set(t,{subscribe:i=>{var r;(r=this.subscriptions.get(t))==null||r.callbacks.add(i);let s=e.subscribe(()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.forEach(n=>{n();});});return ()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.delete(i),setTimeout(()=>{var n;((n=this.subscriptions.get(t))==null?void 0:n.callbacks.size)===0&&(this.subscriptions.delete(t),s());},10);}},callbacks:new Set}),this.subscriptions.get(t).subscribe)}},X=new x,ye=u=>useSyncExternalStore(X.getOrStoreSubscription(u),u.get),fe=(u,e)=>{useEffect(()=>{let t=u.load(e.buildQueryRequest());return ()=>{t();}},[e,u.load]);};var w=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()}),A=z.record(z.string(),z.object({value:z.any().nullable(),_meta:z.object({timestamp:z.string().optional().nullable()}).optional()})),ee=A.superRefine((u,e)=>{u.id&&e.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),U=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string(),resourceId:z.string().optional()}),k=U.extend({procedure:z.string(),payload:z.any().optional()}),P=U.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:ee});z.union([P,k]);var M=z.string(),te=w.extend({id:M,type:z.literal("SUBSCRIBE")}),ie=w.extend({id:M,type:z.literal("UNSUBSCRIBE")}),se=w.extend({id:M,type:z.literal("QUERY")}),Q=P.extend({id:M}),ne=k.extend({id:M}),re=z.union([ne,Q]);z.union([te,se,re,ie]);var oe=z.object({id:M,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),ae=z.object({id:M,type:z.literal("REPLY"),data:z.any()}),H=z.union([oe,ae,Q]),q=z.object({resource:z.string(),data:z.array(A)});var R=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$1(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 O=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(r=>[r,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 r=s.referencedBy.get(i.type);r&&r instanceof Set?r.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 r=this.nodes.get(s);if(!r)return;let o=r.referencedBy.get(i.type);o&&(o instanceof Set?o.delete(e):r.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(o=>{let n=this.nodes.get(o);!n||!n.references.get(i)||(n.references.delete(i),this.notifySubscribers(o));});}),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(r){(s=this.logger)==null||s.error(`Error in node subscription for node ${e}:`,r);}});}getAllNodes(){return Array.from(this.nodes.values())}};var W="__meta",C="databases",L=class{db;async init(e,t){var p,d;if(typeof window>"u")return;let s=((p=(await window.indexedDB.databases()).find(c=>c.name===t))==null?void 0:p.version)??1,r=await g(e),o=Object.fromEntries(await Promise.all(Object.entries(e).map(async([c,l])=>[c,await g(l)]))),n=await openDB("live-state-databases",1,{upgrade(c){c.objectStoreNames.contains(C)||c.createObjectStore(C);}}),a=(d=await this.getAll(n,C))==null?void 0:d[t];(a==null?void 0:a.schemaHash)!==r&&s++,this.db=await openDB(t,s,{async upgrade(c){[...Object.keys(e),W].forEach(l=>{(a==null?void 0:a.objectHashes[l])!==o[l]&&c.objectStoreNames.contains(l)&&c.deleteObjectStore(l),c.objectStoreNames.contains(l)||c.createObjectStore(l);}),await n.put(C,{schemaHash:r,objectHashes:o},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(W,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(W,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((r,o)=>[s[o],r]))}};var T=class{constructor(e,t,i,s){this.schema=e;this.logger=i,this.optimisticObjGraph=new O(i),this.kvStorage=new L,t!==false&&this.kvStorage.init(this.schema,t.name).then(()=>{this.kvStorage.getMeta("mutationStack").then(r=>{!r||Object.keys(r).length===0||(this.optimisticMutationStack=r,s==null||s(this.optimisticMutationStack));}).then(()=>{Object.entries(this.schema).forEach(([r])=>{this.kvStorage.get(r).then(o=>{if(!o||Object.keys(o).length===0)return;let n=Object.values(o);this.loadConsolidatedState(r,n);});});}).catch(r=>{i.debug("Storage initialization failed (may not be available in this environment):",r);});});}rawObjPool={};optimisticMutationStack={};optimisticObjGraph;optimisticRawObjPool={};logger;collectionSubscriptions=new Map;querySnapshots={};kvStorage;get(e$1,t,i=false){var o;let s=t??g(e$1);if(this.querySnapshots[s]&&!i){let n=this.querySnapshots[s];if(n)return n}let r=((o=e$1.where)!=null&&o.id?[e$1.where.id]:Object.keys(this.optimisticRawObjPool[e$1.resource]??{})).flatMap(n=>{let a=f(this.materializeOneWithInclude(n,e$1.include));return a?[a]:[]});if(e$1.sort&&e$1.sort.length>0){let n=(a,p)=>{for(let d of e$1.sort){let c=a[d.key],l=p[d.key];if(c<l)return d.direction==="asc"?-1:1;if(c>l)return d.direction==="asc"?1:-1}return 0};r.sort(n);}if(e$1.where||e$1.limit){let n=e$1.where?a=>b(a,e$1.where):()=>true;r=e(r,n,e$1.limit);}return i||(this.querySnapshots[s]=r),r}subscribe(e,t){var r;let i=g(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 o,n;(o=this.collectionSubscriptions.get(i))==null||o.callbacks.delete(t),((n=this.collectionSubscriptions.get(i))==null?void 0:n.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var o,n,a;let s=this.schema[e];if(this.logger.debug("Adding mutation",t),!s)throw new Error("Schema not found");let r=(o=this.optimisticRawObjPool[e])==null?void 0:o[t.resourceId];if(i)this.optimisticMutationStack[e]??=[],this.optimisticMutationStack[e].push(t);else {this.optimisticMutationStack[e]=((a=(n=this.optimisticMutationStack)==null?void 0:n[e])==null?void 0:a.filter(c=>c.id!==t.id))??[],this.rawObjPool[e]??={};let p={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=p;let d=p.value;delete d.id,this.kvStorage.set(e,t.resourceId,d);}this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,t.resourceId,t.payload,r);}undoMutation(e,t){var o,n;if(!this.optimisticMutationStack[e])return;let i=(o=this.optimisticMutationStack[e])==null?void 0:o.findIndex(a=>a.id===t);if(i===-1)return;let s=this.optimisticMutationStack[e][i];this.logger.debug("Removing mutation",s);let r=(n=this.optimisticRawObjPool[e])==null?void 0:n[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:{}}])),r);}loadConsolidatedState(e,t){t.forEach(i=>{var n;let s=(n=i.id)==null?void 0:n.value;if(!s)return;let{cleanedPayload:r,nestedMutations:o}=this.extractNestedRelations(e,i);o.forEach(a=>{this.addMutation(a.resource,a);}),this.addMutation(e,{id:s,type:"MUTATE",resource:e,resourceId:s,procedure:"INSERT",payload:r});});}extractNestedRelations(e,t){let i=this.schema[e],s={...t},r=[];return i!=null&&i.relations?(Object.entries(t).forEach(([o,n])=>{var c;let a=i.relations[o];if(!a)return;let p=a.entity.name,d=n==null?void 0:n.value;if(a.type==="one"){if(d&&typeof d=="object"&&!Array.isArray(d)&&((c=d.id)!=null&&c.value)){let l=d.id.value,f={...d},{cleanedPayload:m,nestedMutations:S}=this.extractNestedRelations(p,f);r.push(...S),r.push({id:l,type:"MUTATE",resource:p,resourceId:l,procedure:"INSERT",payload:m}),delete s[o];}}else a.type==="many"&&Array.isArray(d)&&(d.forEach(l=>{var f,m;if(l&&typeof l=="object"&&!Array.isArray(l)&&((m=(f=l.value)==null?void 0:f.id)!=null&&m.value)){let S=l.value.id.value,_={...l.value},{cleanedPayload:F,nestedMutations:V}=this.extractNestedRelations(p,_);r.push(...V),r.push({id:S,type:"MUTATE",resource:p,resourceId:S,procedure:"INSERT",payload:F});}}),delete s[o]);}),{cleanedPayload:s,nestedMutations:r}):{cleanedPayload:s,nestedMutations:r}}updateRawObjPool(e,t,i,s){var n;if(!this.schema[e])return;let r=(n=this.rawObjPool[e])==null?void 0:n[t],o=(this.optimisticMutationStack[e]??[]).reduce((a,p)=>p.resourceId!==t?a:this.schema[e].mergeMutation("set",p.payload,a)[0],r);if(this.optimisticRawObjPool[e]??={},o?this.optimisticRawObjPool[e][t]={value:{...o.value,id:{value:t}}}:delete this.optimisticRawObjPool[e][t],!(!this.optimisticObjGraph.hasNode(t)&&!o)){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(([p,d])=>d.type==="one"?[[d.relationalColumn,p]]:[]));Object.entries(i).forEach(([p,d])=>{let c=this.schema[e].relations[a[p]];if(!a[p])return;let l=s==null?void 0:s.value[p],[,f]=c.mergeMutation("set",d,l);if(f){if(!this.optimisticObjGraph.hasNode(f.value)){let m=c.entity.name;this.optimisticObjGraph.createNode(f.value,m,Object.values(this.schema[m].relations).flatMap(S=>S.type==="many"?[S.entity.name]:[]));}l!=null&&l.value&&this.optimisticObjGraph.removeLink(t,c.entity.name),this.optimisticObjGraph.createLink(t,f.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,r=(a=this.optimisticRawObjPool[s])==null?void 0:a[e];if(!r)return;let[o,n]=Object.entries(t).reduce((p,[d,c])=>{let l=this.schema[s].relations[d];return l&&(l.type==="one"?p[0].push([d,l.entity.name,c??true]):l.type==="many"&&p[1].push([d,l.entity.name,c??true])),p},[[],[]]);return {value:{...r.value,...Object.fromEntries(o.map(([p,d,c])=>[p,this.materializeOneWithInclude(i.references.get(d),typeof c=="object"&&c!==null?c:{})])),...Object.fromEntries(n.map(([p,d,c])=>{let l=i.referencedBy.get(d),f=l instanceof Set;return [p,f?{value:Array.from(l.values()).map(m=>this.materializeOneWithInclude(m,typeof c=="object"&&c!==null?c:{}))}:this.materializeOneWithInclude(l,typeof c=="object"&&c!==null?c:{})]}))}}}notifyCollectionSubscribers(e){this.collectionSubscriptions.forEach(t=>{if(t.query.resource===e||t.flatInclude&&t.flatInclude.includes(e)){let i=g(t.query),s=this.querySnapshots[i],r=this.get(t.query,void 0,true);if(le(r,s))return;this.querySnapshots[i]=r,t.callbacks.forEach(o=>{o(r);});}});}flattenIncludes(e,t){let i=[];return Object.entries(e).forEach(([s,r])=>{var a;let o=(a=this.schema[t])==null?void 0:a.relations[s];if(!o)return;let n=o.entity.name;i.push(n),typeof r=="object"&&r!==null&&i.push(...this.flattenIncludes(r,n));}),Array.from(new Set(i))}};var D=class{url;ws;store;logger;remoteSubscriptions=new Map;eventListeners=new Set;replyHandlers={};constructor(e){var t,i,s,r;this.url=e.url,this.logger=G({level:e.logLevel??v.INFO}),this.store=new T(e.schema,e.storage,this.logger,o=>{var n,a;(a=(n=Object.values(o))==null?void 0:n.flat())==null||a.forEach(p=>{this.sendWsMessage(p);});}),this.ws=new R({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:(r=e.connection)==null?void 0:r.maxReconnectAttempts,credentials:e.credentials}),this.ws.addEventListener("message",o=>{this.handleServerMessage(o.data);}),this.ws.addEventListener("connectionChange",o=>{this.emitEvent({type:"CONNECTION_STATE_CHANGE",open:o.open}),o.open&&(Array.from(this.remoteSubscriptions.values()).forEach(({query:n})=>{this.sendWsMessage({id:a(),type:"SUBSCRIBE",...n});}),Object.values(this.store.optimisticMutationStack).forEach(n=>{n&&n.forEach(a=>{this.sendWsMessage(a);});}));});}get(e){return this.store.get(e)}handleServerMessage(e){try{this.logger.debug("Message received from the server:",e);let t=H.parse(JSON.parse(e));if(this.logger.debug("Parsed message:",t),this.emitEvent({type:"MESSAGE_RECEIVED",message:t}),t.type==="MUTATE"){let{resource:i}=t;try{this.store.addMutation(i,t);}catch(s){this.logger.error("Error merging mutation from the server:",s);}}else if(t.type==="REJECT")this.store.undoMutation(t.resource,t.id);else if(t.type==="REPLY"){let{id:i,data:s}=t;if(this.replyHandlers[i]){clearTimeout(this.replyHandlers[i].timeoutHandle),this.replyHandlers[i].handler(s);return}let r=q.parse(s);this.store.loadConsolidatedState(r.resource,r.data);}}catch(t){this.logger.error("Error parsing message from the server:",t);}}load(e){this.sendWsMessage({id:a(),type:"SUBSCRIBE",...e});let t=g(e);return this.remoteSubscriptions.has(t)?this.remoteSubscriptions.get(t).subCounter+=1:this.remoteSubscriptions.set(t,{query:e,subCounter:1}),()=>{this.remoteSubscriptions.has(t)&&(this.remoteSubscriptions.get(t).subCounter-=1,this.remoteSubscriptions.get(t).subCounter<=0&&(this.remoteSubscriptions.delete(t),this.sendWsMessage({id:a(),type:"UNSUBSCRIBE",...e})));}}subscribe(e,t){return this.store.subscribe(e,t)}mutate(e,t,i,s){var o;let r={id:a(),type:"MUTATE",resource:e,payload:this.store.schema[e].encodeMutation("set",s,new Date().toISOString()),resourceId:t,procedure:i};(o=this.store)==null||o.addMutation(e,r,true),this.sendWsMessage(r);}genericMutate(e,t,i){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let s={id:a(),type:"MUTATE",resource:e,procedure:t,payload:i};return this.sendWsMessage(s),new Promise((r,o)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],o(new Error("Reply timeout"));},5e3),handler:n=>{delete this.replyHandlers[s.id],r(n);}};})}addEventListener(e){return this.eventListeners.add(e),()=>{this.eventListeners.delete(e);}}sendWsMessage(e){var t;(t=this.ws)!=null&&t.connected()&&this.ws.send(JSON.stringify(e));}emitEvent(e){this.eventListeners.forEach(t=>{t(e);});}},qe=u=>{let e=new D(u);return {client:{ws:e.ws,load:t=>e.load(t),addEventListener:t=>e.addEventListener(t)},store:{query:Object.entries(u.schema).reduce((t,[i,s])=>(t[i]=c._init(s,e),t),{}),mutate:d(()=>{},{apply:(t,i,s)=>{if(i.length<2)return;if(i.length>2)throw new Error("Trying to access an invalid path");let[r,o]=i;if(o==="insert"){let{id:n,...a}=s[0];return e.mutate(r,n,"INSERT",a)}if(o==="update"){let[n,a]=s;return e.mutate(r,n,"UPDATE",a)}return e.genericMutate(r,o,s[0])}})}}};export{qe as createClient,ye as useLiveQuery,fe as useLoadData};
|
package/dist/fetch-client.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { C as ClientOptions,
|
|
1
|
+
import { C as ClientOptions, a as ClientRouterConstraint, b as Client } from './index-DgP3OR1v.js';
|
|
2
2
|
import 'zod';
|
|
3
|
-
import 'zod/v3';
|
|
4
|
-
import 'zod/v4/core';
|
|
5
3
|
|
|
6
4
|
type FetchClientOptions = Omit<ClientOptions, "storage"> & {
|
|
7
5
|
fetchOptions?: RequestInit;
|
|
8
6
|
};
|
|
9
|
-
declare const createClient: <TRouter extends
|
|
7
|
+
declare const createClient: <TRouter extends ClientRouterConstraint>(opts: FetchClientOptions) => Client<TRouter, true>;
|
|
10
8
|
|
|
11
9
|
export { type FetchClientOptions, createClient };
|
package/dist/fetch-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {d,b,c,f as f$1}from'./chunk-AHF6GNMI.js';import {stringify}from'qs';var f=async(e,c,r)=>{let n=o=>{if(!o)return {};if(o instanceof Headers){let
|
|
1
|
+
import {d,b,c,f as f$1}from'./chunk-AHF6GNMI.js';import {stringify}from'qs';var f=async(e,c,r)=>{let n=o=>{if(!o)return {};if(o instanceof Headers){let d={};return o.forEach((y,b)=>{d[b]=y;}),d}return Array.isArray(o)?Object.fromEntries(o):o},s=n(r==null?void 0:r.headers),u=n(c==null?void 0:c.headers),a={...r,...c,headers:{...s,...u}},t=await fetch(e,a),i;try{i=await t.json();}catch{i=await t.text().catch(()=>{});}if(!t.ok)throw new Error(`Failed to fetch: ${t.status} ${t.statusText}`,{cause:i});return i},h=e=>{if(e===null)return "null";if(Array.isArray(e))return e.map(h);if(typeof e=="object"&&e!==null&&e.constructor===Object){let c={};for(let[r,n]of Object.entries(e))c[r]=h(n);return c}return e},$=e=>{let c$1={get:async r=>{let n=h(r),s=stringify(n),u=await b(e.credentials)??{},a=await f(`${e.url}/${r.resource}${s?`?${s}`:""}`,{headers:{...u,"Content-Type":"application/json"}},e.fetchOptions);return !a||typeof a!="object"?[]:Array.isArray(a)?a.map(t=>{var d,y;let i=f$1(t),o=((y=(d=t==null?void 0:t.value)==null?void 0:d.id)==null?void 0:y.value)??(t==null?void 0:t.id);return {...i,id:o}}):Object.entries(a).map(([t,i])=>({...f$1(i),id:t}))},subscribe:()=>{throw new Error("Fetch client does not support subscriptions")}};return {query:Object.entries(e.schema).reduce((r,[n,s])=>(r[n]=c._init(s,c$1,true),r),{}),mutate:d(()=>{},{apply:async(r,n,s)=>{if(n.length<2)return;if(n.length>2)throw new Error("Trying to access an invalid path");let[u,a]=n,t=await b(e.credentials)??{};if(a==="insert"){let{id:i,...o}=s[0];await f(`${e.url}/${u}/insert`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:i,payload:e.schema[u].encodeMutation("set",o,new Date().toISOString())})},e.fetchOptions);return}if(a==="update"){let[i,o]=s,{id:d,...y}=o;await f(`${e.url}/${u}/update`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:i,payload:e.schema[u].encodeMutation("set",y,new Date().toISOString())})},e.fetchOptions);return}return await f(`${e.url}/${u}/${a}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({payload:s[0]})},e.fetchOptions)}})}};export{$ as createClient};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import * as z3 from 'zod/v3';
|
|
3
|
-
import * as z4 from 'zod/v4/core';
|
|
4
2
|
|
|
5
3
|
type LiveTypeMeta = {};
|
|
6
4
|
type MutationType = "set";
|
|
@@ -253,169 +251,6 @@ declare const querySchema: z.ZodObject<{
|
|
|
253
251
|
}, z.core.$strip>;
|
|
254
252
|
type RawQueryRequest = z.infer<typeof querySchema>;
|
|
255
253
|
|
|
256
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
257
|
-
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
|
258
|
-
|
|
259
|
-
type RouteRecord = Record<string, AnyRoute>;
|
|
260
|
-
declare class Router<TRoutes extends RouteRecord> {
|
|
261
|
-
readonly routes: TRoutes;
|
|
262
|
-
readonly hooksRegistry: Map<string, Hooks<any>>;
|
|
263
|
-
private constructor();
|
|
264
|
-
static create<TRoutes extends RouteRecord>(opts: {
|
|
265
|
-
routes: TRoutes;
|
|
266
|
-
}): Router<TRoutes>;
|
|
267
|
-
getHooks(resourceName: string): Hooks<any> | undefined;
|
|
268
|
-
}
|
|
269
|
-
type AnyRouter = Router<any>;
|
|
270
|
-
type Mutation<TInputValidator extends z3.ZodTypeAny | z4.$ZodType, // TODO use StandardSchema instead
|
|
271
|
-
TOutput> = {
|
|
272
|
-
inputValidator: TInputValidator;
|
|
273
|
-
handler: (opts: {
|
|
274
|
-
req: MutationRequest<z.infer<TInputValidator>>;
|
|
275
|
-
db: Storage;
|
|
276
|
-
}) => TOutput;
|
|
277
|
-
};
|
|
278
|
-
declare const mutationCreator: <TInputValidator extends z3.ZodTypeAny | z4.$ZodType>(validator?: TInputValidator) => {
|
|
279
|
-
handler: <THandler extends Mutation<TInputValidator, any>["handler"]>(handler: THandler) => Mutation<TInputValidator, ReturnType<THandler>>;
|
|
280
|
-
};
|
|
281
|
-
type ReadAuthorizationHandler<TShape extends LiveObjectAny> = (opts: {
|
|
282
|
-
ctx: BaseRequest["context"];
|
|
283
|
-
}) => WhereClause<TShape> | boolean;
|
|
284
|
-
type MutationAuthorizationHandler<TShape extends LiveObjectAny> = (opts: {
|
|
285
|
-
ctx: BaseRequest["context"];
|
|
286
|
-
value: Simplify<InferLiveObjectWithRelationalIds<TShape>>;
|
|
287
|
-
}) => WhereClause<TShape> | boolean;
|
|
288
|
-
type Authorization<TShape extends LiveObjectAny> = {
|
|
289
|
-
read?: ReadAuthorizationHandler<TShape>;
|
|
290
|
-
insert?: MutationAuthorizationHandler<TShape>;
|
|
291
|
-
update?: {
|
|
292
|
-
preMutation?: MutationAuthorizationHandler<TShape>;
|
|
293
|
-
postMutation?: MutationAuthorizationHandler<TShape>;
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
|
-
type BeforeInsertHook<TShape extends LiveObjectAny> = (opts: {
|
|
297
|
-
ctx?: Record<string, any>;
|
|
298
|
-
value: MaterializedLiveType<TShape>;
|
|
299
|
-
db: Storage;
|
|
300
|
-
}) => Promise<MaterializedLiveType<TShape> | void> | MaterializedLiveType<TShape> | void;
|
|
301
|
-
type AfterInsertHook<TShape extends LiveObjectAny> = (opts: {
|
|
302
|
-
ctx?: Record<string, any>;
|
|
303
|
-
value: MaterializedLiveType<TShape>;
|
|
304
|
-
db: Storage;
|
|
305
|
-
}) => Promise<void> | void;
|
|
306
|
-
type BeforeUpdateHook<TShape extends LiveObjectAny> = (opts: {
|
|
307
|
-
ctx?: Record<string, any>;
|
|
308
|
-
value: MaterializedLiveType<TShape>;
|
|
309
|
-
previousValue?: MaterializedLiveType<TShape>;
|
|
310
|
-
db: Storage;
|
|
311
|
-
}) => Promise<MaterializedLiveType<TShape> | void> | MaterializedLiveType<TShape> | void;
|
|
312
|
-
type AfterUpdateHook<TShape extends LiveObjectAny> = (opts: {
|
|
313
|
-
ctx?: Record<string, any>;
|
|
314
|
-
value: MaterializedLiveType<TShape>;
|
|
315
|
-
previousValue?: MaterializedLiveType<TShape>;
|
|
316
|
-
db: Storage;
|
|
317
|
-
}) => Promise<void> | void;
|
|
318
|
-
type Hooks<TShape extends LiveObjectAny> = {
|
|
319
|
-
beforeInsert?: BeforeInsertHook<TShape>;
|
|
320
|
-
afterInsert?: AfterInsertHook<TShape>;
|
|
321
|
-
beforeUpdate?: BeforeUpdateHook<TShape>;
|
|
322
|
-
afterUpdate?: AfterUpdateHook<TShape>;
|
|
323
|
-
};
|
|
324
|
-
declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, any>>> {
|
|
325
|
-
readonly resourceSchema: TResourceSchema;
|
|
326
|
-
readonly middlewares: Set<TMiddleware>;
|
|
327
|
-
readonly customMutations: TCustomMutations;
|
|
328
|
-
readonly authorization?: Authorization<TResourceSchema>;
|
|
329
|
-
readonly hooks?: Hooks<TResourceSchema>;
|
|
330
|
-
constructor(resourceSchema: TResourceSchema, customMutations?: TCustomMutations, authorization?: Authorization<TResourceSchema>, hooks?: Hooks<TResourceSchema>);
|
|
331
|
-
use(...middlewares: TMiddleware[]): this;
|
|
332
|
-
withMutations<T extends Record<string, Mutation<any, any>>>(mutationFactory: (opts: {
|
|
333
|
-
mutation: typeof mutationCreator;
|
|
334
|
-
}) => T): Route<TResourceSchema, TMiddleware, T>;
|
|
335
|
-
withHooks(hooks: Hooks<TResourceSchema>): Route<TResourceSchema, TMiddleware, TCustomMutations>;
|
|
336
|
-
getAuthorizationClause(req: QueryRequest): WhereClause<TResourceSchema> | undefined | boolean;
|
|
337
|
-
private handleSet;
|
|
338
|
-
private wrapInMiddlewares;
|
|
339
|
-
}
|
|
340
|
-
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
341
|
-
|
|
342
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
343
|
-
|
|
344
|
-
declare class Batcher {
|
|
345
|
-
private storage;
|
|
346
|
-
private queue;
|
|
347
|
-
private scheduled;
|
|
348
|
-
constructor(storage: Storage);
|
|
349
|
-
rawFind<T extends LiveObjectAny>({ resource, commonWhere, uniqueWhere, ...rest }: {
|
|
350
|
-
resource: string;
|
|
351
|
-
commonWhere?: Record<string, any>;
|
|
352
|
-
uniqueWhere?: Record<string, any>;
|
|
353
|
-
include?: Record<string, any>;
|
|
354
|
-
limit?: number;
|
|
355
|
-
sort?: {
|
|
356
|
-
key: string;
|
|
357
|
-
direction: "asc" | "desc";
|
|
358
|
-
}[];
|
|
359
|
-
}): Promise<MaterializedLiveType<T>[]>;
|
|
360
|
-
private getBatchKey;
|
|
361
|
-
private processBatch;
|
|
362
|
-
private executeBatchedRequests;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
interface DataSource {
|
|
366
|
-
get(query: RawQueryRequest, extra?: {
|
|
367
|
-
context?: any;
|
|
368
|
-
batcher?: Batcher;
|
|
369
|
-
}): PromiseOrSync<any[]>;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
373
|
-
|
|
374
|
-
declare abstract class Storage implements DataSource {
|
|
375
|
-
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
376
|
-
include?: IncludeClause<T>;
|
|
377
|
-
}): Promise<InferLiveObject<T> | undefined>;
|
|
378
|
-
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
379
|
-
where?: WhereClause<T>;
|
|
380
|
-
include?: IncludeClause<T>;
|
|
381
|
-
limit?: number;
|
|
382
|
-
sort?: {
|
|
383
|
-
key: string;
|
|
384
|
-
direction: "asc" | "desc";
|
|
385
|
-
}[];
|
|
386
|
-
}): Promise<InferLiveObject<T>[]>;
|
|
387
|
-
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
388
|
-
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
|
|
389
|
-
abstract transaction<T>(fn: (opts: {
|
|
390
|
-
trx: Storage;
|
|
391
|
-
commit: () => Promise<void>;
|
|
392
|
-
rollback: () => Promise<void>;
|
|
393
|
-
}) => Promise<T>): Promise<T>;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
interface BaseRequest {
|
|
397
|
-
headers: Record<string, string>;
|
|
398
|
-
cookies: Record<string, string>;
|
|
399
|
-
queryParams: Record<string, string>;
|
|
400
|
-
context: Record<string, any>;
|
|
401
|
-
}
|
|
402
|
-
interface QueryRequest extends BaseRequest, RawQueryRequest {
|
|
403
|
-
type: "QUERY";
|
|
404
|
-
}
|
|
405
|
-
interface MutationRequest<TInput = any> extends BaseRequest {
|
|
406
|
-
type: "MUTATE";
|
|
407
|
-
input: TInput;
|
|
408
|
-
resource: string;
|
|
409
|
-
resourceId?: string;
|
|
410
|
-
procedure: string;
|
|
411
|
-
}
|
|
412
|
-
type Request = QueryRequest | MutationRequest;
|
|
413
|
-
type NextFunction<O, R = Request> = (req: R) => PromiseOrSync<O>;
|
|
414
|
-
type Middleware<T = any> = (opts: {
|
|
415
|
-
req: Request;
|
|
416
|
-
next: NextFunction<T>;
|
|
417
|
-
}) => ReturnType<NextFunction<T>>;
|
|
418
|
-
|
|
419
254
|
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
420
255
|
|
|
421
256
|
type InferQueryResult<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection>, TSingle extends boolean = false> = TSingle extends true ? Simplify<InferLiveObject<TCollection, TInclude>> | undefined : Simplify<InferLiveObject<TCollection, TInclude>>[];
|
|
@@ -450,11 +285,47 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
|
|
|
450
285
|
subscribe(callback: (value: InferQueryResult<TCollection, TInclude, TSingle>) => void): () => void;
|
|
451
286
|
}
|
|
452
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Extracts the output type from a zod-like schema (mirrors z.infer behavior).
|
|
290
|
+
* TODO: Use StandardSchema instead
|
|
291
|
+
*/
|
|
292
|
+
type InferableSchema = {
|
|
293
|
+
_output: unknown;
|
|
294
|
+
};
|
|
295
|
+
type InferSchema<T extends InferableSchema> = T["_output"];
|
|
296
|
+
/**
|
|
297
|
+
* Simplified router constraint for client-side usage.
|
|
298
|
+
* This avoids importing server-internal types like Storage and Hooks,
|
|
299
|
+
* which can cause type incompatibilities when the package is bundled.
|
|
300
|
+
*/
|
|
301
|
+
type ClientRouterConstraint = {
|
|
302
|
+
routes: Record<string, {
|
|
303
|
+
resourceSchema: LiveObjectAny;
|
|
304
|
+
customMutations: Record<string, {
|
|
305
|
+
inputValidator: InferableSchema;
|
|
306
|
+
handler: (...args: any[]) => any;
|
|
307
|
+
}>;
|
|
308
|
+
}>;
|
|
309
|
+
};
|
|
310
|
+
type Client$1<TRouter extends ClientRouterConstraint, TShouldAwait extends boolean = false> = {
|
|
311
|
+
query: {
|
|
312
|
+
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["resourceSchema"], {}, false, TShouldAwait>;
|
|
313
|
+
};
|
|
314
|
+
mutate: {
|
|
315
|
+
[K in keyof TRouter["routes"]]: {
|
|
316
|
+
insert: (input: Simplify<InferInsert<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
317
|
+
update: (id: string, value: Simplify<InferUpdate<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
318
|
+
} & {
|
|
319
|
+
[K2 in keyof TRouter["routes"][K]["customMutations"]]: (input: InferSchema<TRouter["routes"][K]["customMutations"][K2]["inputValidator"]>) => Promisify<ReturnType<TRouter["routes"][K]["customMutations"][K2]["handler"]>>;
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
|
|
453
324
|
declare const useLiveQuery: <T extends {
|
|
454
325
|
get: () => U;
|
|
455
326
|
subscribe: (cb: (v: U) => void) => () => void;
|
|
456
327
|
}, U>(observable: T) => ReturnType<T["get"]>;
|
|
457
|
-
declare const useLoadData: (client: Client<
|
|
328
|
+
declare const useLoadData: (client: Client<ClientRouterConstraint>["client"], query: QueryBuilder<any, any>) => void;
|
|
458
329
|
|
|
459
330
|
declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
460
331
|
id: z.ZodString;
|
|
@@ -483,20 +354,6 @@ declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
483
354
|
}, z.core.$strip>]>;
|
|
484
355
|
type ServerMessage = z.infer<typeof serverMessageSchema>;
|
|
485
356
|
|
|
486
|
-
type Client$1<TRouter extends AnyRouter, TShouldAwait extends boolean = false> = {
|
|
487
|
-
query: {
|
|
488
|
-
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["resourceSchema"], {}, false, TShouldAwait>;
|
|
489
|
-
};
|
|
490
|
-
mutate: {
|
|
491
|
-
[K in keyof TRouter["routes"]]: {
|
|
492
|
-
insert: (input: Simplify<InferInsert<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
493
|
-
update: (id: string, value: Simplify<InferUpdate<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
494
|
-
} & {
|
|
495
|
-
[K2 in keyof TRouter["routes"][K]["customMutations"]]: (input: z.infer<TRouter["routes"][K]["customMutations"][K2]["inputValidator"]>) => Promisify<ReturnType<TRouter["routes"][K]["customMutations"][K2]["handler"]>>;
|
|
496
|
-
};
|
|
497
|
-
};
|
|
498
|
-
};
|
|
499
|
-
|
|
500
357
|
type WebSocketClientEventMap = WebSocketEventMap & {
|
|
501
358
|
connectionChange: {
|
|
502
359
|
open: boolean;
|
|
@@ -553,7 +410,7 @@ type MessageReceivedEvent = {
|
|
|
553
410
|
message: ServerMessage;
|
|
554
411
|
};
|
|
555
412
|
type ClientEvents = ConnectionStateChangeEvent | MessageReceivedEvent;
|
|
556
|
-
type Client<TRouter extends
|
|
413
|
+
type Client<TRouter extends ClientRouterConstraint> = {
|
|
557
414
|
client: {
|
|
558
415
|
ws: WebSocketClient;
|
|
559
416
|
addEventListener: (listener: (event: ClientEvents) => void) => () => void;
|
|
@@ -561,7 +418,7 @@ type Client<TRouter extends AnyRouter> = {
|
|
|
561
418
|
};
|
|
562
419
|
store: Client$1<TRouter>;
|
|
563
420
|
};
|
|
564
|
-
declare const createClient: <TRouter extends
|
|
421
|
+
declare const createClient: <TRouter extends ClientRouterConstraint>(opts: WebSocketClientOptions) => Client<TRouter>;
|
|
565
422
|
|
|
566
423
|
type ClientOptions = {
|
|
567
424
|
url: string;
|
|
@@ -573,4 +430,4 @@ type ClientOptions = {
|
|
|
573
430
|
logLevel?: LogLevel;
|
|
574
431
|
};
|
|
575
432
|
|
|
576
|
-
export { type
|
|
433
|
+
export { type ClientOptions as C, type MessageReceivedEvent as M, type ClientRouterConstraint as a, type Client$1 as b, useLoadData as c, type ConnectionStateChangeEvent as d, type ClientEvents as e, type Client as f, createClient as g, useLiveQuery as u };
|
package/dist/server.d.cts
CHANGED
|
@@ -181,18 +181,18 @@ interface DataSource {
|
|
|
181
181
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
182
182
|
|
|
183
183
|
declare abstract class Storage implements DataSource {
|
|
184
|
-
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
185
|
-
include?:
|
|
186
|
-
}): Promise<InferLiveObject<T> | undefined>;
|
|
187
|
-
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
184
|
+
abstract findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
|
|
185
|
+
include?: TInclude;
|
|
186
|
+
}): Promise<InferLiveObject<T, TInclude> | undefined>;
|
|
187
|
+
abstract find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
|
|
188
188
|
where?: WhereClause<T>;
|
|
189
|
-
include?:
|
|
189
|
+
include?: TInclude;
|
|
190
190
|
limit?: number;
|
|
191
191
|
sort?: {
|
|
192
192
|
key: string;
|
|
193
193
|
direction: "asc" | "desc";
|
|
194
194
|
}[];
|
|
195
|
-
}): Promise<InferLiveObject<T>[]>;
|
|
195
|
+
}): Promise<InferLiveObject<T, TInclude>[]>;
|
|
196
196
|
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
197
197
|
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
|
|
198
198
|
abstract transaction<T>(fn: (opts: {
|
|
@@ -213,18 +213,18 @@ declare class SQLStorage extends Storage {
|
|
|
213
213
|
private mutationStack;
|
|
214
214
|
constructor(pool: PostgresPool);
|
|
215
215
|
private selectMetaColumns;
|
|
216
|
-
findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
217
|
-
include?:
|
|
218
|
-
}): Promise<InferLiveObject<T> | undefined>;
|
|
219
|
-
find<T extends LiveObjectAny>(resource: T, options?: {
|
|
216
|
+
findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
|
|
217
|
+
include?: TInclude;
|
|
218
|
+
}): Promise<InferLiveObject<T, TInclude> | undefined>;
|
|
219
|
+
find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
|
|
220
220
|
where?: WhereClause<T>;
|
|
221
|
-
include?:
|
|
221
|
+
include?: TInclude;
|
|
222
222
|
limit?: number;
|
|
223
223
|
sort?: {
|
|
224
224
|
key: string;
|
|
225
225
|
direction: "asc" | "desc";
|
|
226
226
|
}[];
|
|
227
|
-
}): Promise<InferLiveObject<T>[]>;
|
|
227
|
+
}): Promise<InferLiveObject<T, TInclude>[]>;
|
|
228
228
|
transaction<T>(fn: (opts: {
|
|
229
229
|
trx: Storage;
|
|
230
230
|
commit: () => Promise<void>;
|
package/dist/server.d.ts
CHANGED
|
@@ -181,18 +181,18 @@ interface DataSource {
|
|
|
181
181
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
182
182
|
|
|
183
183
|
declare abstract class Storage implements DataSource {
|
|
184
|
-
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
185
|
-
include?:
|
|
186
|
-
}): Promise<InferLiveObject<T> | undefined>;
|
|
187
|
-
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
184
|
+
abstract findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
|
|
185
|
+
include?: TInclude;
|
|
186
|
+
}): Promise<InferLiveObject<T, TInclude> | undefined>;
|
|
187
|
+
abstract find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
|
|
188
188
|
where?: WhereClause<T>;
|
|
189
|
-
include?:
|
|
189
|
+
include?: TInclude;
|
|
190
190
|
limit?: number;
|
|
191
191
|
sort?: {
|
|
192
192
|
key: string;
|
|
193
193
|
direction: "asc" | "desc";
|
|
194
194
|
}[];
|
|
195
|
-
}): Promise<InferLiveObject<T>[]>;
|
|
195
|
+
}): Promise<InferLiveObject<T, TInclude>[]>;
|
|
196
196
|
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
197
197
|
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
|
|
198
198
|
abstract transaction<T>(fn: (opts: {
|
|
@@ -213,18 +213,18 @@ declare class SQLStorage extends Storage {
|
|
|
213
213
|
private mutationStack;
|
|
214
214
|
constructor(pool: PostgresPool);
|
|
215
215
|
private selectMetaColumns;
|
|
216
|
-
findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
217
|
-
include?:
|
|
218
|
-
}): Promise<InferLiveObject<T> | undefined>;
|
|
219
|
-
find<T extends LiveObjectAny>(resource: T, options?: {
|
|
216
|
+
findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
|
|
217
|
+
include?: TInclude;
|
|
218
|
+
}): Promise<InferLiveObject<T, TInclude> | undefined>;
|
|
219
|
+
find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
|
|
220
220
|
where?: WhereClause<T>;
|
|
221
|
-
include?:
|
|
221
|
+
include?: TInclude;
|
|
222
222
|
limit?: number;
|
|
223
223
|
sort?: {
|
|
224
224
|
key: string;
|
|
225
225
|
direction: "asc" | "desc";
|
|
226
226
|
}[];
|
|
227
|
-
}): Promise<InferLiveObject<T>[]>;
|
|
227
|
+
}): Promise<InferLiveObject<T, TInclude>[]>;
|
|
228
228
|
transaction<T>(fn: (opts: {
|
|
229
229
|
trx: Storage;
|
|
230
230
|
commit: () => Promise<void>;
|