@live-state/sync 0.0.1 → 0.0.3
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-G5SVBG4B.js +1 -0
- package/dist/chunk-LLHCJUB6.js +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +2 -2
- package/dist/fetch-client.js +1 -1
- package/dist/{index-BS5EvFM-.d.ts → index-4Y_YcJTJ.d.ts} +203 -41
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +36 -12
- package/dist/index.d.ts +36 -12
- package/dist/index.js +1 -1
- package/dist/server.cjs +2 -2
- package/dist/server.d.cts +38 -33
- package/dist/server.d.ts +38 -33
- package/dist/server.js +2 -2
- package/package.json +17 -4
- package/dist/chunk-2W2QGOPU.js +0 -1
- package/dist/chunk-EK7ODJWE.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var L="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var l;(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";})(l||(l={}));var u=class extends Error{constructor(t,n){super(`${n} (${t})`),this.name="ULIDError",this.code=t;}};function I(e){let t=Math.floor(e()*32);return t===32&&(t=31),L.charAt(t)}function M(e){let t=E(),n=t&&(t.crypto||t.msCrypto)||null;if(typeof(n==null?void 0:n.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return n.getRandomValues(i),i[0]/255};if(typeof(n==null?void 0:n.randomBytes)=="function")return ()=>n.randomBytes(1).readUInt8()/255;throw new u(l.PRNGDetectFailure,"Failed to find a reliable PRNG")}function E(){return O()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function A(e,t){let n="";for(;e>0;e--)n=I(t)+n;return n}function _(e,t=10){if(isNaN(e))throw new u(l.EncodeTimeValueMalformed,`Time must be a number: ${e}`);if(e>0xffffffffffff)throw new u(l.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${0xffffffffffff}: ${e}`);if(e<0)throw new u(l.EncodeTimeNegative,`Time must be positive: ${e}`);if(Number.isInteger(e)===false)throw new u(l.EncodeTimeValueMalformed,`Time must be an integer: ${e}`);let n,i="";for(let r=t;r>0;r--)n=e%32,i=L.charAt(n)+i,e=(e-n)/32;return i}function O(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function b(e,t){let n=M(),i=Date.now();return _(i,10)+A(16,n)}var j=()=>b().toLowerCase(),V=(e,t)=>typeof e=="function"?e(t):e;var w=(e,t,n=[])=>new Proxy(e,{get:(i,r)=>{var p,T;if(r==="__isProxy__")return true;let o=(p=t.get)==null?void 0:p.call(t,i,[...n,r]);if(o!==void 0)return o;let a=i,s=r;return (T=a[s])!=null&&T.__isProxy__||(a[s]=w(typeof a[s]=="object"?a[s]:()=>{},t,[...n,r])),a[s]},apply:(i,r,o)=>{var a;return (a=t.apply)==null?void 0:a.call(t,i,n,o)}}),f=(e,t,n=false)=>Object.entries(t).every(([i,r])=>{if(i==="$and")return r.every(a=>f(e,a,n));if(i==="$or")return r.some(a=>f(e,a,n));let o=(r==null?void 0:r.$eq)!==void 0?r==null?void 0:r.$eq:r;if(typeof r=="object"&&r!==null&&(r==null?void 0:r.$eq)===void 0){if(r.$in!==void 0){let a=e[i];return a===void 0?false:n?!r.$in.includes(a):r.$in.includes(a)}if(r.$not!==void 0&&!n)return f(e,{[i]:r.$not},true);if(r.$gt!==void 0){let a=e[i];return typeof a!="number"?false:n?a<=r.$gt:a>r.$gt}if(r.$gte!==void 0){let a=e[i];return typeof a!="number"?false:n?a<r.$gte:a>=r.$gte}if(r.$lt!==void 0){let a=e[i];return typeof a!="number"?false:n?a>=r.$lt:a<r.$lt}if(r.$lte!==void 0){let a=e[i];return typeof a!="number"?false:n?a>r.$lte:a<=r.$lte}return !e[i]||typeof e[i]!="object"?false:f(e[i],r)}return n?e[i]!==o:e[i]===o}),D=(e,t,n)=>{let i=[],r=0;for(let o=0;o<e.length&&(n===void 0||r<n);o++)t(e[o],o)&&(i.push(e[o]),r++);return i};var R=e=>{if(e)return Array.isArray(e.value)?e.value.map(t=>R(t)):typeof e.value!="object"||e.value===null||e.value instanceof Date?e.value:Object.fromEntries(Object.entries(e.value).map(([t,n])=>[t,R(n)]))};export{j as a,V as b,w as c,f as d,D as e,R as f};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var L=Object.create;var h=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var j=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var O=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of b(e))!I.call(t,i)&&i!==n&&h(t,i,{get:()=>e[i],enumerable:!(a=g(e,i))||a.enumerable});return t};var S=(t,e,n)=>(n=t!=null?L(M(t)):{},O(e||!t||!t.__esModule?h(n,"default",{value:t,enumerable:true}):n,t));var s=class{_value;_meta;_encodeInput;_decodeInput};var c=class extends s{inner;constructor(e){super(),this.inner=e;}encodeMutation(e,n,a){return this.inner.encodeMutation(e,n,a)}mergeMutation(e,n,a){return this.inner.mergeMutation(e,n,a)}getStorageFieldType(){return {...this.inner.getStorageFieldType(),nullable:true}}},o=class t extends s{storageType;convertFunc;isIndex;isUnique;defaultValue;foreignReference;isPrimary;constructor(e,n,a,i,r,u,y){super(),this.storageType=e,this.convertFunc=n,this.isIndex=a??false,this.isUnique=i??false,this.defaultValue=r,this.foreignReference=u,this.isPrimary=y??false;}encodeMutation(e,n,a){return {value:n,_meta:{timestamp:a}}}mergeMutation(e,n,a){return a&&a._meta.timestamp&&n._meta.timestamp&&a._meta.timestamp.localeCompare(n._meta.timestamp)>=0?[a,null]:[{value:this.convertFunc?this.convertFunc(n.value):n.value,_meta:n._meta},n]}getStorageFieldType(){return {type:this.storageType,nullable:false,index:this.isIndex,unique:this.isUnique,default:this.defaultValue,references:this.foreignReference,primary:this.isPrimary}}unique(){return new t(this.storageType,this.convertFunc,this.isIndex,true,this.defaultValue,this.foreignReference,this.isPrimary)}index(){return new t(this.storageType,this.convertFunc,true,this.isUnique,this.defaultValue,this.foreignReference,this.isPrimary)}default(e){return new t(this.storageType,this.convertFunc,this.isIndex,this.isUnique,e,this.foreignReference,this.isPrimary)}primary(){return new t(this.storageType,this.convertFunc,this.isIndex,this.isUnique,this.defaultValue,this.foreignReference,true)}nullable(){return new c(this)}},p=class t extends o{constructor(){super("integer",e=>Number(e));}static create(){return new t}},_=p.create,l=class t extends o{constructor(e){super("varchar",void 0,void 0,void 0,void 0,e);}static create(){return new t}static createId(){return new t().index().unique().primary()}static createReference(e){return new t(e)}},V=l.create,E=l.createId,C=l.createReference,d=class t extends o{constructor(){super("boolean",e=>typeof e=="string"?e.toLowerCase()==="true":!!e);}static create(){return new t}},F=d.create,m=class t extends o{constructor(){super("timestamp",e=>typeof e=="string"?new Date(e):e);}static create(){return new t}},q=m.create;var v=class t extends s{name;fields;relations;constructor(e,n,a){super(),this.name=e,this.fields=n,this.relations=a??{};}encodeMutation(e,n,a){return Object.fromEntries(Object.entries(n).map(([i,r])=>[i,(this.fields[i]??this.relations[i]).encodeMutation("set",r,a)]))}mergeMutation(e,n,a){let i={};return [{value:{...(a==null?void 0:a.value)??{},...Object.fromEntries(Object.entries(n).map(([r,u])=>{let y=this.fields[r]??this.relations[r];if(!y)return [r,u];let[R,f]=y.mergeMutation(e,u,a==null?void 0:a.value[r]);return f&&(i[r]=f),[r,R]}))}},i]}setRelations(e){return new t(this.name,this.fields,e)}getStorageFieldType(){throw new Error("Method not implemented.")}static create(e,n){return new t(e,n)}},$=v.create,T=class t extends s{entity;type;required;relationalColumn;foreignColumn;sourceEntity;constructor(e,n,a,i,r){super(),this.entity=e,this.type=n,this.required=r??false,this.relationalColumn=a,this.foreignColumn=i;}encodeMutation(e,n,a){if(e!=="set")throw new Error("Mutation type not implemented.");if(this.type==="many")throw new Error("Many not implemented.");return {value:n,_meta:{timestamp:a}}}mergeMutation(e,n,a){if(this.type==="many")throw new Error("Many not implemented.");return a&&a._meta.timestamp&&n._meta.timestamp&&a._meta.timestamp.localeCompare(n._meta.timestamp)>=0?[a,null]:[n,n]}getStorageFieldType(){return {type:"varchar",nullable:!this.required,references:`${this.entity.name}.${String(this.foreignColumn??this.relationalColumn??"id")}`}}toJSON(){return {entityName:this.entity.name,type:this.type,required:this.required,relationalColumn:this.relationalColumn,foreignColumn:this.foreignColumn}}static createOneFactory(){return (e,n,a)=>new t(e,"one",n,void 0,a??false)}static createManyFactory(){return (e,n,a)=>new t(e,"many",void 0,n,a??false)}},D=(t,e)=>({$type:"relations",objectName:t.name,relations:e({one:T.createOneFactory(),many:T.createManyFactory()})}),x=t=>{if(t)return Array.isArray(t.value)?t.value.map(e=>x(e)):typeof t.value!="object"||t.value===null||t.value instanceof Date?t.value:Object.fromEntries(Object.entries(t.value).map(([e,n])=>[e,x(n)]))},k=t=>Object.fromEntries(Object.entries(t).flatMap(([e,n])=>{if(n.$type==="relations")return [];let a=n,i=Object.values(t).find(r=>r.$type==="relations"&&r.objectName===n.name);return i&&(a=a.setRelations(i.relations)),[[a.name,a]]}));export{j as a,S as b,s as c,p as d,_ as e,l as f,V as g,E as h,C as i,d as j,F as k,m as l,q as m,v as n,$ as o,T as p,D as q,x as r,k as s};
|
package/dist/client.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { f as Client, e as ClientEvents, C as ClientOptions, d as ConnectionStateChangeEvent, M as MessageReceivedEvent, c as SubscriptionProvider, g as createClient, u as useLiveQuery } from './index-4Y_YcJTJ.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {c,a,d,b}from'./chunk-2W2QGOPU.js';import {useState,useEffect}from'react';import {jsx,Fragment}from'react/jsx-runtime';import {z}from'zod';import {stringify}from'qs';import {openDB}from'idb';var X=d=>{let[e,t]=useState(()=>d.get());return useEffect(()=>d.subscribe(()=>{let i=d.get();t(i);}),[]),e},ee=({children:d,client:e})=>(useEffect(()=>{e.subscribe();},[]),jsx(Fragment,{children:d}));z.object({type:z.literal("QUERY"),resource:z.string(),where:z.record(z.any()).optional(),include:z.record(z.any()).optional()});var j=z.record(z.object({value:z.string().or(z.number()).or(z.boolean()).or(z.date()),_meta:z.object({timestamp:z.string().optional()}).optional()})).superRefine((d,e)=>{d.id&&e.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),K=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string()}),C=K.extend({procedure:z.string(),payload:z.any().optional()}),L=K.extend({resourceId:z.string(),payload:j});z.union([C,L]);var v=z.string(),H=z.object({id:v,type:z.literal("SUBSCRIBE"),resource:z.string()}),_=z.object({id:v,type:z.literal("SYNC"),lastSyncedAt:z.string().optional(),resources:z.string().array().optional(),where:z.record(z.any()).optional()}),N=L.extend({id:v}),V=C.extend({id:v}),Y=z.union([V,N]);z.union([H,_,Y]);var $=z.object({id:v,type:z.literal("SYNC"),resource:z.string(),data:z.record(j)}),J=z.object({id:v,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),q=z.object({id:v,type:z.literal("REPLY"),data:z.any()}),W=z.union([$,J,q,N]);var w=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){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t);}removeEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.get(e).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){this.dispatchEvent("error",e);}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){this.eventListeners.has(e)&&this.eventListeners.get(e).forEach(i=>{i(t);});}};var O=class{nodes;constructor(){this.nodes=new Map;}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,i){let s=this.nodes.get(e),r=this.nodes.get(t);if(!s)throw new Error(`Source node with id ${e} does not exist`);if(!r)throw new Error(`Target node with id ${t} does not exist`);s.references.set(i,t);let n=r.referencedBy.get(i);n&&n instanceof Set?n.add(e):r.referencedBy.set(i,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 n=r.referencedBy.get(t);n&&(n instanceof Set?n.delete(e):r.referencedBy.delete(t),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 c=this.nodes.get(n);!c||!c.references.get(i)||(c.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=>{try{i(e);}catch(s){console.error(`Error in node subscription for node ${e}:`,s);}});}getAllNodes(){return Array.from(this.nodes.values())}};var x="__meta",T=class{db;async init(e){this.db=await openDB("live-state",1,{upgrade(t){Object.keys(e).forEach(i=>t.createObjectStore(i)),t.createObjectStore(x);}});}async get(e){if(this.db.getAllRecords)return this.db.getAllRecords(e);let[t,i]=await Promise.all([this.db.getAll(e),this.db.getAllKeys(e)]);return Object.fromEntries(t.map((s,r)=>[i[r],s]))}getOne(e,t){return this.db.get(e,t)}set(e,t,i){return this.db.put(e,i,t)}delete(e,t){return this.db.delete(e,t)}getMeta(e){return this.db.get(x,e)}setMeta(e,t){return this.db.put(x,t,e)}};var R=class{constructor(e,t){this.schema=e;this.kvStorage=new T,this.kvStorage.init(this.schema).then(()=>{this.kvStorage.getMeta("mutationStack").then(i=>{!i||Object.keys(i).length===0||(this.optimisticMutationStack=i,t==null||t(this.optimisticMutationStack));}).then(()=>{Object.entries(this.schema).forEach(([i,s])=>{this.kvStorage.get(i).then(r=>{!r||Object.keys(r).length===0||this.loadConsolidatedState(i,r);});});}).catch(i=>{console.error("Failed to load state from storage",i);});});}rawObjPool={};optimisticMutationStack={};optimisticObjGraph=new O;optimisticRawObjPool={};resourceTypeSubscriptions={};kvStorage;get(e){return Object.fromEntries(Object.entries(this.optimisticRawObjPool[e]??{}).map(([t,i])=>[t,d(i)]))}getOne(e,t){var n;let i=this.optimisticObjGraph.getNode(t);if(!i)return;let s=(n=this.optimisticRawObjPool[e])==null?void 0:n[t];if(!s)return;let r={value:{...s.value,...Object.fromEntries(Array.from(i.references.entries()).map(([c,h])=>{var l;let g=this.optimisticObjGraph.getNode(h);if(!g)return [c,void 0];let[y,m]=Object.entries(this.schema[e].relations).find(u=>u[1].relationalColumn===c||u[1].foreignColumn===c)??[],f=m==null?void 0:m.entity.name;return !f||!m?[c,void 0]:[y,(l=this.optimisticRawObjPool[f])==null?void 0:l[g.id]]})),...Object.fromEntries(Array.from(i.referencedBy.entries()).map(([c,h])=>{var u;let g=h instanceof Set,y=g?Array.from(h.values()).flatMap(p=>{let b=this.optimisticObjGraph.getNode(p);return b?[b]:[]}):this.optimisticObjGraph.getNode(h);if(!y)return [c,void 0];let[m,f]=Object.entries(this.schema[e].relations).find(p=>p[1].relationalColumn===c||p[1].foreignColumn===c)??[],l=f==null?void 0:f.entity.name;return !l||!f?[c,g?[]:void 0]:[m,g?{value:y.map(p=>{var b;return (b=this.optimisticRawObjPool[l])==null?void 0:b[p.id]})}:(u=this.optimisticRawObjPool[l])==null?void 0:u[y.id]]}))}};return d(r)}subscribe(e,t){if(e.length===1)return this.resourceTypeSubscriptions[e[0]]||(this.resourceTypeSubscriptions[e[0]]=new Set),this.resourceTypeSubscriptions[e[0]].add(t),()=>{this.resourceTypeSubscriptions[e[0]].delete(t);};if(e.length===2){if(!this.optimisticObjGraph.getNode(e[1]))throw new Error("Node not found");return this.optimisticObjGraph.subscribe(e[1],t)}throw new Error("Not implemented")}addMutation(e,t,i=false){var h,g,y,m,f;let s=this.schema[e];if(console.log("Adding mutation",t),!s)throw new Error("Schema not found");let r=(h=this.optimisticRawObjPool[e])==null?void 0:h[t.resourceId];if(i)(this.optimisticMutationStack[e]??=[]).push(t);else {this.optimisticMutationStack[e]=(y=(g=this.optimisticMutationStack)==null?void 0:g[e])==null?void 0:y.filter(p=>p.id!==t.id),this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.rawObjPool[e]??={};let l={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=l;let u=l.value;delete u.id,this.kvStorage.set(e,t.resourceId,u);}let n=(m=this.rawObjPool[e])==null?void 0:m[t.resourceId],c=(this.optimisticMutationStack[e]??[]).reduce((l,u)=>u.resourceId!==t.resourceId?l:this.schema[e].mergeMutation("set",u.payload,l)[0],n);if(c&&((this.optimisticRawObjPool[e]??={})[t.resourceId]={value:{...c.value,id:{value:t.resourceId}}}),this.optimisticObjGraph.hasNode(t.resourceId)||this.optimisticObjGraph.createNode(t.resourceId,e,Object.values(s.relations).flatMap(l=>l.type==="many"?[l.foreignColumn]:[])),Object.keys(s.relations).length>0){let l=Object.fromEntries(Object.entries(s.relations).flatMap(([u,p])=>p.type==="one"?[[p.relationalColumn,u]]:[]));Object.entries(t.payload).forEach(([u,p])=>{if(!p||!l[u])return;let b=r==null?void 0:r.value[u],[,M]=s.relations[l[u]].mergeMutation("set",p,b);if(M){if(!this.optimisticObjGraph.hasNode(M.value)){let P=s.relations[l[u]].entity.name;this.optimisticObjGraph.createNode(M.value,P,Object.values(this.schema[P].relations).flatMap(k=>k.type==="many"?[k.foreignColumn]:[]));}b!=null&&b.value&&this.optimisticObjGraph.removeLink(t.resourceId,u),this.optimisticObjGraph.createLink(t.resourceId,M.value,u);}});}(f=this.resourceTypeSubscriptions[e])==null||f.forEach(l=>l()),this.optimisticObjGraph.notifySubscribers(t.resourceId);}loadConsolidatedState(e,t){Object.entries(t).forEach(([i,s])=>{this.addMutation(e,{id:i,type:"MUTATE",resource:e,resourceId:i,payload:s});});}};var A=class{url;ws;store;routeSubscriptions={};replyHandlers={};constructor(e){this.url=e.url,this.store=new R(e.schema,t=>{var i,s;(s=(i=Object.values(t))==null?void 0:i.flat())==null||s.forEach(r=>this.sendWsMessage(r));}),this.ws=new w({url:e.url,autoConnect:true,autoReconnect:true,reconnectTimeout:5e3,credentials:e.credentials}),this.ws.addEventListener("message",t=>{this.handleServerMessage(t.data);}),this.ws.addEventListener("connectionChange",t=>{t.open&&(this.sendWsMessage({id:a(),type:"SYNC"}),Object.entries(this.routeSubscriptions).forEach(([i,s])=>{s>0&&this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:i});}),Object.values(this.store.optimisticMutationStack).forEach(i=>{i&&i.forEach(s=>this.sendWsMessage(s));}));});}get(e){if(e.length===0)throw new Error("Path must not be empty");return e.length===1?this.store.get(e[0]):this.store.getOne(e[0],e[1])}handleServerMessage(e){try{console.log("Message received from the server:",e);let t=W.parse(JSON.parse(e));if(console.log("Parsed message:",t),t.type==="MUTATE"){let{resource:i}=t;try{this.store.addMutation(i,t);}catch(s){console.error("Error parsing mutation from the server:",s);}}else if(t.type==="SYNC"){let{resource:i,data:s}=t;console.log("Syncing resource:",s,t),this.store.loadConsolidatedState(i,s);}else if(t.type!=="REJECT"){if(t.type==="REPLY"){let{id:i,data:s}=t;if(!this.replyHandlers[i])return;clearTimeout(this.replyHandlers[i].timeoutHandle),this.replyHandlers[i].handler(s);}}}catch(t){console.error("Error parsing message from the server:",t);}}subscribeToRemote(e){return this.routeSubscriptions[e]=(this.routeSubscriptions[e]??0)+1,this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:e}),()=>{this.routeSubscriptions[e]-=1,this.routeSubscriptions[e];}}subscribeToStore(e,t){this.store.subscribe(e,t);}mutate(e,t,i){let s={id:a(),type:"MUTATE",resource:e,payload:this.store.schema[e].encodeMutation("set",i,new Date().toISOString()),resourceId:t};this.store.addMutation(e,s,true),this.sendWsMessage(s);}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,n)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],n(new Error("Reply timeout"));},5e3),handler:c=>{delete this.replyHandlers[s.id],r(c);}};})}sendWsMessage(e){this.ws&&this.ws.connected()&&this.ws.send(JSON.stringify(e));}},Ne=d=>{let e=new A(d);return {client:{ws:e.ws,subscribe:t=>{let i=[];for(let s of t??Object.keys(e.store.schema))i.push(e.subscribeToRemote(s));return ()=>{console.log("Removing listeners",i),i.forEach(s=>s());}}},store:c(()=>{},{apply:(t,i,s)=>{let r=i.slice(0,-1),n=i[i.length-1];if(n==="get")return e.get(r);if(n==="subscribe")return e.subscribeToStore(r,s[0]);if(n==="subscribeToRemote")return e.subscribeToRemote(r[0]);if(n==="insert"){let{id:c,...h}=s[0];return e.mutate(r[0],c,h)}if(n==="update"){let[c,h]=s;return e.mutate(r[0],c,h)}return e.genericMutate(r[0],n,s[0])}})}};export{ee as SubscriptionProvider,Ne as createClient,X as useLiveQuery};
|
|
1
|
+
import {c,a,f,d,e,b}from'./chunk-G5SVBG4B.js';import {useSyncExternalStore,useEffect}from'react';import {xxHash32}from'js-xxhash';import {jsx,Fragment}from'react/jsx-runtime';import {z}from'zod';import {stringify}from'qs';import ae from'fast-deep-equal';import {openDB}from'idb';var m=d=>xxHash32(JSON.stringify(d)).toString(32);var k=class{subscriptions=new Map;getOrStoreSubscription(e){let t=m(e);return this.subscriptions.has(t)?this.subscriptions.get(t).subscribe:(this.subscriptions.set(t,{subscribe:i=>{var n;(n=this.subscriptions.get(t))==null||n.callbacks.add(i);let s=e.subscribe(()=>{var r;(r=this.subscriptions.get(t))==null||r.callbacks.forEach(o=>{o();});});return ()=>{var r;(r=this.subscriptions.get(t))==null||r.callbacks.delete(i),setTimeout(()=>{var o;((o=this.subscriptions.get(t))==null?void 0:o.callbacks.size)===0&&(this.subscriptions.delete(t),s());},10);}},callbacks:new Set}),this.subscriptions.get(t).subscribe)}},F=new k,he=d=>useSyncExternalStore(F.getOrStoreSubscription(d),d.get),pe=({children:d,client:e})=>(useEffect(()=>{e.subscribe();},[e.subscribe]),jsx(Fragment,{children:d}));var N=z.object({resource:z.string(),where:z.record(z.any()).optional(),include:z.record(z.any()).optional(),lastSyncedAt:z.string().optional(),limit:z.number().optional(),sort:z.array(z.object({key:z.string(),direction:z.enum(["asc","desc"])})).optional()}),x=z.record(z.object({value:z.string().or(z.number()).or(z.boolean()).or(z.date()).nullable(),_meta:z.object({timestamp:z.string().optional().nullable()}).optional()})).superRefine((d,e)=>{d.id&&e.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),H=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string()}),_=H.extend({procedure:z.string(),payload:z.any().optional()}),L=H.extend({resourceId:z.string(),payload:x});z.union([_,L]);var v=z.string(),ee=z.object({id:v,type:z.literal("SUBSCRIBE"),resource:z.string()}),te=N.extend({id:v,type:z.literal("QUERY")}),q=L.extend({id:v}),ie=_.extend({id:v}),se=z.union([ie,q]);z.union([ee,te,se]);var ne=z.object({id:v,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),re=z.object({id:v,type:z.literal("REPLY"),data:z.any()}),K=z.union([ne,re,q]),U=z.object({resource:z.string(),data:z.record(x)});var M=class d{_collection;_client;_where;_include;_limit;_single;_sort;constructor(e,t,i,s,n,r,o){this._collection=e,this._client=t,this._where=i??{},this._include=s??{},this._limit=n,this._single=r,this._sort=o,this.get=this.get.bind(this),this.subscribe=this.subscribe.bind(this);}where(e){return new d(this._collection,this._client,{...this._where,...e},this._include,this._limit,this._single,this._sort)}include(e){return new d(this._collection,this._client,this._where,{...this._include,...e},this._limit,this._single,this._sort)}get(){let e=this._client.get({resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort});return this._single?e[0]:e}subscribe(e){return this._client.subscribe({resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort},t=>{if(this._single)return e(t[0]);e(t);})}limit(e){return new d(this._collection,this._client,this._where,this._include,e,this._single,this._sort)}one(e){return this.first({id:e})}first(e){return new d(this._collection,this._client,e??this._where,this._include,1,true,this._sort)}orderBy(e,t="asc"){let i=[...this._sort??[],{key:e,direction:t}];return new d(this._collection,this._client,this._where,this._include,this._limit,this._single,i)}toJSON(){return {resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort}}static _init(e,t){return new d(e,t)}};var E=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(s=>{s(t);});}};var T=class{nodes;constructor(){this.nodes=new Map;}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(n=>[n,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 n=s.referencedBy.get(i.type);n&&n instanceof Set?n.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 n=this.nodes.get(s);if(!n)return;let r=n.referencedBy.get(i.type);r&&(r instanceof Set?r.delete(e):n.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(r=>{let o=this.nodes.get(r);!o||!o.references.get(i)||(o.references.delete(i),this.notifySubscribers(r));});}),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=>{try{i(e);}catch(s){console.error(`Error in node subscription for node ${e}:`,s);}});}getAllNodes(){return Array.from(this.nodes.values())}};var A="__meta",C="databases",R=class{db;async init(e,t){var y,h;if(typeof window>"u")return;let s=((y=(await window.indexedDB.databases()).find(l=>l.name===t))==null?void 0:y.version)??1,n=await m(e),r=Object.fromEntries(await Promise.all(Object.entries(e).map(async([l,u])=>[l,await m(u)]))),o=await openDB("live-state-databases",1,{upgrade(l){l.objectStoreNames.contains(C)||l.createObjectStore(C);}}),c=(h=await this.getAll(o,C))==null?void 0:h[t];(c==null?void 0:c.schemaHash)!==n&&s++,this.db=await openDB(t,s,{async upgrade(l){[...Object.keys(e),A].forEach(u=>{(c==null?void 0:c.objectHashes[u])!==r[u]&&l.objectStoreNames.contains(u)&&l.deleteObjectStore(u),l.objectStoreNames.contains(u)||l.createObjectStore(u);}),await o.put(C,{schemaHash:n,objectHashes:r},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(A,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(A,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((n,r)=>[s[r],n]))}};var O=class{constructor(e,t,i){this.schema=e;this.kvStorage=new R,t!==false&&this.kvStorage.init(this.schema,t.name).then(()=>{this.kvStorage.getMeta("mutationStack").then(s=>{!s||Object.keys(s).length===0||(this.optimisticMutationStack=s,i==null||i(this.optimisticMutationStack));}).then(()=>{Object.entries(this.schema).forEach(([s,n])=>{this.kvStorage.get(s).then(r=>{!r||Object.keys(r).length===0||this.loadConsolidatedState(s,r);});});}).catch(s=>{console.error("Failed to load state from storage",s);});});}rawObjPool={};optimisticMutationStack={};optimisticObjGraph=new T;optimisticRawObjPool={};collectionSubscriptions=new Map;querySnapshots={};kvStorage;get(e$1,t,i=false){var r;let s=t??m(e$1);if(this.querySnapshots[s]&&!i){let o=this.querySnapshots[s];if(o)return o}let n=((r=e$1.where)!=null&&r.id?[e$1.where.id]:Object.keys(this.optimisticRawObjPool[e$1.resource]??{})).flatMap(o=>{let c=f(this.materializeOneWithInclude(o,e$1.include));return c?[c]:[]});if(e$1.sort&&e$1.sort.length>0){let o=(c,y)=>{for(let h of e$1.sort){let l=c[h.key],u=y[h.key];if(l<u)return h.direction==="asc"?-1:1;if(l>u)return h.direction==="asc"?1:-1}return 0};n.sort(o);}if(e$1.where||e$1.limit){let o=e$1.where?c=>d(c,e$1.where):()=>true;n=e(n,o,e$1.limit);}return i||(this.querySnapshots[s]=n),n}subscribe(e,t){var r;let i=m(e),s=this.collectionSubscriptions.get(i),n=this.schema[e.resource];return s||this.collectionSubscriptions.set(i,{callbacks:new Set,query:e,flatInclude:e.include?Object.keys(e.include).map(o=>n.relations[o].entity.name):void 0}),(r=this.collectionSubscriptions.get(i))==null||r.callbacks.add(t),()=>{var o,c;(o=this.collectionSubscriptions.get(i))==null||o.callbacks.delete(t),((c=this.collectionSubscriptions.get(i))==null?void 0:c.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var c,y,h,l;let s=this.schema[e];if(console.log("Adding mutation",t),!s)throw new Error("Schema not found");let n=(c=this.optimisticRawObjPool[e])==null?void 0:c[t.resourceId];if(i)this.optimisticMutationStack[e]??=[],this.optimisticMutationStack[e].push(t);else {this.optimisticMutationStack[e]=((h=(y=this.optimisticMutationStack)==null?void 0:y[e])==null?void 0:h.filter(b=>b.id!==t.id))??[],this.rawObjPool[e]??={};let u={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}};this.rawObjPool[e][t.resourceId]=u;let f=u.value;delete f.id,this.kvStorage.set(e,t.resourceId,f);}this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack);let r=(l=this.rawObjPool[e])==null?void 0:l[t.resourceId],o=(this.optimisticMutationStack[e]??[]).reduce((u,f)=>f.resourceId!==t.resourceId?u:this.schema[e].mergeMutation("set",f.payload,u)[0],r);if(o&&(this.optimisticRawObjPool[e]??={},this.optimisticRawObjPool[e][t.resourceId]={value:{...o.value,id:{value:t.resourceId}}}),this.optimisticObjGraph.hasNode(t.resourceId)||this.optimisticObjGraph.createNode(t.resourceId,e,Object.values(s.relations).flatMap(u=>u.type==="many"?[u.entity.name]:[])),Object.keys(s.relations).length>0){let u=Object.fromEntries(Object.entries(s.relations).flatMap(([f,b])=>b.type==="one"?[[b.relationalColumn,f]]:[]));Object.entries(t.payload).forEach(([f,b])=>{let j=s.relations[u[f]];if(!b||!u[f])return;let S=n==null?void 0:n.value[f],[,w]=j.mergeMutation("set",b,S);if(w){if(!this.optimisticObjGraph.hasNode(w.value)){let W=j.entity.name;this.optimisticObjGraph.createNode(w.value,W,Object.values(this.schema[W].relations).flatMap(P=>P.type==="many"?[P.entity.name]:[]));}S!=null&&S.value&&this.optimisticObjGraph.removeLink(t.resourceId,j.entity.name),this.optimisticObjGraph.createLink(t.resourceId,w.value);}});}this.notifyCollectionSubscribers(e),this.optimisticObjGraph.notifySubscribers(t.resourceId);}loadConsolidatedState(e,t){Object.entries(t).forEach(([i,s])=>{this.addMutation(e,{id:i,type:"MUTATE",resource:e,resourceId:i,payload:s});});}materializeOneWithInclude(e,t={}){var c;if(!e)return;let i=this.optimisticObjGraph.getNode(e);if(!i)return;let s=i.type,n=(c=this.optimisticRawObjPool[s])==null?void 0:c[e];if(!n)return;let[r,o]=Object.keys(t).reduce((y,h)=>{let l=this.schema[s].relations[h];return l.type==="one"?y[0].push([h,l.entity.name]):l.type==="many"&&y[1].push([h,l.entity.name]),y},[[],[]]);return {value:{...n.value,...Object.fromEntries(r.map(([y,h])=>[y,this.materializeOneWithInclude(i.references.get(h))])),...Object.fromEntries(o.map(([y,h])=>{let l=i.referencedBy.get(h),u=l instanceof Set;return [y,u?{value:Array.from(l.values()).map(f=>this.materializeOneWithInclude(f))}:this.materializeOneWithInclude(l)]}))}}}notifyCollectionSubscribers(e){this.collectionSubscriptions.forEach(t=>{if(t.query.resource===e||t.flatInclude&&t.flatInclude.includes(e)){let i=m(t.query),s=this.querySnapshots[i],n=this.get(t.query,void 0,true);if(ae(n,s))return;this.querySnapshots[i]=n,t.callbacks.forEach(r=>{r(n);});}});}};var I=class{url;ws;store;remoteSubCounters={};eventListeners=new Set;replyHandlers={};constructor(e){this.url=e.url,this.store=new O(e.schema,e.storage,t=>{var i,s;(s=(i=Object.values(t))==null?void 0:i.flat())==null||s.forEach(n=>{this.sendWsMessage(n);});}),this.ws=new E({url:e.url,autoConnect:true,autoReconnect:true,reconnectTimeout:5e3,credentials:e.credentials}),this.ws.addEventListener("message",t=>{this.handleServerMessage(t.data);}),this.ws.addEventListener("connectionChange",t=>{this.emitEvent({type:"CONNECTION_STATE_CHANGE",open:t.open}),t.open&&(Object.keys(this.store.schema).forEach(i=>{this.sendWsMessage({id:a(),type:"QUERY",resource:i});}),Object.entries(this.remoteSubCounters).forEach(([i,s])=>{s>0&&this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:i});}),Object.values(this.store.optimisticMutationStack).forEach(i=>{i&&i.forEach(s=>{this.sendWsMessage(s);});}));});}get(e){return this.store.get(e)}handleServerMessage(e){try{console.log("Message received from the server:",e);let t=K.parse(JSON.parse(e));if(console.log("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){console.error("Error merging mutation from the server:",s);}}else if(t.type!=="REJECT"){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 n=U.parse(s);this.store.loadConsolidatedState(n.resource,n.data);}}}catch(t){console.error("Error parsing message from the server:",t);}}subscribeToRemote(e){return this.remoteSubCounters[e]=(this.remoteSubCounters[e]??0)+1,this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:e}),()=>{this.remoteSubCounters[e]-=1,this.remoteSubCounters[e];}}subscribe(e,t){return this.store.subscribe(e,t)}mutate(e,t,i){var n;let s={id:a(),type:"MUTATE",resource:e,payload:this.store.schema[e].encodeMutation("set",i,new Date().toISOString()),resourceId:t};(n=this.store)==null||n.addMutation(e,s,true),this.sendWsMessage(s);}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((n,r)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],r(new Error("Reply timeout"));},5e3),handler:o=>{delete this.replyHandlers[s.id],n(o);}};})}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=d=>{let e=new I(d);return {client:{ws:e.ws,subscribe:t=>{let i=[];for(let s of t??Object.keys(e.store.schema))i.push(e.subscribeToRemote(s));return ()=>{console.log("Removing listeners",i),i.forEach(s=>{s();});}},addEventListener:t=>e.addEventListener(t)},store:{query:Object.entries(d.schema).reduce((t,[i,s])=>(t[i]=M._init(s,e),t),{}),mutate:c(()=>{},{apply:(t,i,s)=>{if(i.length<2)return;if(i.length>2)throw new Error("Trying to access an invalid path");let[n,r]=i;if(r==="insert"){let{id:o,...c}=s[0];return e.mutate(n,o,c)}if(r==="update"){let[o,c]=s;return e.mutate(n,o,c)}return e.genericMutate(n,r,s[0])}})}}};export{pe as SubscriptionProvider,qe as createClient,he as useLiveQuery};
|
package/dist/fetch-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AnyRouter, C as ClientOptions, L as LiveObjectAny, W as WhereClause, I as IncludeClause, S as Simplify, a as InferLiveObject, b as LiveObjectMutationInput } from './index-
|
|
1
|
+
import { A as AnyRouter, C as ClientOptions, L as LiveObjectAny, W as WhereClause, I as IncludeClause, S as Simplify, a as InferLiveObject, b as LiveObjectMutationInput } from './index-4Y_YcJTJ.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
@@ -13,6 +13,6 @@ type FetchClient<TRouter extends AnyRouter> = {
|
|
|
13
13
|
upsert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => Promise<void>;
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
|
-
declare const createClient: <TRouter extends AnyRouter>(opts: ClientOptions) => FetchClient<TRouter>;
|
|
16
|
+
declare const createClient: <TRouter extends AnyRouter>(opts: Omit<ClientOptions, "storage">) => FetchClient<TRouter>;
|
|
17
17
|
|
|
18
18
|
export { createClient };
|
package/dist/fetch-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {c,b,
|
|
1
|
+
import {c,b,f}from'./chunk-G5SVBG4B.js';import {stringify}from'qs';var v=r=>c(()=>{},{apply:async(f$1,c,i)=>{if(c.length>2)throw new Error("Trying to access invalid property");let[n,o]=c,s=await b(r.credentials)??{};if(o==="get"){let e=i[0],t={};return e!=null&&e.where&&(t.where=e.where),e!=null&&e.include&&(t.include=e.include),fetch(`${r.url}/${n}${Object.keys(t).length>0?`?${stringify(t)}`:""}`,{headers:s}).then(async y=>Object.fromEntries(Object.entries(await y.json()??{}).map(([l,d])=>[l,f(d)])))}if(o==="upsert"){let{id:e,...t}=i[0];return fetch(`${r.url}/${n}/set`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({resourceId:e,payload:r.schema[n].encodeMutation("set",t,new Date().toISOString())})})}return fetch(`${r.url}/${n}/${o}`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify(i[0])})}});export{v as createClient};
|
|
@@ -41,18 +41,18 @@ type InferLiveType<T extends LiveTypeAny> = T["_value"] extends Record<string, L
|
|
|
41
41
|
} : T["_value"];
|
|
42
42
|
type InferIndex<T extends LiveTypeAny> = string;
|
|
43
43
|
|
|
44
|
-
declare class
|
|
44
|
+
declare class NullableLiveType<T extends LiveTypeAny> extends LiveType<T["_value"] | null, T["_meta"], T["_encodeInput"], T["_decodeInput"]> {
|
|
45
45
|
readonly inner: T;
|
|
46
46
|
constructor(inner: T);
|
|
47
|
-
encodeMutation(mutationType: MutationType, input: T["_value"] |
|
|
48
|
-
mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] |
|
|
49
|
-
MaterializedLiveType<LiveType<T["_value"] |
|
|
47
|
+
encodeMutation(mutationType: MutationType, input: T["_value"] | null, timestamp: string): T["_decodeInput"];
|
|
48
|
+
mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] | null, T["_meta"], T["_value"] | Partial<T["_value"] | null>, T["_decodeInput"]>> | undefined): [
|
|
49
|
+
MaterializedLiveType<LiveType<T["_value"] | null, T["_meta"], T["_value"] | Partial<T["_value"] | null>, T["_decodeInput"]>>,
|
|
50
50
|
T["_decodeInput"] | null
|
|
51
51
|
];
|
|
52
52
|
getStorageFieldType(): StorageFieldType;
|
|
53
53
|
}
|
|
54
54
|
type LiveAtomicTypeMeta = {
|
|
55
|
-
timestamp: string;
|
|
55
|
+
timestamp: string | null;
|
|
56
56
|
} & LiveTypeMeta;
|
|
57
57
|
declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta, Value, {
|
|
58
58
|
value: Value;
|
|
@@ -91,7 +91,7 @@ declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta,
|
|
|
91
91
|
index(): LiveAtomicType<Value>;
|
|
92
92
|
default(value: Value): LiveAtomicType<Value>;
|
|
93
93
|
primary(): LiveAtomicType<Value>;
|
|
94
|
-
|
|
94
|
+
nullable(): NullableLiveType<this>;
|
|
95
95
|
}
|
|
96
96
|
declare class LiveString extends LiveAtomicType<string> {
|
|
97
97
|
private constructor();
|
|
@@ -100,12 +100,14 @@ declare class LiveString extends LiveAtomicType<string> {
|
|
|
100
100
|
static createReference(foreignField: `${string}.${string}`): LiveString;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: false positive */
|
|
104
|
+
|
|
103
105
|
type InferLiveObjectWithoutRelations<T extends LiveObjectAny> = {
|
|
104
106
|
[K in keyof T["fields"]]: InferLiveType<T["fields"][K]>;
|
|
105
107
|
};
|
|
106
|
-
type InferLiveObject<T extends LiveObjectAny> = InferLiveObjectWithoutRelations<T> & {
|
|
107
|
-
[K in keyof T["relations"]]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
|
|
108
|
-
};
|
|
108
|
+
type InferLiveObject<T extends LiveObjectAny, Include extends IncludeClause<T> | undefined = undefined> = InferLiveObjectWithoutRelations<T> & (Include extends IncludeClause<T> ? {
|
|
109
|
+
[K in keyof T["relations"] as Include[K] extends true ? K : never]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
|
|
110
|
+
} : {});
|
|
109
111
|
type InferRelationalColumns<T extends Record<string, RelationAny>> = {
|
|
110
112
|
[K in keyof T as T[K] extends Relation<any, any, any, infer ColumnName, any, any> ? ColumnName extends string ? ColumnName : never : never]: T[K]["type"] extends "one" ? T[K] extends Relation<infer Entity, any, any, any, any, any> ? T[K]["required"] extends true ? InferIndex<Entity> : InferIndex<Entity> | undefined : never : never;
|
|
111
113
|
};
|
|
@@ -124,7 +126,7 @@ declare class LiveObject<TName extends string, TSchema extends Record<string, Li
|
|
|
124
126
|
}
|
|
125
127
|
type LiveObjectAny = LiveObject<string, Record<string, LiveTypeAny>, any>;
|
|
126
128
|
declare class Relation<TEntity extends LiveObjectAny, TSourceEntity extends LiveObjectAny, TType extends "one" | "many", TRelationalColumn extends keyof TSourceEntity["fields"], TForeignColumn extends keyof TEntity["fields"], TRequired extends boolean> extends LiveType<InferIndex<TEntity>, {
|
|
127
|
-
timestamp: string;
|
|
129
|
+
timestamp: string | null;
|
|
128
130
|
} & LiveTypeMeta> {
|
|
129
131
|
readonly entity: TEntity;
|
|
130
132
|
readonly type: TType;
|
|
@@ -154,6 +156,13 @@ declare class Relation<TEntity extends LiveObjectAny, TSourceEntity extends Live
|
|
|
154
156
|
} | null
|
|
155
157
|
];
|
|
156
158
|
getStorageFieldType(): StorageFieldType;
|
|
159
|
+
toJSON(): {
|
|
160
|
+
entityName: string;
|
|
161
|
+
type: TType;
|
|
162
|
+
required: TRequired;
|
|
163
|
+
relationalColumn: TRelationalColumn | undefined;
|
|
164
|
+
foreignColumn: TForeignColumn | undefined;
|
|
165
|
+
};
|
|
157
166
|
static createOneFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TOriginEntity["fields"], TRequired extends boolean = false>(entity: TEntity, column: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "one", TColumn, never, TRequired>;
|
|
158
167
|
static createManyFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TEntity["fields"], TRequired extends boolean = false>(entity: TEntity, foreignColumn: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "many", never, TColumn, TRequired>;
|
|
159
168
|
}
|
|
@@ -182,10 +191,25 @@ type RawSchema = Record<string, LiveObjectAny | RelationsDecl>;
|
|
|
182
191
|
type Schema<TRawSchema extends RawSchema> = {
|
|
183
192
|
[K in keyof TRawSchema as TRawSchema[K] extends LiveObjectAny ? TRawSchema[K]["name"] : never]: TRawSchema[K] extends LiveObjectAny ? ParseObjectFromSchema<TRawSchema, TRawSchema[K]["name"]> : never;
|
|
184
193
|
};
|
|
185
|
-
type WhereClause<T extends LiveObjectAny> = {
|
|
186
|
-
[K in keyof T["fields"]]?: InferLiveType<T["fields"][K]
|
|
194
|
+
type WhereClause<T extends LiveObjectAny> = ({
|
|
195
|
+
[K in keyof T["fields"]]?: InferLiveType<T["fields"][K]> | ({
|
|
196
|
+
$eq?: InferLiveType<T["fields"][K]>;
|
|
197
|
+
$in?: InferLiveType<T["fields"][K]>[];
|
|
198
|
+
$not?: InferLiveType<T["fields"][K]> | {
|
|
199
|
+
$in?: InferLiveType<T["fields"][K]>[];
|
|
200
|
+
$eq?: InferLiveType<T["fields"][K]>;
|
|
201
|
+
};
|
|
202
|
+
} & (InferLiveType<T["fields"][K]> extends number ? {
|
|
203
|
+
$gt?: InferLiveType<T["fields"][K]>;
|
|
204
|
+
$gte?: InferLiveType<T["fields"][K]>;
|
|
205
|
+
$lt?: InferLiveType<T["fields"][K]>;
|
|
206
|
+
$lte?: InferLiveType<T["fields"][K]>;
|
|
207
|
+
} : {}));
|
|
187
208
|
} & {
|
|
188
209
|
[K in keyof T["relations"]]?: WhereClause<T["relations"][K]["entity"]>;
|
|
210
|
+
}) | {
|
|
211
|
+
$and?: WhereClause<T>[];
|
|
212
|
+
$or?: WhereClause<T>[];
|
|
189
213
|
};
|
|
190
214
|
type IncludeClause<T extends LiveObjectAny> = {
|
|
191
215
|
[K in keyof T["relations"]]?: boolean;
|
|
@@ -233,11 +257,20 @@ declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends M
|
|
|
233
257
|
}
|
|
234
258
|
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
235
259
|
|
|
260
|
+
type Simplify<T> = T extends Record<string, unknown> ? {
|
|
261
|
+
[K in keyof T]: Simplify<T[K]>;
|
|
262
|
+
} : T;
|
|
263
|
+
|
|
236
264
|
declare abstract class Storage {
|
|
237
|
-
abstract
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
abstract
|
|
265
|
+
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
266
|
+
include?: IncludeClause<T>;
|
|
267
|
+
}): Promise<InferLiveObject<T> | undefined>;
|
|
268
|
+
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
269
|
+
where?: WhereClause<T>;
|
|
270
|
+
include?: IncludeClause<T>;
|
|
271
|
+
}): Promise<Record<string, InferLiveObject<T>>>;
|
|
272
|
+
insert<T extends LiveObjectAny>(resource: T, value: Simplify<LiveObjectMutationInput<T>>): Promise<InferLiveObject<T>>;
|
|
273
|
+
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: LiveObjectMutationInput<T>): Promise<InferLiveObject<T>>;
|
|
241
274
|
}
|
|
242
275
|
|
|
243
276
|
type ParsedRequest<TInput = any> = {
|
|
@@ -259,23 +292,151 @@ type Middleware<T = any> = (opts: {
|
|
|
259
292
|
next: NextFunction<T>;
|
|
260
293
|
}) => ReturnType<NextFunction<T>>;
|
|
261
294
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
type DeepSubscribable<T> = {
|
|
267
|
-
[K in keyof T]: DeepSubscribable<T[K]>;
|
|
268
|
-
} & {
|
|
269
|
-
get: () => T;
|
|
270
|
-
subscribe: (callback: (value: T) => void) => () => void;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
declare const useLiveQuery: <T extends DeepSubscribable<U>, U>(observable: T) => Simplify<ReturnType<T["get"]>>;
|
|
295
|
+
declare const useLiveQuery: <T extends {
|
|
296
|
+
get: () => U;
|
|
297
|
+
subscribe: (cb: (v: U) => void) => () => void;
|
|
298
|
+
}, U>(observable: T) => ReturnType<T["get"]>;
|
|
274
299
|
declare const SubscriptionProvider: ({ children, client, }: {
|
|
275
300
|
children: React.ReactNode;
|
|
276
301
|
client: Client<AnyRouter>["client"];
|
|
277
302
|
}) => react_jsx_runtime.JSX.Element;
|
|
278
303
|
|
|
304
|
+
declare const serverMessageSchema: z.ZodUnion<[z.ZodObject<{
|
|
305
|
+
id: z.ZodString;
|
|
306
|
+
type: z.ZodLiteral<"REJECT">;
|
|
307
|
+
resource: z.ZodString;
|
|
308
|
+
message: z.ZodOptional<z.ZodString>;
|
|
309
|
+
}, "strip", z.ZodTypeAny, {
|
|
310
|
+
type: "REJECT";
|
|
311
|
+
id: string;
|
|
312
|
+
resource: string;
|
|
313
|
+
message?: string | undefined;
|
|
314
|
+
}, {
|
|
315
|
+
type: "REJECT";
|
|
316
|
+
id: string;
|
|
317
|
+
resource: string;
|
|
318
|
+
message?: string | undefined;
|
|
319
|
+
}>, z.ZodObject<{
|
|
320
|
+
id: z.ZodString;
|
|
321
|
+
type: z.ZodLiteral<"REPLY">;
|
|
322
|
+
data: z.ZodAny;
|
|
323
|
+
}, "strip", z.ZodTypeAny, {
|
|
324
|
+
type: "REPLY";
|
|
325
|
+
id: string;
|
|
326
|
+
data?: any;
|
|
327
|
+
}, {
|
|
328
|
+
type: "REPLY";
|
|
329
|
+
id: string;
|
|
330
|
+
data?: any;
|
|
331
|
+
}>, z.ZodObject<z.objectUtil.extendShape<z.objectUtil.extendShape<{
|
|
332
|
+
id: z.ZodOptional<z.ZodString>;
|
|
333
|
+
type: z.ZodLiteral<"MUTATE">;
|
|
334
|
+
resource: z.ZodString;
|
|
335
|
+
}, {
|
|
336
|
+
resourceId: z.ZodString;
|
|
337
|
+
payload: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
338
|
+
value: z.ZodNullable<z.ZodUnion<[z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>>;
|
|
339
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
340
|
+
timestamp: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
341
|
+
}, "strip", z.ZodTypeAny, {
|
|
342
|
+
timestamp?: string | null | undefined;
|
|
343
|
+
}, {
|
|
344
|
+
timestamp?: string | null | undefined;
|
|
345
|
+
}>>;
|
|
346
|
+
}, "strip", z.ZodTypeAny, {
|
|
347
|
+
value: string | number | boolean | Date | null;
|
|
348
|
+
_meta?: {
|
|
349
|
+
timestamp?: string | null | undefined;
|
|
350
|
+
} | undefined;
|
|
351
|
+
}, {
|
|
352
|
+
value: string | number | boolean | Date | null;
|
|
353
|
+
_meta?: {
|
|
354
|
+
timestamp?: string | null | undefined;
|
|
355
|
+
} | undefined;
|
|
356
|
+
}>>, Record<string, {
|
|
357
|
+
value: string | number | boolean | Date | null;
|
|
358
|
+
_meta?: {
|
|
359
|
+
timestamp?: string | null | undefined;
|
|
360
|
+
} | undefined;
|
|
361
|
+
}>, Record<string, {
|
|
362
|
+
value: string | number | boolean | Date | null;
|
|
363
|
+
_meta?: {
|
|
364
|
+
timestamp?: string | null | undefined;
|
|
365
|
+
} | undefined;
|
|
366
|
+
}>>;
|
|
367
|
+
}>, {
|
|
368
|
+
id: z.ZodString;
|
|
369
|
+
}>, "strip", z.ZodTypeAny, {
|
|
370
|
+
type: "MUTATE";
|
|
371
|
+
id: string;
|
|
372
|
+
resource: string;
|
|
373
|
+
payload: Record<string, {
|
|
374
|
+
value: string | number | boolean | Date | null;
|
|
375
|
+
_meta?: {
|
|
376
|
+
timestamp?: string | null | undefined;
|
|
377
|
+
} | undefined;
|
|
378
|
+
}>;
|
|
379
|
+
resourceId: string;
|
|
380
|
+
}, {
|
|
381
|
+
type: "MUTATE";
|
|
382
|
+
id: string;
|
|
383
|
+
resource: string;
|
|
384
|
+
payload: Record<string, {
|
|
385
|
+
value: string | number | boolean | Date | null;
|
|
386
|
+
_meta?: {
|
|
387
|
+
timestamp?: string | null | undefined;
|
|
388
|
+
} | undefined;
|
|
389
|
+
}>;
|
|
390
|
+
resourceId: string;
|
|
391
|
+
}>]>;
|
|
392
|
+
type ServerMessage = z.infer<typeof serverMessageSchema>;
|
|
393
|
+
|
|
394
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
395
|
+
|
|
396
|
+
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>>[];
|
|
397
|
+
declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false> {
|
|
398
|
+
private _collection;
|
|
399
|
+
private _client;
|
|
400
|
+
private _where;
|
|
401
|
+
private _include;
|
|
402
|
+
private _limit?;
|
|
403
|
+
private _single?;
|
|
404
|
+
private _sort?;
|
|
405
|
+
private constructor();
|
|
406
|
+
where(where: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, TSingle>;
|
|
407
|
+
include<TNewInclude extends IncludeClause<TCollection>>(include: TNewInclude): QueryBuilder<TCollection, TInclude & TNewInclude, TSingle>;
|
|
408
|
+
get(): InferQueryResult<TCollection, TInclude, TSingle>;
|
|
409
|
+
subscribe(callback: (value: InferQueryResult<TCollection, TInclude, TSingle>) => void): () => void;
|
|
410
|
+
limit(limit: number): QueryBuilder<TCollection, TInclude, TSingle>;
|
|
411
|
+
one(id: string): QueryBuilder<TCollection, TInclude, true>;
|
|
412
|
+
first(where?: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, true>;
|
|
413
|
+
orderBy(key: keyof TCollection["fields"], direction?: "asc" | "desc"): QueryBuilder<TCollection, TInclude, TSingle>;
|
|
414
|
+
toJSON(): {
|
|
415
|
+
resource: string;
|
|
416
|
+
where: WhereClause<TCollection>;
|
|
417
|
+
include: TInclude;
|
|
418
|
+
limit: number | undefined;
|
|
419
|
+
sort: {
|
|
420
|
+
key: string;
|
|
421
|
+
direction: "asc" | "desc";
|
|
422
|
+
}[] | undefined;
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
type Client$1<TRouter extends AnyRouter> = {
|
|
427
|
+
query: {
|
|
428
|
+
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["_resourceSchema"]>;
|
|
429
|
+
};
|
|
430
|
+
mutate: {
|
|
431
|
+
[K in keyof TRouter["routes"]]: {
|
|
432
|
+
insert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => void;
|
|
433
|
+
update: (id: string, value: Omit<Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>, "id">) => void;
|
|
434
|
+
} & {
|
|
435
|
+
[K2 in keyof TRouter["routes"][K]["customMutations"]]: (input: z.infer<TRouter["routes"][K]["customMutations"][K2]["inputValidator"]>) => Promisify<ReturnType<TRouter["routes"][K]["customMutations"][K2]["handler"]>>;
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
};
|
|
439
|
+
|
|
279
440
|
type WebSocketClientEventMap = WebSocketEventMap & {
|
|
280
441
|
connectionChange: {
|
|
281
442
|
open: boolean;
|
|
@@ -315,24 +476,22 @@ declare class WebSocketClient {
|
|
|
315
476
|
private dispatchEvent;
|
|
316
477
|
}
|
|
317
478
|
|
|
318
|
-
type
|
|
319
|
-
|
|
479
|
+
type ConnectionStateChangeEvent = {
|
|
480
|
+
type: "CONNECTION_STATE_CHANGE";
|
|
481
|
+
open: boolean;
|
|
320
482
|
};
|
|
483
|
+
type MessageReceivedEvent = {
|
|
484
|
+
type: "MESSAGE_RECEIVED";
|
|
485
|
+
message: ServerMessage;
|
|
486
|
+
};
|
|
487
|
+
type ClientEvents = ConnectionStateChangeEvent | MessageReceivedEvent;
|
|
321
488
|
type Client<TRouter extends AnyRouter> = {
|
|
322
489
|
client: {
|
|
323
490
|
ws: WebSocketClient;
|
|
324
491
|
subscribe: (resourceType?: string[]) => () => void;
|
|
492
|
+
addEventListener: (listener: (event: ClientEvents) => void) => () => void;
|
|
325
493
|
};
|
|
326
|
-
store:
|
|
327
|
-
[K in keyof TRouter["routes"]]: {
|
|
328
|
-
insert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => void;
|
|
329
|
-
update: (id: string, value: Omit<Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>, "id">) => void;
|
|
330
|
-
};
|
|
331
|
-
} & {
|
|
332
|
-
[K in keyof TRouter["routes"]]: {
|
|
333
|
-
[K2 in keyof TRouter["routes"][K]["customMutations"]]: (input: z.infer<TRouter["routes"][K]["customMutations"][K2]["inputValidator"]>) => Promisify<ReturnType<TRouter["routes"][K]["customMutations"][K2]["handler"]>>;
|
|
334
|
-
};
|
|
335
|
-
};
|
|
494
|
+
store: Client$1<TRouter>;
|
|
336
495
|
};
|
|
337
496
|
declare const createClient: <TRouter extends AnyRouter>(opts: ClientOptions) => Client<TRouter>;
|
|
338
497
|
|
|
@@ -340,6 +499,9 @@ type ClientOptions = {
|
|
|
340
499
|
url: string;
|
|
341
500
|
schema: Schema<any>;
|
|
342
501
|
credentials?: Generatable<Awaitable<Record<string, string>>>;
|
|
502
|
+
storage: {
|
|
503
|
+
name: string;
|
|
504
|
+
} | false;
|
|
343
505
|
};
|
|
344
506
|
|
|
345
|
-
export { type AnyRouter as A, type ClientOptions as C, type IncludeClause as I, type LiveObjectAny as L, type Simplify as S, type WhereClause as W, type InferLiveObject as a, type LiveObjectMutationInput as b, SubscriptionProvider as c, type
|
|
507
|
+
export { type AnyRouter as A, type ClientOptions as C, type IncludeClause as I, type LiveObjectAny as L, type MessageReceivedEvent as M, type Simplify as S, type WhereClause as W, type InferLiveObject as a, type LiveObjectMutationInput as b, SubscriptionProvider as c, type ConnectionStateChangeEvent as d, type ClientEvents as e, type Client as f, createClient as g, useLiveQuery as u };
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var s=class{_value;_meta;_encodeInput;_decodeInput};var c=class extends s{inner;constructor(e){super(),this.inner=e;}encodeMutation(e,t,n){return this.inner.encodeMutation(e,t,n)}mergeMutation(e,t,n){return this.inner.mergeMutation(e,t,n)}getStorageFieldType(){return {...this.inner.getStorageFieldType(),nullable:true}}},o=class a extends s{storageType;convertFunc;isIndex;isUnique;defaultValue;foreignReference;isPrimary;constructor(e,t,n,r,i,u,y){super(),this.storageType=e,this.convertFunc=t,this.isIndex=n??false,this.isUnique=r??false,this.defaultValue=i,this.foreignReference=u,this.isPrimary=y??false;}encodeMutation(e,t,n){return {value:t,_meta:{timestamp:n}}}mergeMutation(e,t,n){return n&&n._meta.timestamp&&t._meta.timestamp&&n._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[n,null]:[{value:this.convertFunc?this.convertFunc(t.value):t.value,_meta:t._meta},t]}getStorageFieldType(){return {type:this.storageType,nullable:false,index:this.isIndex,unique:this.isUnique,default:this.defaultValue,references:this.foreignReference,primary:this.isPrimary}}unique(){return new a(this.storageType,this.convertFunc,this.isIndex,true,this.defaultValue,this.foreignReference,this.isPrimary)}index(){return new a(this.storageType,this.convertFunc,true,this.isUnique,this.defaultValue,this.foreignReference,this.isPrimary)}default(e){return new a(this.storageType,this.convertFunc,this.isIndex,this.isUnique,e,this.foreignReference,this.isPrimary)}primary(){return new a(this.storageType,this.convertFunc,this.isIndex,this.isUnique,this.defaultValue,this.foreignReference,true)}nullable(){return new c(this)}},p=class a extends o{constructor(){super("integer",e=>Number(e));}static create(){return new a}},g=p.create,l=class a extends o{constructor(e){super("varchar",void 0,void 0,void 0,void 0,e);}static create(){return new a}static createId(){return new a().index().unique().primary()}static createReference(e){return new a(e)}},b=l.create,M=l.createId,I=l.createReference,d=class a extends o{constructor(){super("boolean",e=>typeof e=="string"?e.toLowerCase()==="true":!!e);}static create(){return new a}},O=d.create,m=class a extends o{constructor(){super("timestamp",e=>typeof e=="string"?new Date(e):e);}static create(){return new a}},j=m.create;var v=class a extends s{name;fields;relations;constructor(e,t,n){super(),this.name=e,this.fields=t,this.relations=n??{};}encodeMutation(e,t,n){return Object.fromEntries(Object.entries(t).map(([r,i])=>[r,(this.fields[r]??this.relations[r]).encodeMutation("set",i,n)]))}mergeMutation(e,t,n){let r={};return [{value:{...(n==null?void 0:n.value)??{},...Object.fromEntries(Object.entries(t).map(([i,u])=>{let y=this.fields[i]??this.relations[i];if(!y)return [i,u];let[x,f]=y.mergeMutation(e,u,n==null?void 0:n.value[i]);return f&&(r[i]=f),[i,x]}))}},r]}setRelations(e){return new a(this.name,this.fields,e)}getStorageFieldType(){throw new Error("Method not implemented.")}static create(e,t){return new a(e,t)}},K=v.create,T=class a extends s{entity;type;required;relationalColumn;foreignColumn;sourceEntity;constructor(e,t,n,r,i){super(),this.entity=e,this.type=t,this.required=i??false,this.relationalColumn=n,this.foreignColumn=r;}encodeMutation(e,t,n){if(e!=="set")throw new Error("Mutation type not implemented.");if(this.type==="many")throw new Error("Many not implemented.");return {value:t,_meta:{timestamp:n}}}mergeMutation(e,t,n){if(this.type==="many")throw new Error("Many not implemented.");return n&&n._meta.timestamp&&t._meta.timestamp&&n._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[n,null]:[t,t]}getStorageFieldType(){return {type:"varchar",nullable:!this.required,references:`${this.entity.name}.${String(this.foreignColumn??this.relationalColumn??"id")}`}}toJSON(){return {entityName:this.entity.name,type:this.type,required:this.required,relationalColumn:this.relationalColumn,foreignColumn:this.foreignColumn}}static createOneFactory(){return (e,t,n)=>new a(e,"one",t,void 0,n??false)}static createManyFactory(){return (e,t,n)=>new a(e,"many",void 0,t,n??false)}},A=(a,e)=>({$type:"relations",objectName:a.name,relations:e({one:T.createOneFactory(),many:T.createManyFactory()})}),h=a=>{if(a)return Array.isArray(a.value)?a.value.map(e=>h(e)):typeof a.value!="object"||a.value===null||a.value instanceof Date?a.value:Object.fromEntries(Object.entries(a.value).map(([e,t])=>[e,h(t)]))},_=a=>Object.fromEntries(Object.entries(a).flatMap(([e,t])=>{if(t.$type==="relations")return [];let n=t,r=Object.values(a).find(i=>i.$type==="relations"&&i.objectName===t.name);return r&&(n=n.setRelations(r.relations)),[[n.name,n]]}));exports.LiveBoolean=d;exports.LiveNumber=p;exports.LiveObject=v;exports.LiveString=l;exports.LiveTimestamp=m;exports.LiveType=s;exports.Relation=T;exports.boolean=O;exports.createRelations=A;exports.createSchema=_;exports.id=M;exports.inferValue=h;exports.number=g;exports.object=K;exports.reference=I;exports.string=b;exports.timestamp=j;
|
package/dist/index.d.cts
CHANGED
|
@@ -34,18 +34,18 @@ type InferLiveType<T extends LiveTypeAny> = T["_value"] extends Record<string, L
|
|
|
34
34
|
} : T["_value"];
|
|
35
35
|
type InferIndex<T extends LiveTypeAny> = string;
|
|
36
36
|
|
|
37
|
-
declare class
|
|
37
|
+
declare class NullableLiveType<T extends LiveTypeAny> extends LiveType<T["_value"] | null, T["_meta"], T["_encodeInput"], T["_decodeInput"]> {
|
|
38
38
|
readonly inner: T;
|
|
39
39
|
constructor(inner: T);
|
|
40
|
-
encodeMutation(mutationType: MutationType, input: T["_value"] |
|
|
41
|
-
mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] |
|
|
42
|
-
MaterializedLiveType<LiveType<T["_value"] |
|
|
40
|
+
encodeMutation(mutationType: MutationType, input: T["_value"] | null, timestamp: string): T["_decodeInput"];
|
|
41
|
+
mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] | null, T["_meta"], T["_value"] | Partial<T["_value"] | null>, T["_decodeInput"]>> | undefined): [
|
|
42
|
+
MaterializedLiveType<LiveType<T["_value"] | null, T["_meta"], T["_value"] | Partial<T["_value"] | null>, T["_decodeInput"]>>,
|
|
43
43
|
T["_decodeInput"] | null
|
|
44
44
|
];
|
|
45
45
|
getStorageFieldType(): StorageFieldType;
|
|
46
46
|
}
|
|
47
47
|
type LiveAtomicTypeMeta = {
|
|
48
|
-
timestamp: string;
|
|
48
|
+
timestamp: string | null;
|
|
49
49
|
} & LiveTypeMeta;
|
|
50
50
|
declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta, Value, {
|
|
51
51
|
value: Value;
|
|
@@ -84,7 +84,7 @@ declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta,
|
|
|
84
84
|
index(): LiveAtomicType<Value>;
|
|
85
85
|
default(value: Value): LiveAtomicType<Value>;
|
|
86
86
|
primary(): LiveAtomicType<Value>;
|
|
87
|
-
|
|
87
|
+
nullable(): NullableLiveType<this>;
|
|
88
88
|
}
|
|
89
89
|
declare class LiveNumber extends LiveAtomicType<number> {
|
|
90
90
|
private constructor();
|
|
@@ -111,12 +111,14 @@ declare class LiveTimestamp extends LiveAtomicType<Date> {
|
|
|
111
111
|
}
|
|
112
112
|
declare const timestamp: typeof LiveTimestamp.create;
|
|
113
113
|
|
|
114
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: false positive */
|
|
115
|
+
|
|
114
116
|
type InferLiveObjectWithoutRelations<T extends LiveObjectAny> = {
|
|
115
117
|
[K in keyof T["fields"]]: InferLiveType<T["fields"][K]>;
|
|
116
118
|
};
|
|
117
|
-
type InferLiveObject<T extends LiveObjectAny> = InferLiveObjectWithoutRelations<T> & {
|
|
118
|
-
[K in keyof T["relations"]]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
|
|
119
|
-
};
|
|
119
|
+
type InferLiveObject<T extends LiveObjectAny, Include extends IncludeClause<T> | undefined = undefined> = InferLiveObjectWithoutRelations<T> & (Include extends IncludeClause<T> ? {
|
|
120
|
+
[K in keyof T["relations"] as Include[K] extends true ? K : never]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
|
|
121
|
+
} : {});
|
|
120
122
|
type InferRelationalColumns<T extends Record<string, RelationAny>> = {
|
|
121
123
|
[K in keyof T as T[K] extends Relation<any, any, any, infer ColumnName, any, any> ? ColumnName extends string ? ColumnName : never : never]: T[K]["type"] extends "one" ? T[K] extends Relation<infer Entity, any, any, any, any, any> ? T[K]["required"] extends true ? InferIndex<Entity> : InferIndex<Entity> | undefined : never : never;
|
|
122
124
|
};
|
|
@@ -136,7 +138,7 @@ declare class LiveObject<TName extends string, TSchema extends Record<string, Li
|
|
|
136
138
|
declare const object: typeof LiveObject.create;
|
|
137
139
|
type LiveObjectAny = LiveObject<string, Record<string, LiveTypeAny>, any>;
|
|
138
140
|
declare class Relation<TEntity extends LiveObjectAny, TSourceEntity extends LiveObjectAny, TType extends "one" | "many", TRelationalColumn extends keyof TSourceEntity["fields"], TForeignColumn extends keyof TEntity["fields"], TRequired extends boolean> extends LiveType<InferIndex<TEntity>, {
|
|
139
|
-
timestamp: string;
|
|
141
|
+
timestamp: string | null;
|
|
140
142
|
} & LiveTypeMeta> {
|
|
141
143
|
readonly entity: TEntity;
|
|
142
144
|
readonly type: TType;
|
|
@@ -166,6 +168,13 @@ declare class Relation<TEntity extends LiveObjectAny, TSourceEntity extends Live
|
|
|
166
168
|
} | null
|
|
167
169
|
];
|
|
168
170
|
getStorageFieldType(): StorageFieldType;
|
|
171
|
+
toJSON(): {
|
|
172
|
+
entityName: string;
|
|
173
|
+
type: TType;
|
|
174
|
+
required: TRequired;
|
|
175
|
+
relationalColumn: TRelationalColumn | undefined;
|
|
176
|
+
foreignColumn: TForeignColumn | undefined;
|
|
177
|
+
};
|
|
169
178
|
static createOneFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TOriginEntity["fields"], TRequired extends boolean = false>(entity: TEntity, column: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "one", TColumn, never, TRequired>;
|
|
170
179
|
static createManyFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TEntity["fields"], TRequired extends boolean = false>(entity: TEntity, foreignColumn: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "many", never, TColumn, TRequired>;
|
|
171
180
|
}
|
|
@@ -200,10 +209,25 @@ type Schema<TRawSchema extends RawSchema> = {
|
|
|
200
209
|
[K in keyof TRawSchema as TRawSchema[K] extends LiveObjectAny ? TRawSchema[K]["name"] : never]: TRawSchema[K] extends LiveObjectAny ? ParseObjectFromSchema<TRawSchema, TRawSchema[K]["name"]> : never;
|
|
201
210
|
};
|
|
202
211
|
declare const createSchema: <TRawSchema extends RawSchema>(schema: TRawSchema) => Schema<TRawSchema>;
|
|
203
|
-
type WhereClause<T extends LiveObjectAny> = {
|
|
204
|
-
[K in keyof T["fields"]]?: InferLiveType<T["fields"][K]
|
|
212
|
+
type WhereClause<T extends LiveObjectAny> = ({
|
|
213
|
+
[K in keyof T["fields"]]?: InferLiveType<T["fields"][K]> | ({
|
|
214
|
+
$eq?: InferLiveType<T["fields"][K]>;
|
|
215
|
+
$in?: InferLiveType<T["fields"][K]>[];
|
|
216
|
+
$not?: InferLiveType<T["fields"][K]> | {
|
|
217
|
+
$in?: InferLiveType<T["fields"][K]>[];
|
|
218
|
+
$eq?: InferLiveType<T["fields"][K]>;
|
|
219
|
+
};
|
|
220
|
+
} & (InferLiveType<T["fields"][K]> extends number ? {
|
|
221
|
+
$gt?: InferLiveType<T["fields"][K]>;
|
|
222
|
+
$gte?: InferLiveType<T["fields"][K]>;
|
|
223
|
+
$lt?: InferLiveType<T["fields"][K]>;
|
|
224
|
+
$lte?: InferLiveType<T["fields"][K]>;
|
|
225
|
+
} : {}));
|
|
205
226
|
} & {
|
|
206
227
|
[K in keyof T["relations"]]?: WhereClause<T["relations"][K]["entity"]>;
|
|
228
|
+
}) | {
|
|
229
|
+
$and?: WhereClause<T>[];
|
|
230
|
+
$or?: WhereClause<T>[];
|
|
207
231
|
};
|
|
208
232
|
type IncludeClause<T extends LiveObjectAny> = {
|
|
209
233
|
[K in keyof T["relations"]]?: boolean;
|