@live-state/sync 0.0.3 → 0.0.4-beta.10
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-E7NFSHVD.js +1 -0
- package/dist/chunk-GUSCESQZ.js +1 -0
- package/dist/client.d.ts +3 -1
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +4 -13
- package/dist/fetch-client.js +1 -1
- package/dist/{index-4Y_YcJTJ.d.ts → index-C5AAiO4g.d.ts} +151 -145
- package/dist/index-COp5Ib0a.d.cts +282 -0
- package/dist/index-COp5Ib0a.d.ts +282 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -236
- package/dist/index.d.ts +1 -236
- package/dist/index.js +1 -1
- package/dist/server.cjs +2 -2
- package/dist/server.d.cts +119 -122
- package/dist/server.d.ts +119 -122
- package/dist/server.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-G5SVBG4B.js +0 -1
- package/dist/chunk-LLHCJUB6.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var b="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var l;(function(t){t.Base32IncorrectEncoding="B32_ENC_INVALID",t.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",t.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",t.EncodeTimeNegative="ENC_TIME_NEG",t.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",t.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",t.PRNGDetectFailure="PRNG_DETECT",t.ULIDInvalid="ULID_INVALID",t.Unexpected="UNEXPECTED",t.UUIDInvalid="UUID_INVALID";})(l||(l={}));var u=class extends Error{constructor(e,n){super(`${n} (${e})`),this.name="ULIDError",this.code=e;}};function L(t){let e=Math.floor(t()*32);return e===32&&(e=31),b.charAt(e)}function R(t){let e=w(),n=e&&(e.crypto||e.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 w(){return E()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function A(t,e){let n="";for(;t>0;t--)n=L(e)+n;return n}function M(t,e=10){if(isNaN(t))throw new u(l.EncodeTimeValueMalformed,`Time must be a number: ${t}`);if(t>0xffffffffffff)throw new u(l.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${0xffffffffffff}: ${t}`);if(t<0)throw new u(l.EncodeTimeNegative,`Time must be positive: ${t}`);if(Number.isInteger(t)===false)throw new u(l.EncodeTimeValueMalformed,`Time must be an integer: ${t}`);let n,i="";for(let r=e;r>0;r--)n=t%32,i=b.charAt(n)+i,t=(t-n)/32;return i}function E(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function I(t,e){let n=R(),i=Date.now();return M(i,10)+A(16,n)}var N=()=>I().toLowerCase(),j=(t,e)=>typeof t=="function"?t(e):t;var _=class t{_collection;_client;_where;_include;_limit;_single;_sort;_shouldAwait;constructor(e,n,i,r,a,s,o,T){this._collection=e,this._client=n,this._where=i??{},this._include=r??{},this._limit=a,this._single=s,this._sort=o,this._shouldAwait=T,this.get=this.get.bind(this),this.subscribe=this.subscribe.bind(this);}where(e){return new t(this._collection,this._client,{...this._where,...e},this._include,this._limit,this._single,this._sort,this._shouldAwait)}include(e){return new t(this._collection,this._client,this._where,{...this._include,...e},this._limit,this._single,this._sort,this._shouldAwait)}get(){let e=this._client.get({resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort});return this._shouldAwait?Promise.resolve(e).then(n=>this._single?n[0]:n):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},n=>{if(this._single)return e(n[0]);e(n);})}limit(e){return new t(this._collection,this._client,this._where,this._include,e,this._single,this._sort,this._shouldAwait)}one(e){return this.first({id:e})}first(e){return new t(this._collection,this._client,e??this._where,this._include,1,true,this._sort,this._shouldAwait)}orderBy(e,n="asc"){let i=[...this._sort??[],{key:e,direction:n}];return new t(this._collection,this._client,this._where,this._include,this._limit,this._single,i,this._shouldAwait)}toJSON(){return {resource:this._collection.name,where:this._where,include:this._include,limit:this._limit,sort:this._sort}}static _init(e,n,i){return new t(e,n,void 0,void 0,void 0,void 0,void 0,i??false)}};var O=(t,e,n=[])=>new Proxy(t,{get:(i,r)=>{var T,y;if(r==="__isProxy__")return true;let a=(T=e.get)==null?void 0:T.call(e,i,[...n,r]);if(a!==void 0)return a;let s=i,o=r;return (y=s[o])!=null&&y.__isProxy__||(s[o]=O(typeof s[o]=="object"?s[o]:()=>{},e,[...n,r])),s[o]},apply:(i,r,a)=>{var s;return (s=e.apply)==null?void 0:s.call(e,i,n,a)}}),D=(t,e,n)=>{let i=[],r=0;for(let a=0;a<t.length&&(n===void 0||r<n);a++)e(t[a],a)&&(i.push(t[a]),r++);return i};var g=t=>t?Array.isArray(t.value)?t.value.map(n=>g(n)):typeof t.value!="object"||t.value===null||t.value instanceof Date?t.value:Object.fromEntries(Object.entries(t.value).map(([n,i])=>Array.isArray(i)?[n,i.map(r=>g(r))]:[n,g(i)])):void 0;export{N as a,j as b,_ as c,O as d,D as e,g as f};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import'js-xxhash';var O=Object.create;var I=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var V=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var K=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of M(e))!S.call(t,a)&&a!==n&&I(t,a,{get:()=>e[a],enumerable:!(i=A(e,a))||i.enumerable});return t};var C=(t,e,n)=>(n=t!=null?O(j(t)):{},K(e||!t||!t.__esModule?I(n,"default",{value:t,enumerable:true}):n,t));var o=class{_value;_meta;_encodeInput;_decodeInput};var m=class extends o{inner;constructor(e){super(),this.inner=e;}encodeMutation(e,n,i){return this.inner.encodeMutation(e,n,i)}mergeMutation(e,n,i){return this.inner.mergeMutation(e,n,i)}getStorageFieldType(){return {...this.inner.getStorageFieldType(),nullable:true}}},y=class t extends o{storageType;convertFunc;isIndex;isUnique;defaultValue;foreignReference;isPrimary;constructor(e,n,i,a,s,l,r){super(),this.storageType=e,this.convertFunc=n,this.isIndex=i??false,this.isUnique=a??false,this.defaultValue=s,this.foreignReference=l,this.isPrimary=r??false;}encodeMutation(e,n,i){return {value:n,_meta:{timestamp:i}}}mergeMutation(e,n,i){return i&&i._meta.timestamp&&n._meta.timestamp&&i._meta.timestamp.localeCompare(n._meta.timestamp)>=0?[i,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 m(this)}},v=class t extends y{constructor(){super("integer",e=>Number(e));}static create(){return new t}},F=v.create,d=class t extends y{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)}},q=d.create,N=d.createId,D=d.createReference,h=class t extends y{constructor(){super("boolean",e=>typeof e=="string"?e.toLowerCase()==="true":!!e);}static create(){return new t}},W=h.create,L=class t extends y{constructor(){super("timestamp",e=>typeof e=="string"?new Date(e):e);}static create(){return new t}},P=L.create;var g=class t extends o{name;fields;relations;constructor(e,n,i){super(),this.name=e,this.fields=n,this.relations=i??{};}encodeMutation(e,n,i){return Object.fromEntries(Object.entries(n).map(([a,s])=>[a,(this.fields[a]??this.relations[a]).encodeMutation("set",s,i)]))}mergeMutation(e,n,i){let a={};return [{value:{...(i==null?void 0:i.value)??{},...Object.fromEntries(Object.entries(n).map(([s,l])=>{let r=this.fields[s]??this.relations[s];if(!r)return [s,l];let[u,p]=r.mergeMutation(e,l,i==null?void 0:i.value[s]);return p&&(a[s]=p),[s,u]}))}},a]}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)}},z=g.create,f=class t extends o{entity;type;required;relationalColumn;foreignColumn;sourceEntity;constructor(e,n,i,a,s){super(),this.entity=e,this.type=n,this.required=s??false,this.relationalColumn=i,this.foreignColumn=a;}encodeMutation(e,n,i){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:i}}}mergeMutation(e,n,i){if(this.type==="many")throw new Error("Many not implemented.");return i&&i._meta.timestamp&&n._meta.timestamp&&i._meta.timestamp.localeCompare(n._meta.timestamp)>=0?[i,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,i)=>new t(e,"one",n,void 0,i??false)}static createManyFactory(){return (e,n,i)=>new t(e,"many",void 0,n,i??false)}},G=(t,e)=>({$type:"relations",objectName:t.name,relations:e({one:f.createOneFactory(),many:f.createManyFactory()})}),x=t=>t?Array.isArray(t.value)?t.value.map(n=>x(n)):typeof t.value!="object"||t.value===null||t.value instanceof Date?t.value:Object.fromEntries(Object.entries(t.value).map(([n,i])=>Array.isArray(i)?[n,i.map(a=>x(a))]:[n,x(i)])):void 0,H=t=>Object.fromEntries(Object.entries(t).flatMap(([e,n])=>{if(n.$type==="relations")return [];let i=n,a=Object.values(t).find(s=>s.$type==="relations"&&s.objectName===n.name);return a&&(i=i.setRelations(a.relations)),[[i.name,i]]}));var w=(t,e,n)=>{let i={},a=n[e];if(!a)return i;let s=l=>{l.$and?l.$and.forEach(s):l.$or?l.$or.forEach(s):Object.entries(l).forEach(([r,u])=>{var p;if((p=a.relations)!=null&&p[r]&&(i[r]=true,typeof u=="object"&&u!==null&&!Array.isArray(u))){let b=w(u,a.relations[r].entity.name,n);Object.keys(b).length>0&&(i[r]=b);}});};return s(t),i},c=(t,e,n=false)=>Object.entries(e).every(([i,a])=>{if(i==="$and")return a.every(l=>c(t,l,n));if(i==="$or")return a.some(l=>c(t,l,n));let s=(a==null?void 0:a.$eq)!==void 0?a==null?void 0:a.$eq:a;if(typeof a=="object"&&a!==null&&(a==null?void 0:a.$eq)===void 0){if(a.$in!==void 0){let r=t[i];return r===void 0?false:n?!a.$in.includes(r):a.$in.includes(r)}if(a.$not!==void 0&&!n)return c(t,{[i]:a.$not},true);if(a.$gt!==void 0){let r=t[i];return typeof r!="number"?false:n?r<=a.$gt:r>a.$gt}if(a.$gte!==void 0){let r=t[i];return typeof r!="number"?false:n?r<a.$gte:r>=a.$gte}if(a.$lt!==void 0){let r=t[i];return typeof r!="number"?false:n?r>=a.$lt:r<a.$lt}if(a.$lte!==void 0){let r=t[i];return typeof r!="number"?false:n?r>a.$lte:r<=a.$lte}let l=t[i];return !l||typeof l!="object"&&!Array.isArray(l)?false:Array.isArray(l)?n?!l.some(r=>c(r,a,false)):l.some(r=>c(r,a,false)):c(l,a,n)}return n?t[i]!==s:t[i]===s}),T={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},R=class{level;prefix;constructor(e={}){this.level=e.level??T.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=T.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=T.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=T.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=T.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=T.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},Z=t=>new R(t);export{V as a,C as b,o as c,m as d,y as e,v as f,F as g,d as h,q as i,N as j,D as k,h as l,W as m,L as n,P as o,g as p,z as q,f as r,G as s,x as t,H as u,w as v,c as w,T as x,Z as y};
|
package/dist/client.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { d as Client, c as ClientEvents, C as ClientOptions, b as ConnectionStateChangeEvent, M as MessageReceivedEvent, S as SubscriptionProvider, e as createClient, u as useLiveQuery } from './index-C5AAiO4g.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
|
4
|
+
import 'zod/v3';
|
|
5
|
+
import 'zod/v4/core';
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import {d,c,a,f,e,b}from'./chunk-E7NFSHVD.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 g=l=>xxHash32(JSON.stringify(l)).toString(32);var m=(l,e,t=false)=>Object.entries(e).every(([i,s])=>{if(i==="$and")return s.every(o=>m(l,o,t));if(i==="$or")return s.some(o=>m(l,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=l[i];return n===void 0?false:t?!s.$in.includes(n):s.$in.includes(n)}if(s.$not!==void 0&&!t)return m(l,{[i]:s.$not},true);if(s.$gt!==void 0){let n=l[i];return typeof n!="number"?false:t?n<=s.$gt:n>s.$gt}if(s.$gte!==void 0){let n=l[i];return typeof n!="number"?false:t?n<s.$gte:n>=s.$gte}if(s.$lt!==void 0){let n=l[i];return typeof n!="number"?false:t?n>=s.$lt:n<s.$lt}if(s.$lte!==void 0){let n=l[i];return typeof n!="number"?false:t?n>s.$lte:n<=s.$lte}let o=l[i];return !o||typeof o!="object"&&!Array.isArray(o)?false:Array.isArray(o)?t?!o.some(n=>m(n,s,false)):o.some(n=>m(n,s,false)):m(o,s,t)}return t?l[i]!==r:l[i]===r}),y={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},C=class{level;prefix;constructor(e={}){this.level=e.level??y.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=y.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=y.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=y.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=y.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=y.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},T=l=>new C(l);var j=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)}},J=new j,de=l=>useSyncExternalStore(J.getOrStoreSubscription(l),l.get),he=({children:l,client:e})=>(useEffect(()=>{e.subscribe();},[e.subscribe]),jsx(Fragment,{children:l}));var N=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()}),x=z.record(z.string(),z.object({value:z.string().or(z.number()).or(z.boolean()).or(z.date()).nullable(),_meta:z.object({timestamp:z.string().optional().nullable()}).optional()})),X=x.superRefine((l,e)=>{l.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()}),A=U.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:X});z.union([A,k]);var S=z.string(),ee=z.object({id:S,type:z.literal("SUBSCRIBE"),resource:z.string()}),te=N.extend({id:S,type:z.literal("QUERY")}),H=A.extend({id:S}),ie=k.extend({id:S}),se=z.union([ie,H]);z.union([ee,te,se]);var ne=z.object({id:S,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),re=z.object({id:S,type:z.literal("REPLY"),data:z.any()}),Q=z.union([ne,re,H]),K=z.object({resource:z.string(),data:z.record(z.string(),x)});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 w=class{constructor(e){this.logger=e;this.nodes=new Map;}nodes;createNode(e,t,i){if(this.nodes.has(e))throw new Error(`Node with id ${e} already exists`);let 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",O="databases",R=class{db;async init(e,t){var p,h;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,d])=>[c,await g(d)]))),n=await openDB("live-state-databases",1,{upgrade(c){c.objectStoreNames.contains(O)||c.createObjectStore(O);}}),a=(h=await this.getAll(n,O))==null?void 0:h[t];(a==null?void 0:a.schemaHash)!==r&&s++,this.db=await openDB(t,s,{async upgrade(c){[...Object.keys(e),W].forEach(d=>{(a==null?void 0:a.objectHashes[d])!==o[d]&&c.objectStoreNames.contains(d)&&c.deleteObjectStore(d),c.objectStoreNames.contains(d)||c.createObjectStore(d);}),await n.put(O,{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 L=class{constructor(e,t,i,s){this.schema=e;this.logger=i,this.optimisticObjGraph=new w(i),this.kvStorage=new R,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,o])=>{this.kvStorage.get(r).then(n=>{!n||Object.keys(n).length===0||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 h of e$1.sort){let c=a[h.key],d=p[h.key];if(c<d)return h.direction==="asc"?-1:1;if(c>d)return h.direction==="asc"?1:-1}return 0};r.sort(n);}if(e$1.where||e$1.limit){let n=e$1.where?a=>m(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 h=p.value;delete h.id,this.kvStorage.set(e,t.resourceId,h);}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){Object.entries(t).forEach(([i,s])=>{this.addMutation(e,{id:i,type:"MUTATE",resource:e,resourceId:i,procedure:"INSERT",payload:s});});}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,h])=>h.type==="one"?[[h.relationalColumn,p]]:[]));Object.entries(i).forEach(([p,h])=>{let c=this.schema[e].relations[a[p]];if(!a[p])return;let d=s==null?void 0:s.value[p],[,b]=c.mergeMutation("set",h,d);if(b){if(!this.optimisticObjGraph.hasNode(b.value)){let M=c.entity.name;this.optimisticObjGraph.createNode(b.value,M,Object.values(this.schema[M].relations).flatMap(I=>I.type==="many"?[I.entity.name]:[]));}d!=null&&d.value&&this.optimisticObjGraph.removeLink(t,c.entity.name),this.optimisticObjGraph.createLink(t,b.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,[h,c])=>{let d=this.schema[s].relations[h];return d&&(d.type==="one"?p[0].push([h,d.entity.name,c??true]):d.type==="many"&&p[1].push([h,d.entity.name,c??true])),p},[[],[]]);return {value:{...r.value,...Object.fromEntries(o.map(([p,h,c])=>[p,this.materializeOneWithInclude(i.references.get(h),typeof c=="object"&&c!==null?c:{})])),...Object.fromEntries(n.map(([p,h,c])=>{let d=i.referencedBy.get(h),b=d instanceof Set;return [p,b?{value:Array.from(d.values()).map(M=>this.materializeOneWithInclude(M,typeof c=="object"&&c!==null?c:{}))}:this.materializeOneWithInclude(d,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(ae(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 P=class{url;ws;store;logger;remoteSubCounters={};eventListeners=new Set;replyHandlers={};constructor(e){var t,i,s,r;this.url=e.url,this.logger=T({level:e.logLevel??y.INFO}),this.store=new L(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 E({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&&(Object.keys(this.store.schema).forEach(n=>{this.sendWsMessage({id:a(),type:"QUERY",resource:n});}),Object.entries(this.remoteSubCounters).forEach(([n,a$1])=>{a$1>0&&this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource: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=Q.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=K.parse(s);this.store.loadConsolidatedState(r.resource,r.data);}}catch(t){this.logger.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,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=l=>{let e=new P(l),t=T({level:l.logLevel??y.INFO,prefix:"Client"});return {client:{ws:e.ws,subscribe:i=>{let s=[];for(let r of i??Object.keys(e.store.schema))s.push(e.subscribeToRemote(r));return ()=>{t.debug("Removing listeners",s),s.forEach(r=>{r();});}},addEventListener:i=>e.addEventListener(i)},store:{query:Object.entries(l.schema).reduce((i,[s,r])=>(i[s]=c._init(r,e),i),{}),mutate:d(()=>{},{apply:(i,s,r)=>{if(s.length<2)return;if(s.length>2)throw new Error("Trying to access an invalid path");let[o,n]=s;if(n==="insert"){let{id:a,...p}=r[0];return e.mutate(o,a,"INSERT",p)}if(n==="update"){let[a,p]=r;return e.mutate(o,a,"UPDATE",p)}return e.genericMutate(o,n,r[0])}})}}};export{he as SubscriptionProvider,Qe as createClient,de as useLiveQuery};
|
package/dist/fetch-client.d.ts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
import { A as AnyRouter, C as ClientOptions,
|
|
1
|
+
import { A as AnyRouter, C as ClientOptions, a as Client } from './index-C5AAiO4g.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
|
4
|
+
import 'zod/v3';
|
|
5
|
+
import 'zod/v4/core';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
headers?: Record<string, string>;
|
|
7
|
-
where?: WhereClause<T>;
|
|
8
|
-
include?: IncludeClause<T>;
|
|
9
|
-
};
|
|
10
|
-
type FetchClient<TRouter extends AnyRouter> = {
|
|
11
|
-
[K in keyof TRouter["routes"]]: {
|
|
12
|
-
get: (opts?: GetOptions<TRouter["routes"][K]["_resourceSchema"]>) => Promise<Record<string, Simplify<InferLiveObject<TRouter["routes"][K]["_resourceSchema"]>>>>;
|
|
13
|
-
upsert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => Promise<void>;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
declare const createClient: <TRouter extends AnyRouter>(opts: Omit<ClientOptions, "storage">) => FetchClient<TRouter>;
|
|
7
|
+
declare const createClient: <TRouter extends AnyRouter>(opts: Omit<ClientOptions, "storage">) => Client<TRouter, true>;
|
|
17
8
|
|
|
18
9
|
export { createClient };
|
package/dist/fetch-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {d,b,c,f}from'./chunk-E7NFSHVD.js';import {stringify}from'qs';var u=async(...e)=>{let o=await fetch(...e),t;try{t=await o.json();}catch{t=await o.text().catch(()=>{});}if(!o.ok)throw new Error(`Failed to fetch: ${o.status} ${o.statusText}`,{cause:t});return t},S=e=>{let o={get:async t=>{let n=stringify(t),a=await b(e.credentials)??{},r=await u(`${e.url}/${t.resource}${n?`?${n}`:""}`,{headers:{...a,"Content-Type":"application/json"}});return !r||typeof r!="object"?[]:Object.entries(r).map(([i,s])=>({...f(s),id:i}))},subscribe:()=>{throw new Error("Fetch client does not support subscriptions")}};return {query:Object.entries(e.schema).reduce((t,[n,a])=>(t[n]=c._init(a,o,true),t),{}),mutate:d(()=>{},{apply:async(t,n,a)=>{if(n.length<2)return;if(n.length>2)throw new Error("Trying to access an invalid path");let[r,i]=n,s=await b(e.credentials)??{};if(i==="insert"){let{id:c,...y}=a[0];await u(`${e.url}/${r}/insert`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({resourceId:c,payload:e.schema[r].encodeMutation("set",y,new Date().toISOString())})});return}if(i==="update"){let[c,y]=a,{id:O,...m}=y;await u(`${e.url}/${r}/update`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({resourceId:c,payload:e.schema[r].encodeMutation("set",m,new Date().toISOString())})});return}await u(`${e.url}/${r}/${i}`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({payload:a[0]})});}})}};export{S as createClient};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type Awaitable<T> = T | Promise<T>;
|
|
6
|
-
type Generatable<T, Arg = never> = T | ((arg: Arg) => T);
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import * as z3 from 'zod/v3';
|
|
4
|
+
import * as z4 from 'zod/v4/core';
|
|
7
5
|
|
|
8
6
|
type LiveTypeMeta = {};
|
|
9
7
|
type MutationType = "set";
|
|
@@ -54,7 +52,7 @@ declare class NullableLiveType<T extends LiveTypeAny> extends LiveType<T["_value
|
|
|
54
52
|
type LiveAtomicTypeMeta = {
|
|
55
53
|
timestamp: string | null;
|
|
56
54
|
} & LiveTypeMeta;
|
|
57
|
-
declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta, Value, {
|
|
55
|
+
declare class LiveAtomicType<Value, DefaultValue = undefined> extends LiveType<Value, LiveAtomicTypeMeta, Value, {
|
|
58
56
|
value: Value;
|
|
59
57
|
_meta: LiveAtomicTypeMeta;
|
|
60
58
|
}> {
|
|
@@ -62,10 +60,10 @@ declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta,
|
|
|
62
60
|
readonly convertFunc?: (value: any) => Value;
|
|
63
61
|
readonly isIndex: boolean;
|
|
64
62
|
readonly isUnique: boolean;
|
|
65
|
-
readonly defaultValue
|
|
63
|
+
readonly defaultValue: DefaultValue;
|
|
66
64
|
readonly foreignReference?: string;
|
|
67
65
|
readonly isPrimary: boolean;
|
|
68
|
-
constructor(storageType: string, convertFunc?: (value: any) => Value, index?: boolean, unique?: boolean, defaultValue?:
|
|
66
|
+
constructor(storageType: string, convertFunc?: (value: any) => Value, index?: boolean, unique?: boolean, defaultValue?: DefaultValue, references?: string, primary?: boolean);
|
|
69
67
|
encodeMutation(mutationType: MutationType, input: Value, timestamp: string): {
|
|
70
68
|
value: Value;
|
|
71
69
|
_meta: LiveAtomicTypeMeta;
|
|
@@ -87,16 +85,16 @@ declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta,
|
|
|
87
85
|
} | null
|
|
88
86
|
];
|
|
89
87
|
getStorageFieldType(): StorageFieldType;
|
|
90
|
-
unique(): LiveAtomicType<Value>;
|
|
91
|
-
index(): LiveAtomicType<Value>;
|
|
92
|
-
default(value: Value): LiveAtomicType<Value>;
|
|
93
|
-
primary(): LiveAtomicType<Value>;
|
|
88
|
+
unique(): LiveAtomicType<Value, undefined>;
|
|
89
|
+
index(): LiveAtomicType<Value, undefined>;
|
|
90
|
+
default(value: Value): LiveAtomicType<Value, Value>;
|
|
91
|
+
primary(): LiveAtomicType<Value, undefined>;
|
|
94
92
|
nullable(): NullableLiveType<this>;
|
|
95
93
|
}
|
|
96
94
|
declare class LiveString extends LiveAtomicType<string> {
|
|
97
95
|
private constructor();
|
|
98
96
|
static create(): LiveString;
|
|
99
|
-
static createId(): LiveAtomicType<string>;
|
|
97
|
+
static createId(): LiveAtomicType<string, undefined>;
|
|
100
98
|
static createReference(foreignField: `${string}.${string}`): LiveString;
|
|
101
99
|
}
|
|
102
100
|
|
|
@@ -106,10 +104,10 @@ type InferLiveObjectWithoutRelations<T extends LiveObjectAny> = {
|
|
|
106
104
|
[K in keyof T["fields"]]: InferLiveType<T["fields"][K]>;
|
|
107
105
|
};
|
|
108
106
|
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"]>[];
|
|
107
|
+
[K in keyof T["relations"] as Include[K] extends true ? K : never]: T["relations"][K]["type"] extends "one" ? T["fields"][Exclude<T["relations"][K]["relationalColumn"], undefined>] extends NullableLiveType<any> ? InferLiveObject<T["relations"][K]["entity"]> | null : InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
|
|
110
108
|
} : {});
|
|
111
109
|
type InferRelationalColumns<T extends Record<string, RelationAny>> = {
|
|
112
|
-
[K in keyof T as T[K] extends
|
|
110
|
+
[K in keyof T as T[K]["type"] extends "many" ? never : T[K]["relationalColumn"]]: T[K]["required"] extends true ? InferIndex<T[K]["entity"]> : InferIndex<T[K]["entity"]> | null;
|
|
113
111
|
};
|
|
114
112
|
type InferLiveObjectWithRelationalIds<T extends LiveObjectAny> = keyof T["relations"] extends string ? InferLiveObjectWithoutRelations<T> & InferRelationalColumns<T["relations"]> : InferLiveObjectWithoutRelations<T>;
|
|
115
113
|
type LiveObjectMutationInput<TSchema extends LiveObjectAny> = Partial<InferLiveObjectWithRelationalIds<TSchema>>;
|
|
@@ -199,7 +197,7 @@ type WhereClause<T extends LiveObjectAny> = ({
|
|
|
199
197
|
$in?: InferLiveType<T["fields"][K]>[];
|
|
200
198
|
$eq?: InferLiveType<T["fields"][K]>;
|
|
201
199
|
};
|
|
202
|
-
} & (InferLiveType<T["fields"][K]> extends number ? {
|
|
200
|
+
} & (Exclude<InferLiveType<T["fields"][K]>, null | undefined> extends number | Date ? {
|
|
203
201
|
$gt?: InferLiveType<T["fields"][K]>;
|
|
204
202
|
$gte?: InferLiveType<T["fields"][K]>;
|
|
205
203
|
$lt?: InferLiveType<T["fields"][K]>;
|
|
@@ -212,8 +210,52 @@ type WhereClause<T extends LiveObjectAny> = ({
|
|
|
212
210
|
$or?: WhereClause<T>[];
|
|
213
211
|
};
|
|
214
212
|
type IncludeClause<T extends LiveObjectAny> = {
|
|
215
|
-
[K in keyof T["relations"]]?: boolean
|
|
213
|
+
[K in keyof T["relations"]]?: boolean | IncludeClause<T["relations"][K]["entity"]>;
|
|
214
|
+
};
|
|
215
|
+
type GetFieldType<T> = T extends NullableLiveType<any> ? T["inner"] : T;
|
|
216
|
+
type HasDefaultValue<T> = T extends LiveAtomicType<any, undefined> ? false : true;
|
|
217
|
+
type InferInsert<T extends LiveObjectAny> = {
|
|
218
|
+
[K in keyof T["fields"] as HasDefaultValue<GetFieldType<T["fields"][K]>> extends true ? never : K]: InferLiveType<T["fields"][K]>;
|
|
219
|
+
} & {
|
|
220
|
+
[K in keyof T["fields"] as HasDefaultValue<GetFieldType<T["fields"][K]>> extends false ? never : K]?: InferLiveType<T["fields"][K]>;
|
|
216
221
|
};
|
|
222
|
+
type InferUpdate<T extends LiveObjectAny> = Omit<LiveObjectMutationInput<T>, "id">;
|
|
223
|
+
|
|
224
|
+
type Promisify<T> = T extends Promise<any> ? T : Promise<T>;
|
|
225
|
+
type ConditionalPromise<T, P extends boolean> = P extends true ? Promise<T> : T;
|
|
226
|
+
type Awaitable<T> = T | Promise<T>;
|
|
227
|
+
type Generatable<T, Arg = never> = T | ((arg: Arg) => T);
|
|
228
|
+
|
|
229
|
+
type Simplify<T> = T extends Record<string, unknown> ? {
|
|
230
|
+
[K in keyof T]: Simplify<T[K]>;
|
|
231
|
+
} : T extends Array<infer U> ? Array<Simplify<U>> : T;
|
|
232
|
+
declare const LogLevel: {
|
|
233
|
+
readonly CRITICAL: 0;
|
|
234
|
+
readonly ERROR: 1;
|
|
235
|
+
readonly WARN: 2;
|
|
236
|
+
readonly INFO: 3;
|
|
237
|
+
readonly DEBUG: 4;
|
|
238
|
+
};
|
|
239
|
+
type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];
|
|
240
|
+
|
|
241
|
+
declare const querySchema: z.ZodObject<{
|
|
242
|
+
resource: z.ZodString;
|
|
243
|
+
where: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
244
|
+
include: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
245
|
+
lastSyncedAt: z.ZodOptional<z.ZodString>;
|
|
246
|
+
limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
247
|
+
sort: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
248
|
+
key: z.ZodString;
|
|
249
|
+
direction: z.ZodEnum<{
|
|
250
|
+
asc: "asc";
|
|
251
|
+
desc: "desc";
|
|
252
|
+
}>;
|
|
253
|
+
}, z.core.$strip>>>;
|
|
254
|
+
}, z.core.$strip>;
|
|
255
|
+
type RawQueryRequest = z.infer<typeof querySchema>;
|
|
256
|
+
|
|
257
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
258
|
+
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
|
217
259
|
|
|
218
260
|
type RouteRecord = Record<string, AnyRoute>;
|
|
219
261
|
declare class Router<TRoutes extends RouteRecord> {
|
|
@@ -223,43 +265,49 @@ declare class Router<TRoutes extends RouteRecord> {
|
|
|
223
265
|
routes: TRoutes;
|
|
224
266
|
}): Router<TRoutes>;
|
|
225
267
|
}
|
|
226
|
-
type AnyRouter = Router<
|
|
227
|
-
type
|
|
228
|
-
|
|
229
|
-
db: Storage;
|
|
230
|
-
schema: TSchema;
|
|
231
|
-
}) => Promise<TResult>;
|
|
232
|
-
type Mutation<TInputValidator extends ZodTypeAny, // TODO use StandardSchema instead
|
|
233
|
-
THandler extends RequestHandler<z.infer<TInputValidator>, any, any>> = {
|
|
268
|
+
type AnyRouter = Router<any>;
|
|
269
|
+
type Mutation<TInputValidator extends z3.ZodTypeAny | z4.$ZodType, // TODO use StandardSchema instead
|
|
270
|
+
TOutput> = {
|
|
234
271
|
inputValidator: TInputValidator;
|
|
235
|
-
handler:
|
|
272
|
+
handler: (opts: {
|
|
273
|
+
req: MutationRequest<z.infer<TInputValidator>>;
|
|
274
|
+
db: Storage;
|
|
275
|
+
}) => TOutput;
|
|
236
276
|
};
|
|
237
|
-
declare const mutationCreator: <TInputValidator extends ZodTypeAny>(validator?: TInputValidator) => {
|
|
238
|
-
handler: <THandler extends
|
|
277
|
+
declare const mutationCreator: <TInputValidator extends z3.ZodTypeAny | z4.$ZodType>(validator?: TInputValidator) => {
|
|
278
|
+
handler: <THandler extends Mutation<TInputValidator, any>["handler"]>(handler: THandler) => Mutation<TInputValidator, ReturnType<THandler>>;
|
|
239
279
|
};
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
280
|
+
type ReadAuthorizationHandler<TShape extends LiveObjectAny> = (opts: {
|
|
281
|
+
ctx: BaseRequest["context"];
|
|
282
|
+
}) => WhereClause<TShape> | boolean;
|
|
283
|
+
type MutationAuthorizationHandler<TShape extends LiveObjectAny> = (opts: {
|
|
284
|
+
ctx: BaseRequest["context"];
|
|
285
|
+
value: Simplify<InferLiveObjectWithRelationalIds<TShape>>;
|
|
286
|
+
}) => WhereClause<TShape> | boolean;
|
|
287
|
+
type Authorization<TShape extends LiveObjectAny> = {
|
|
288
|
+
read?: ReadAuthorizationHandler<TShape>;
|
|
289
|
+
insert?: MutationAuthorizationHandler<TShape>;
|
|
290
|
+
update?: {
|
|
291
|
+
preMutation?: MutationAuthorizationHandler<TShape>;
|
|
292
|
+
postMutation?: MutationAuthorizationHandler<TShape>;
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, any>>> {
|
|
296
|
+
readonly resourceSchema: TResourceSchema;
|
|
243
297
|
readonly middlewares: Set<TMiddleware>;
|
|
244
298
|
readonly customMutations: TCustomMutations;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
private handleSet;
|
|
248
|
-
handleRequest(opts: {
|
|
249
|
-
req: ParsedRequest;
|
|
250
|
-
db: Storage;
|
|
251
|
-
schema: Schema<any>;
|
|
252
|
-
}): Promise<any>;
|
|
299
|
+
readonly authorization?: Authorization<TResourceSchema>;
|
|
300
|
+
constructor(resourceSchema: TResourceSchema, customMutations?: TCustomMutations, authorization?: Authorization<TResourceSchema>);
|
|
253
301
|
use(...middlewares: TMiddleware[]): this;
|
|
254
|
-
withMutations<T extends Record<string, Mutation<any,
|
|
302
|
+
withMutations<T extends Record<string, Mutation<any, any>>>(mutationFactory: (opts: {
|
|
255
303
|
mutation: typeof mutationCreator;
|
|
256
304
|
}) => T): Route<TResourceSchema, TMiddleware, T>;
|
|
305
|
+
private handleSet;
|
|
306
|
+
private wrapInMiddlewares;
|
|
257
307
|
}
|
|
258
308
|
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
259
309
|
|
|
260
|
-
|
|
261
|
-
[K in keyof T]: Simplify<T[K]>;
|
|
262
|
-
} : T;
|
|
310
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
263
311
|
|
|
264
312
|
declare abstract class Storage {
|
|
265
313
|
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
@@ -269,26 +317,37 @@ declare abstract class Storage {
|
|
|
269
317
|
where?: WhereClause<T>;
|
|
270
318
|
include?: IncludeClause<T>;
|
|
271
319
|
}): Promise<Record<string, InferLiveObject<T>>>;
|
|
272
|
-
insert<T extends LiveObjectAny>(resource: T, value: Simplify<
|
|
273
|
-
update<T extends LiveObjectAny>(resource: T, resourceId: string, value:
|
|
320
|
+
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
321
|
+
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<InferLiveObject<T>>;
|
|
322
|
+
abstract transaction<T>(fn: (opts: {
|
|
323
|
+
trx: Storage;
|
|
324
|
+
commit: () => Promise<void>;
|
|
325
|
+
rollback: () => Promise<void>;
|
|
326
|
+
}) => Promise<T>): Promise<T>;
|
|
274
327
|
}
|
|
275
328
|
|
|
276
|
-
|
|
329
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: any's are actually used correctly */
|
|
330
|
+
|
|
331
|
+
interface BaseRequest {
|
|
277
332
|
headers: Record<string, string>;
|
|
278
333
|
cookies: Record<string, string>;
|
|
279
|
-
|
|
280
|
-
resourceName: string;
|
|
281
|
-
procedure?: string;
|
|
334
|
+
queryParams: Record<string, string>;
|
|
282
335
|
context: Record<string, any>;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
type: "QUERY"
|
|
336
|
+
}
|
|
337
|
+
interface QueryRequest extends BaseRequest, RawQueryRequest {
|
|
338
|
+
type: "QUERY";
|
|
339
|
+
}
|
|
340
|
+
interface MutationRequest<TInput = any> extends BaseRequest {
|
|
341
|
+
type: "MUTATE";
|
|
342
|
+
input: TInput;
|
|
343
|
+
resource: string;
|
|
286
344
|
resourceId?: string;
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
type
|
|
345
|
+
procedure: string;
|
|
346
|
+
}
|
|
347
|
+
type Request = QueryRequest | MutationRequest;
|
|
348
|
+
type NextFunction<O, R = Request> = (req: R) => Awaitable<O>;
|
|
290
349
|
type Middleware<T = any> = (opts: {
|
|
291
|
-
req:
|
|
350
|
+
req: Request;
|
|
292
351
|
next: NextFunction<T>;
|
|
293
352
|
}) => ReturnType<NextFunction<T>>;
|
|
294
353
|
|
|
@@ -301,100 +360,37 @@ declare const SubscriptionProvider: ({ children, client, }: {
|
|
|
301
360
|
client: Client<AnyRouter>["client"];
|
|
302
361
|
}) => react_jsx_runtime.JSX.Element;
|
|
303
362
|
|
|
304
|
-
declare const serverMessageSchema: z.ZodUnion<[z.ZodObject<{
|
|
363
|
+
declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
305
364
|
id: z.ZodString;
|
|
306
365
|
type: z.ZodLiteral<"REJECT">;
|
|
307
366
|
resource: z.ZodString;
|
|
308
367
|
message: z.ZodOptional<z.ZodString>;
|
|
309
|
-
},
|
|
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<{
|
|
368
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
320
369
|
id: z.ZodString;
|
|
321
370
|
type: z.ZodLiteral<"REPLY">;
|
|
322
371
|
data: z.ZodAny;
|
|
323
|
-
},
|
|
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>;
|
|
372
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
333
373
|
type: z.ZodLiteral<"MUTATE">;
|
|
334
374
|
resource: z.ZodString;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
375
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
376
|
+
procedure: z.ZodEnum<{
|
|
377
|
+
INSERT: "INSERT";
|
|
378
|
+
UPDATE: "UPDATE";
|
|
379
|
+
}>;
|
|
380
|
+
payload: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
338
381
|
value: z.ZodNullable<z.ZodUnion<[z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>>;
|
|
339
382
|
_meta: z.ZodOptional<z.ZodObject<{
|
|
340
383
|
timestamp: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
341
|
-
},
|
|
342
|
-
|
|
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
|
-
}>, {
|
|
384
|
+
}, z.core.$strip>>;
|
|
385
|
+
}, z.core.$strip>>;
|
|
368
386
|
id: z.ZodString;
|
|
369
|
-
}
|
|
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
|
-
}>]>;
|
|
387
|
+
}, z.core.$strip>]>;
|
|
392
388
|
type ServerMessage = z.infer<typeof serverMessageSchema>;
|
|
393
389
|
|
|
394
390
|
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
395
391
|
|
|
396
392
|
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> {
|
|
393
|
+
declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false, TShouldAwait extends boolean = false> {
|
|
398
394
|
private _collection;
|
|
399
395
|
private _client;
|
|
400
396
|
private _where;
|
|
@@ -402,15 +398,16 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
|
|
|
402
398
|
private _limit?;
|
|
403
399
|
private _single?;
|
|
404
400
|
private _sort?;
|
|
401
|
+
private _shouldAwait?;
|
|
405
402
|
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>;
|
|
403
|
+
where(where: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
404
|
+
include<TNewInclude extends IncludeClause<TCollection>>(include: TNewInclude): QueryBuilder<TCollection, TInclude & TNewInclude, TSingle, TShouldAwait>;
|
|
405
|
+
get(): ConditionalPromise<InferQueryResult<TCollection, TInclude, TSingle>, TShouldAwait>;
|
|
409
406
|
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>;
|
|
407
|
+
limit(limit: number): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
408
|
+
one(id: string): QueryBuilder<TCollection, TInclude, true, TShouldAwait>;
|
|
409
|
+
first(where?: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, true, TShouldAwait>;
|
|
410
|
+
orderBy(key: keyof TCollection["fields"], direction?: "asc" | "desc"): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
414
411
|
toJSON(): {
|
|
415
412
|
resource: string;
|
|
416
413
|
where: WhereClause<TCollection>;
|
|
@@ -423,14 +420,14 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
|
|
|
423
420
|
};
|
|
424
421
|
}
|
|
425
422
|
|
|
426
|
-
type Client$1<TRouter extends AnyRouter> = {
|
|
423
|
+
type Client$1<TRouter extends AnyRouter, TShouldAwait extends boolean = false> = {
|
|
427
424
|
query: {
|
|
428
|
-
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["
|
|
425
|
+
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["resourceSchema"], {}, false, TShouldAwait>;
|
|
429
426
|
};
|
|
430
427
|
mutate: {
|
|
431
428
|
[K in keyof TRouter["routes"]]: {
|
|
432
|
-
insert: (input: Simplify<
|
|
433
|
-
update: (id: string, value:
|
|
429
|
+
insert: (input: Simplify<InferInsert<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
430
|
+
update: (id: string, value: Simplify<InferUpdate<TRouter["routes"][K]["resourceSchema"]>>) => ConditionalPromise<void, TShouldAwait>;
|
|
434
431
|
} & {
|
|
435
432
|
[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
433
|
};
|
|
@@ -476,6 +473,14 @@ declare class WebSocketClient {
|
|
|
476
473
|
private dispatchEvent;
|
|
477
474
|
}
|
|
478
475
|
|
|
476
|
+
interface WebSocketClientOptions extends ClientOptions {
|
|
477
|
+
connection?: {
|
|
478
|
+
autoConnect?: boolean;
|
|
479
|
+
autoReconnect?: boolean;
|
|
480
|
+
reconnectTimeout?: number;
|
|
481
|
+
maxReconnectAttempts?: number;
|
|
482
|
+
};
|
|
483
|
+
}
|
|
479
484
|
type ConnectionStateChangeEvent = {
|
|
480
485
|
type: "CONNECTION_STATE_CHANGE";
|
|
481
486
|
open: boolean;
|
|
@@ -493,7 +498,7 @@ type Client<TRouter extends AnyRouter> = {
|
|
|
493
498
|
};
|
|
494
499
|
store: Client$1<TRouter>;
|
|
495
500
|
};
|
|
496
|
-
declare const createClient: <TRouter extends AnyRouter>(opts:
|
|
501
|
+
declare const createClient: <TRouter extends AnyRouter>(opts: WebSocketClientOptions) => Client<TRouter>;
|
|
497
502
|
|
|
498
503
|
type ClientOptions = {
|
|
499
504
|
url: string;
|
|
@@ -502,6 +507,7 @@ type ClientOptions = {
|
|
|
502
507
|
storage: {
|
|
503
508
|
name: string;
|
|
504
509
|
} | false;
|
|
510
|
+
logLevel?: LogLevel;
|
|
505
511
|
};
|
|
506
512
|
|
|
507
|
-
export { type AnyRouter as A, type ClientOptions as C, type
|
|
513
|
+
export { type AnyRouter as A, type ClientOptions as C, type MessageReceivedEvent as M, SubscriptionProvider as S, type Client$1 as a, type ConnectionStateChangeEvent as b, type ClientEvents as c, type Client as d, createClient as e, useLiveQuery as u };
|