@live-state/sync 0.0.6-canary-6 → 0.0.6-canary-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +1 -1
- package/dist/fetch-client.js +1 -1
- package/dist/{index-D8jFoiy6.d.ts → index-H5NdEfdH.d.ts} +43 -35
- package/dist/server.cjs +2 -2
- package/dist/server.d.cts +15 -4
- package/dist/server.d.ts +15 -4
- package/dist/server.js +2 -2
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-H5NdEfdH.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import 'zod/v3';
|
package/dist/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {d,c,a,f,e,b}from'./chunk-RCXJM33Z.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 x=z.object({resource:z.string(),where:z.record(z.string(),z.any()).optional(),include:z.record(z.string(),z.any()).optional(),lastSyncedAt:z.string().optional(),limit:z.coerce.number().optional(),sort:z.array(z.object({key:z.string(),direction:z.enum(["asc","desc"])})).optional()}),k=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=k.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()}),A=U.extend({procedure:z.string(),payload:z.any().optional()}),W=U.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:X});z.union([W,A]);var S=z.string(),ee=x.extend({id:S,type:z.literal("SUBSCRIBE")}),te=x.extend({id:S,type:z.literal("QUERY")}),H=W.extend({id:S}),ie=A.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(),k)});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 P="__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),P].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(P,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(P,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(D=>D.type==="many"?[D.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 I=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 I(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};
|
|
1
|
+
import {d,c,a,f,e,b}from'./chunk-RCXJM33Z.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 n=(s==null?void 0:s.$eq)!==void 0?s==null?void 0:s.$eq:s;if(typeof s=="object"&&s!==null&&(s==null?void 0:s.$eq)===void 0){if(s.$in!==void 0){let r=l[i];return r===void 0?false:t?!s.$in.includes(r):s.$in.includes(r)}if(s.$not!==void 0&&!t)return m(l,{[i]:s.$not},true);if(s.$gt!==void 0){let r=l[i];return typeof r!="number"?false:t?r<=s.$gt:r>s.$gt}if(s.$gte!==void 0){let r=l[i];return typeof r!="number"?false:t?r<s.$gte:r>=s.$gte}if(s.$lt!==void 0){let r=l[i];return typeof r!="number"?false:t?r>=s.$lt:r<s.$lt}if(s.$lte!==void 0){let r=l[i];return typeof r!="number"?false:t?r>s.$lte:r<=s.$lte}let o=l[i];return !o||typeof o!="object"&&!Array.isArray(o)?false:Array.isArray(o)?t?!o.some(r=>m(r,s,false)):o.some(r=>m(r,s,false)):m(o,s,t)}return t?l[i]!==n:l[i]===n}),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 n;(n=this.subscriptions.get(t))==null||n.callbacks.add(i);let s=e.subscribe(()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.forEach(r=>{r();});});return ()=>{var o;(o=this.subscriptions.get(t))==null||o.callbacks.delete(i),setTimeout(()=>{var r;((r=this.subscriptions.get(t))==null?void 0:r.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 x=z.object({resource:z.string(),where:z.record(z.string(),z.any()).optional(),include:z.record(z.string(),z.any()).optional(),lastSyncedAt:z.string().optional(),limit:z.coerce.number().optional(),sort:z.array(z.object({key:z.string(),direction:z.enum(["asc","desc"])})).optional()}),k=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=k.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()}),A=U.extend({procedure:z.string(),payload:z.any().optional()}),W=U.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:X});z.union([W,A]);var S=z.string(),ee=x.extend({id:S,type:z.literal("SUBSCRIBE")}),te=x.extend({id:S,type:z.literal("QUERY")}),H=W.extend({id:S}),ie=A.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.array(k)});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(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 o=n.referencedBy.get(i.type);o&&(o instanceof Set?o.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(o=>{let r=this.nodes.get(o);!r||!r.references.get(i)||(r.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(n){(s=this.logger)==null||s.error(`Error in node subscription for node ${e}:`,n);}});}getAllNodes(){return Array.from(this.nodes.values())}};var P="__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,n=await g(e),o=Object.fromEntries(await Promise.all(Object.entries(e).map(async([c,d])=>[c,await g(d)]))),r=await openDB("live-state-databases",1,{upgrade(c){c.objectStoreNames.contains(O)||c.createObjectStore(O);}}),a=(h=await this.getAll(r,O))==null?void 0:h[t];(a==null?void 0:a.schemaHash)!==n&&s++,this.db=await openDB(t,s,{async upgrade(c){[...Object.keys(e),P].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 r.put(O,{schemaHash:n,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(P,e):new Promise(t=>t(void 0))}setMeta(e,t){var i;return (i=this.db)==null?void 0:i.put(P,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,o)=>[s[o],n]))}};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(n=>{!n||Object.keys(n).length===0||(this.optimisticMutationStack=n,s==null||s(this.optimisticMutationStack));}).then(()=>{Object.entries(this.schema).forEach(([n])=>{this.kvStorage.get(n).then(o=>{if(!o||Object.keys(o).length===0)return;let r=Object.values(o);this.loadConsolidatedState(n,r);});});}).catch(n=>{i.debug("Storage initialization failed (may not be available in this environment):",n);});});}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 r=this.querySnapshots[s];if(r)return r}let n=((o=e$1.where)!=null&&o.id?[e$1.where.id]:Object.keys(this.optimisticRawObjPool[e$1.resource]??{})).flatMap(r=>{let a=f(this.materializeOneWithInclude(r,e$1.include));return a?[a]:[]});if(e$1.sort&&e$1.sort.length>0){let r=(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};n.sort(r);}if(e$1.where||e$1.limit){let r=e$1.where?a=>m(a,e$1.where):()=>true;n=e(n,r,e$1.limit);}return i||(this.querySnapshots[s]=n),n}subscribe(e,t){var n;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}),(n=this.collectionSubscriptions.get(i))==null||n.callbacks.add(t),()=>{var o,r;(o=this.collectionSubscriptions.get(i))==null||o.callbacks.delete(t),((r=this.collectionSubscriptions.get(i))==null?void 0:r.callbacks.size)===0&&(this.collectionSubscriptions.delete(i),delete this.querySnapshots[i]);}}addMutation(e,t,i=false){var o,r,a;let s=this.schema[e];if(this.logger.debug("Adding mutation",t),!s)throw new Error("Schema not found");let n=(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=(r=this.optimisticMutationStack)==null?void 0:r[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,n);}undoMutation(e,t){var o,r;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 n=(r=this.optimisticRawObjPool[e])==null?void 0:r[s.resourceId];this.optimisticMutationStack[e].splice(i,1),this.kvStorage.setMeta("mutationStack",this.optimisticMutationStack),this.updateRawObjPool(e,s.resourceId,Object.fromEntries(Object.entries(s.payload).map(([a])=>[a,{value:null,_meta:{}}])),n);}loadConsolidatedState(e,t){t.forEach(i=>{var n;let s=(n=i.id)==null?void 0:n.value;s&&this.addMutation(e,{id:s,type:"MUTATE",resource:e,resourceId:s,procedure:"INSERT",payload:i});});}updateRawObjPool(e,t,i,s){var r;if(!this.schema[e])return;let n=(r=this.rawObjPool[e])==null?void 0:r[t],o=(this.optimisticMutationStack[e]??[]).reduce((a,p)=>p.resourceId!==t?a:this.schema[e].mergeMutation("set",p.payload,a)[0],n);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(D=>D.type==="many"?[D.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,n=(a=this.optimisticRawObjPool[s])==null?void 0:a[e];if(!n)return;let[o,r]=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:{...n.value,...Object.fromEntries(o.map(([p,h,c])=>[p,this.materializeOneWithInclude(i.references.get(h),typeof c=="object"&&c!==null?c:{})])),...Object.fromEntries(r.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],n=this.get(t.query,void 0,true);if(ae(n,s))return;this.querySnapshots[i]=n,t.callbacks.forEach(o=>{o(n);});}});}flattenIncludes(e,t){let i=[];return Object.entries(e).forEach(([s,n])=>{var a;let o=(a=this.schema[t])==null?void 0:a.relations[s];if(!o)return;let r=o.entity.name;i.push(r),typeof n=="object"&&n!==null&&i.push(...this.flattenIncludes(n,r));}),Array.from(new Set(i))}};var I=class{url;ws;store;logger;remoteSubCounters={};eventListeners=new Set;replyHandlers={};constructor(e){var t,i,s,n;this.url=e.url,this.logger=T({level:e.logLevel??y.INFO}),this.store=new L(e.schema,e.storage,this.logger,o=>{var r,a;(a=(r=Object.values(o))==null?void 0:r.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:(n=e.connection)==null?void 0:n.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(r=>{this.sendWsMessage({id:a(),type:"QUERY",resource:r});}),Object.entries(this.remoteSubCounters).forEach(([r,a$1])=>{a$1>0&&this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:r});}),Object.values(this.store.optimisticMutationStack).forEach(r=>{r&&r.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 n=K.parse(s);this.store.loadConsolidatedState(n.resource,n.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 n={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,n,true),this.sendWsMessage(n);}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,o)=>{this.replyHandlers[s.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[s.id],o(new Error("Reply timeout"));},5e3),handler:r=>{delete this.replyHandlers[s.id],n(r);}};})}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 I(l),t=T({level:l.logLevel??y.INFO,prefix:"Client"});return {client:{ws:e.ws,subscribe:i=>{let s=[];for(let n of i??Object.keys(e.store.schema))s.push(e.subscribeToRemote(n));return ()=>{t.debug("Removing listeners",s),s.forEach(n=>{n();});}},addEventListener:i=>e.addEventListener(i)},store:{query:Object.entries(l.schema).reduce((i,[s,n])=>(i[s]=c._init(n,e),i),{}),mutate:d(()=>{},{apply:(i,s,n)=>{if(s.length<2)return;if(s.length>2)throw new Error("Trying to access an invalid path");let[o,r]=s;if(r==="insert"){let{id:a,...p}=n[0];return e.mutate(o,a,"INSERT",p)}if(r==="update"){let[a,p]=n;return e.mutate(o,a,"UPDATE",p)}return e.genericMutate(o,r,n[0])}})}}};export{he as SubscriptionProvider,Qe as createClient,de as useLiveQuery};
|
package/dist/fetch-client.d.ts
CHANGED
package/dist/fetch-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {d,b,c,f}from'./chunk-RCXJM33Z.js';import {stringify}from'qs';var
|
|
1
|
+
import {d,b,c,f as f$1}from'./chunk-RCXJM33Z.js';import {stringify}from'qs';var f=async(e,c,r)=>{let n=o=>{if(!o)return {};if(o instanceof Headers){let y={};return o.forEach((d,b)=>{y[b]=d;}),y}return Array.isArray(o)?Object.fromEntries(o):o},s=n(r==null?void 0:r.headers),u=n(c==null?void 0:c.headers),a={...r,...c,headers:{...s,...u}},t=await fetch(e,a),i;try{i=await t.json();}catch{i=await t.text().catch(()=>{});}if(!t.ok)throw new Error(`Failed to fetch: ${t.status} ${t.statusText}`,{cause:i});return i},h=e=>{if(e===null)return "null";if(Array.isArray(e))return e.map(h);if(typeof e=="object"&&e!==null&&e.constructor===Object){let c={};for(let[r,n]of Object.entries(e))c[r]=h(n);return c}return e},C=e=>{let c$1={get:async r=>{let n=h(r),s=stringify(n),u=await b(e.credentials)??{},a=await f(`${e.url}/${r.resource}${s?`?${s}`:""}`,{headers:{...u,"Content-Type":"application/json"}},e.fetchOptions);return !a||typeof a!="object"?[]:Array.isArray(a)?a.map(t=>{var y,d;let i=f$1(t),o=((d=(y=t==null?void 0:t.value)==null?void 0:y.id)==null?void 0:d.value)??(t==null?void 0:t.id);return {...i,id:o}}):Object.entries(a).map(([t,i])=>({...f$1(i),id:t}))},subscribe:()=>{throw new Error("Fetch client does not support subscriptions")}};return {query:Object.entries(e.schema).reduce((r,[n,s])=>(r[n]=c._init(s,c$1,true),r),{}),mutate:d(()=>{},{apply:async(r,n,s)=>{if(n.length<2)return;if(n.length>2)throw new Error("Trying to access an invalid path");let[u,a]=n,t=await b(e.credentials)??{};if(a==="insert"){let{id:i,...o}=s[0];await f(`${e.url}/${u}/insert`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:i,payload:e.schema[u].encodeMutation("set",o,new Date().toISOString())})},e.fetchOptions);return}if(a==="update"){let[i,o]=s,{id:y,...d}=o;await f(`${e.url}/${u}/update`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({resourceId:i,payload:e.schema[u].encodeMutation("set",d,new Date().toISOString())})},e.fetchOptions);return}return await f(`${e.url}/${u}/${a}`,{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({payload:s[0]})},e.fetchOptions)}})}};export{C as createClient};
|
|
@@ -307,16 +307,57 @@ declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends M
|
|
|
307
307
|
}
|
|
308
308
|
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
309
309
|
|
|
310
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
311
|
+
|
|
312
|
+
interface DataSource {
|
|
313
|
+
get(query: RawQueryRequest): Awaitable<any[]>;
|
|
314
|
+
}
|
|
315
|
+
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>>[];
|
|
316
|
+
declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false, TShouldAwait extends boolean = false> {
|
|
317
|
+
private _collection;
|
|
318
|
+
private _client;
|
|
319
|
+
private _where;
|
|
320
|
+
private _include;
|
|
321
|
+
private _limit?;
|
|
322
|
+
private _single?;
|
|
323
|
+
private _sort?;
|
|
324
|
+
private _shouldAwait?;
|
|
325
|
+
private constructor();
|
|
326
|
+
where(where: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
327
|
+
include<TNewInclude extends IncludeClause<TCollection>>(include: TNewInclude): QueryBuilder<TCollection, TInclude & TNewInclude, TSingle, TShouldAwait>;
|
|
328
|
+
get(): ConditionalPromise<InferQueryResult<TCollection, TInclude, TSingle>, TShouldAwait>;
|
|
329
|
+
subscribe(callback: (value: InferQueryResult<TCollection, TInclude, TSingle>) => void): () => void;
|
|
330
|
+
limit(limit: number): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
331
|
+
one(id: string): QueryBuilder<TCollection, TInclude, true, TShouldAwait>;
|
|
332
|
+
first(where?: WhereClause<TCollection>): QueryBuilder<TCollection, TInclude, true, TShouldAwait>;
|
|
333
|
+
orderBy(key: keyof TCollection["fields"], direction?: "asc" | "desc"): QueryBuilder<TCollection, TInclude, TSingle, TShouldAwait>;
|
|
334
|
+
toJSON(): {
|
|
335
|
+
resource: string;
|
|
336
|
+
where: WhereClause<TCollection>;
|
|
337
|
+
include: TInclude;
|
|
338
|
+
limit: number | undefined;
|
|
339
|
+
sort: {
|
|
340
|
+
key: string;
|
|
341
|
+
direction: "asc" | "desc";
|
|
342
|
+
}[] | undefined;
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
310
346
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
311
347
|
|
|
312
|
-
declare abstract class Storage {
|
|
348
|
+
declare abstract class Storage implements DataSource {
|
|
313
349
|
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
314
350
|
include?: IncludeClause<T>;
|
|
315
351
|
}): Promise<InferLiveObject<T> | undefined>;
|
|
316
352
|
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
317
353
|
where?: WhereClause<T>;
|
|
318
354
|
include?: IncludeClause<T>;
|
|
319
|
-
|
|
355
|
+
limit?: number;
|
|
356
|
+
sort?: {
|
|
357
|
+
key: string;
|
|
358
|
+
direction: "asc" | "desc";
|
|
359
|
+
}[];
|
|
360
|
+
}): Promise<InferLiveObject<T>[]>;
|
|
320
361
|
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
321
362
|
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<InferLiveObject<T>>;
|
|
322
363
|
abstract transaction<T>(fn: (opts: {
|
|
@@ -387,39 +428,6 @@ declare const serverMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
387
428
|
}, z.core.$strip>]>;
|
|
388
429
|
type ServerMessage = z.infer<typeof serverMessageSchema>;
|
|
389
430
|
|
|
390
|
-
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
391
|
-
|
|
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>>[];
|
|
393
|
-
declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false, TShouldAwait extends boolean = false> {
|
|
394
|
-
private _collection;
|
|
395
|
-
private _client;
|
|
396
|
-
private _where;
|
|
397
|
-
private _include;
|
|
398
|
-
private _limit?;
|
|
399
|
-
private _single?;
|
|
400
|
-
private _sort?;
|
|
401
|
-
private _shouldAwait?;
|
|
402
|
-
private constructor();
|
|
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>;
|
|
406
|
-
subscribe(callback: (value: InferQueryResult<TCollection, TInclude, TSingle>) => void): () => void;
|
|
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>;
|
|
411
|
-
toJSON(): {
|
|
412
|
-
resource: string;
|
|
413
|
-
where: WhereClause<TCollection>;
|
|
414
|
-
include: TInclude;
|
|
415
|
-
limit: number | undefined;
|
|
416
|
-
sort: {
|
|
417
|
-
key: string;
|
|
418
|
-
direction: "asc" | "desc";
|
|
419
|
-
}[] | undefined;
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
|
|
423
431
|
type Client$1<TRouter extends AnyRouter, TShouldAwait extends boolean = false> = {
|
|
424
432
|
query: {
|
|
425
433
|
[K in keyof TRouter["routes"]]: QueryBuilder<TRouter["routes"][K]["resourceSchema"], {}, false, TShouldAwait>;
|
package/dist/server.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var Q=require('crypto'),jsXxhash=require('js-xxhash'),mt=require('qs'),zod=require('zod'),kysely=require('kysely'),postgres=require('kysely/helpers/postgres');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Q__default=/*#__PURE__*/_interopDefault(Q);var mt__default=/*#__PURE__*/_interopDefault(mt);var Ke=Object.create;var ge=Object.defineProperty;var Fe=Object.getOwnPropertyDescriptor;var qe=Object.getOwnPropertyNames;var Ue=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var Qe=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var Ge=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of qe(e))!Be.call(r,i)&&i!==t&&ge(r,i,{get:()=>e[i],enumerable:!(n=Fe(e,i))||n.enumerable});return r};var Re=(r,e,t)=>(t=r!=null?Ke(Ue(r)):{},Ge(ge(t,"default",{value:r,enumerable:true}),r));var oe=Qe(H=>{Object.defineProperty(H,"__esModule",{value:true});H.parse=ut;H.serialize=lt;var rt=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,it=/^[\u0021-\u003A\u003C-\u007E]*$/,at=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,ot=/^[\u0020-\u003A\u003D-\u007E]*$/,st=Object.prototype.toString,ct=(()=>{let r=function(){};return r.prototype=Object.create(null),r})();function ut(r,e){let t=new ct,n=r.length;if(n<2)return t;let i=(e==null?void 0:e.decode)||dt,a=0;do{let s=r.indexOf("=",a);if(s===-1)break;let o=r.indexOf(";",a),c=o===-1?n:o;if(s>c){a=r.lastIndexOf(";",s-1)+1;continue}let l=Me(r,a,s),p=Le(r,s,l),u=r.slice(l,p);if(t[u]===void 0){let h=Me(r,s+1,c),g=Le(r,c,h),d=i(r.slice(h,g));t[u]=d;}a=c+1;}while(a<n);return t}function Me(r,e,t){do{let n=r.charCodeAt(e);if(n!==32&&n!==9)return e}while(++e<t);return t}function Le(r,e,t){for(;e>t;){let n=r.charCodeAt(--e);if(n!==32&&n!==9)return e+1}return t}function lt(r,e,t){let n=(t==null?void 0:t.encode)||encodeURIComponent;if(!rt.test(r))throw new TypeError(`argument name is invalid: ${r}`);let i=n(e);if(!it.test(i))throw new TypeError(`argument val is invalid: ${e}`);let a=r+"="+i;if(!t)return a;if(t.maxAge!==void 0){if(!Number.isInteger(t.maxAge))throw new TypeError(`option maxAge is invalid: ${t.maxAge}`);a+="; Max-Age="+t.maxAge;}if(t.domain){if(!at.test(t.domain))throw new TypeError(`option domain is invalid: ${t.domain}`);a+="; Domain="+t.domain;}if(t.path){if(!ot.test(t.path))throw new TypeError(`option path is invalid: ${t.path}`);a+="; Path="+t.path;}if(t.expires){if(!yt(t.expires)||!Number.isFinite(t.expires.valueOf()))throw new TypeError(`option expires is invalid: ${t.expires}`);a+="; Expires="+t.expires.toUTCString();}if(t.httpOnly&&(a+="; HttpOnly"),t.secure&&(a+="; Secure"),t.partitioned&&(a+="; Partitioned"),t.priority)switch(typeof t.priority=="string"?t.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${t.priority}`)}if(t.sameSite)switch(typeof t.sameSite=="string"?t.sameSite.toLowerCase():t.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${t.sameSite}`)}return a}function dt(r){if(r.indexOf("%")===-1)return r;try{return decodeURIComponent(r)}catch{return r}}function yt(r){return st.call(r)==="[object Date]"}});var xe="0123456789ABCDEFGHJKMNPQRSTVWXYZ",W=32;var Ze=16,ve=10,be=0xffffffffffff;var C;(function(r){r.Base32IncorrectEncoding="B32_ENC_INVALID",r.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",r.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",r.EncodeTimeNegative="ENC_TIME_NEG",r.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",r.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",r.PRNGDetectFailure="PRNG_DETECT",r.ULIDInvalid="ULID_INVALID",r.Unexpected="UNEXPECTED",r.UUIDInvalid="UUID_INVALID";})(C||(C={}));var $=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name="ULIDError",this.code=e;}};function He(r){let e=Math.floor(r()*W);return e===W&&(e=W-1),xe.charAt(e)}function Je(r){var n;let e=Ye(),t=e&&(e.crypto||e.msCrypto)||(typeof Q__default.default<"u"?Q__default.default:null);if(typeof(t==null?void 0:t.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return t.getRandomValues(i),i[0]/255};if(typeof(t==null?void 0:t.randomBytes)=="function")return ()=>t.randomBytes(1).readUInt8()/255;if((n=Q__default.default)!=null&&n.randomBytes)return ()=>Q__default.default.randomBytes(1).readUInt8()/255;throw new $(C.PRNGDetectFailure,"Failed to find a reliable PRNG")}function Ye(){return tt()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Xe(r,e){let t="";for(;r>0;r--)t=He(e)+t;return t}function et(r,e=ve){if(isNaN(r))throw new $(C.EncodeTimeValueMalformed,`Time must be a number: ${r}`);if(r>be)throw new $(C.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${be}: ${r}`);if(r<0)throw new $(C.EncodeTimeNegative,`Time must be positive: ${r}`);if(Number.isInteger(r)===false)throw new $(C.EncodeTimeValueMalformed,`Time must be an integer: ${r}`);let t,n="";for(let i=e;i>0;i--)t=r%W,n=xe.charAt(t)+n,r=(r-t)/W;return n}function tt(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function Se(r,e){let t=Je(),n=Date.now();return et(n,ve)+Xe(Ze,t)}var G=()=>Se().toLowerCase();var z=(...r)=>{let e=r.filter(t=>!!t);return e.length===0?{}:e.length===1?e[0]:{$and:e}};var w=r=>r?Array.isArray(r.value)?r.value.map(t=>w(t)):typeof r.value!="object"||r.value===null||r.value instanceof Date?r.value:Object.fromEntries(Object.entries(r.value).map(([t,n])=>Array.isArray(n)?[t,n.map(i=>w(i))]:[t,w(n)])):void 0;var we=r=>jsXxhash.xxHash32(JSON.stringify(r)).toString(32),K=(r,e,t)=>{let n={},i=t[e];if(!i)return n;let a=s=>{s.$and?s.$and.forEach(a):s.$or?s.$or.forEach(a):Object.entries(s).forEach(([o,c])=>{var l;if((l=i.relations)!=null&&l[o]&&(n[o]=true,typeof c=="object"&&c!==null&&!Array.isArray(c))){let p=K(c,i.relations[o].entity.name,t);Object.keys(p).length>0&&(n[o]=p);}});};return a(r),n},O=(r,e,t=false)=>Object.entries(e).every(([n,i])=>{if(n==="$and")return i.every(s=>O(r,s,t));if(n==="$or")return i.some(s=>O(r,s,t));let a=(i==null?void 0:i.$eq)!==void 0?i==null?void 0:i.$eq:i;if(typeof i=="object"&&i!==null&&(i==null?void 0:i.$eq)===void 0){if(i.$in!==void 0){let o=r[n];return o===void 0?false:t?!i.$in.includes(o):i.$in.includes(o)}if(i.$not!==void 0&&!t)return O(r,{[n]:i.$not},true);if(i.$gt!==void 0){let o=r[n];return typeof o!="number"?false:t?o<=i.$gt:o>i.$gt}if(i.$gte!==void 0){let o=r[n];return typeof o!="number"?false:t?o<i.$gte:o>=i.$gte}if(i.$lt!==void 0){let o=r[n];return typeof o!="number"?false:t?o>=i.$lt:o<i.$lt}if(i.$lte!==void 0){let o=r[n];return typeof o!="number"?false:t?o>i.$lte:o<=i.$lte}let s=r[n];return !s||typeof s!="object"&&!Array.isArray(s)?false:Array.isArray(s)?t?!s.some(o=>O(o,i,false)):s.some(o=>O(o,i,false)):O(s,i,t)}return t?r[n]!==a:r[n]===a}),E={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},ae=class{level;prefix;constructor(e={}){this.level=e.level??E.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=E.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=E.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=E.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=E.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=E.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},Ie=r=>new ae(r);var Z=class{storage;queue=new Map;scheduled=false;constructor(e){this.storage=e;}async rawFind({resource:e,commonWhere:t,uniqueWhere:n,...i}){return new Promise((a,s)=>{let o=this.getBatchKey({resource:e,commonWhere:t,...i}),c={resource:e,commonWhere:t,uniqueWhere:n,...i,resolve:a,reject:s};this.queue.has(o)||this.queue.set(o,[]);let l=this.queue.get(o);l&&l.push(c),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(e){let{resource:t,commonWhere:n,...i}=e;return `${t}:${JSON.stringify(n??{})}:${JSON.stringify(i??{})}`}async processBatch(){this.scheduled=false;let e=Array.from(this.queue.entries());this.queue.clear();for(let[,t]of e)try{await this.executeBatchedRequests(t);}catch(n){t.forEach(i=>{i.reject(n);});}}async executeBatchedRequests(e){var h,g;if(e.length===0)return;let t=e[0],{resource:n,commonWhere:i,include:a,sort:s}=t,o=e.length===1?t.limit:void 0,c=e.map(d=>d.uniqueWhere).filter(d=>d!==void 0),l=i,p=(h=Object.entries(c[0]??{})[0])==null?void 0:h[0];if(c.length>0){let d=c.map(R=>R[p]).filter(R=>R!=null);d.length>0&&(l=z(i,{[p]:{$in:d}}));}let u=await this.storage.rawFind({resource:n,where:l,include:a,sort:s,limit:o});for(let d of e){let R={};if(d.uniqueWhere){let[f,y]=Object.entries(d.uniqueWhere)[0];for(let[m,T]of Object.entries(u))((g=T.value[f])==null?void 0:g.value)===y&&(R[m]=T);}else Object.assign(R,u);d.resolve(R);}}};var je=Re(oe());var F=zod.z.object({resource:zod.z.string(),where:zod.z.record(zod.z.string(),zod.z.any()).optional(),include:zod.z.record(zod.z.string(),zod.z.any()).optional(),lastSyncedAt:zod.z.string().optional(),limit:zod.z.coerce.number().optional(),sort:zod.z.array(zod.z.object({key:zod.z.string(),direction:zod.z.enum(["asc","desc"])})).optional()}),se=zod.z.record(zod.z.string(),zod.z.object({value:zod.z.string().or(zod.z.number()).or(zod.z.boolean()).or(zod.z.date()).nullable(),_meta:zod.z.object({timestamp:zod.z.string().optional().nullable()}).optional()})),pt=se.superRefine((r,e)=>{r.id&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Oe=zod.z.object({id:zod.z.string().optional(),type:zod.z.literal("MUTATE"),resource:zod.z.string(),resourceId:zod.z.string().optional()}),q=Oe.extend({procedure:zod.z.string(),payload:zod.z.any().optional()}),U=Oe.extend({procedure:zod.z.enum(["INSERT","UPDATE"]),payload:pt});zod.z.union([U,q]);var Ae=F.omit({resource:true}),ce=q.omit({id:true,type:true,resource:true,procedure:true}),ue=U.omit({id:true,type:true,resource:true,procedure:true});zod.z.union([ue,ce]);var le=r=>{if(r==null)return r;if(r==="null")return null;if(Array.isArray(r))return r.map(le);if(typeof r=="object"&&r.constructor===Object){let e={};for(let[t,n]of Object.entries(r))e[t]=le(n);return e}return r},Ee=r=>{let e=r.logger;return async t=>{var n;try{let i=typeof t.headers.getSetCookie=="function"?Object.fromEntries(t.headers):t.headers,a={headers:i,cookies:i.cookie?je.default.parse(i.cookie):{}},s=new URL(t.url),o=s.pathname.split("/"),c=s.searchParams,l=le(mt__default.default.parse(c.toString())),p=await((n=r.contextProvider)==null?void 0:n.call(r,{transport:"HTTP",headers:a.headers,cookies:a.cookies,queryParams:l}))??{};if(t.method==="GET"){let u=o[o.length-1],{success:h,data:g,error:d}=Ae.safeParse(l);if(!h)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:d},{status:400});let R=await r.handleQuery({req:{...a,...g,type:"QUERY",resource:u,context:p,queryParams:l}});return !R||!R.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(R.data)}if(t.method==="POST")try{let u=o[o.length-1],h=o[o.length-2],g=t.body?await t.json():{},d;if(u==="insert"||u==="update"){let{success:f,data:y,error:m}=ue.safeParse(g);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:m},{status:400});d=y;}else {let{success:f,data:y,error:m}=ce.safeParse(g);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:m},{status:400});d=y;}let R=await r.handleMutation({req:{...a,type:"MUTATE",resource:h,input:d.payload,context:p,resourceId:d.resourceId,procedure:u==="insert"||u==="update"?u.toUpperCase():u,queryParams:{}}});return Response.json(R)}catch(u){return e.error("Error parsing mutation from the client:",u),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(i){return e.error("Unexpected error:",i),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}}};var Pe=Re(oe());var V=zod.z.string(),ht=F.extend({id:V,type:zod.z.literal("SUBSCRIBE")}),Tt=F.extend({id:V,type:zod.z.literal("QUERY")}),Ce=U.extend({id:V}),gt=q.extend({id:V}),Rt=zod.z.union([gt,Ce]),$e=zod.z.union([ht,Tt,Rt]),bt=zod.z.object({id:V,type:zod.z.literal("REJECT"),resource:zod.z.string(),message:zod.z.string().optional()}),xt=zod.z.object({id:V,type:zod.z.literal("REPLY"),data:zod.z.any()});zod.z.union([bt,xt,Ce]);zod.z.object({resource:zod.z.string(),data:zod.z.record(zod.z.string(),se)});var ze=r=>{let e={},t=r.logger;return (n,i)=>{var u;let a=h=>{n.send(JSON.stringify(h));},s=G(),o=new Set,c={headers:i.headers,cookies:typeof i.headers.cookie=="string"?Pe.default.parse(i.headers.cookie):{}},l=mt.parse(i.url.split("?")[1]),p=(u=r.contextProvider)==null?void 0:u.call(r,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:l});e[s]=n,t.info("Client connected:",s),n.on("message",async h=>{var g;try{t.debug("Message received from the client:",h);let d=$e.parse(JSON.parse(h.toString()));if(d.type==="SUBSCRIBE"){let R=await p??{},f=d.resource,y=r.router.routes[f],m;if((g=y==null?void 0:y.authorization)!=null&&g.read){let T=y.authorization.read({ctx:R});m=typeof T=="object"?T:void 0;}o.add(r.subscribeToMutations(d,T=>{var x;!T.resourceId||!T.payload||!Object.keys(T.payload).length||(x=e[s])==null||x.send(JSON.stringify(T));},m));}else if(d.type==="QUERY"){let{resource:R}=d,f=await r.handleQuery({req:{...c,type:"QUERY",resource:R,context:await p??{},queryParams:l}});if(!f||!f.data)throw new Error("Invalid resource");a({id:d.id,type:"REPLY",data:{resource:R,data:Object.fromEntries(Object.entries(f.data??{}).map(([y,m])=>[y,m.value]))}});}else if(d.type==="MUTATE"){let{resource:R}=d;t.debug("Received mutation from client:",d);try{let f=await r.handleMutation({req:{...c,type:"MUTATE",resource:R,input:d.payload,context:{messageId:d.id,...await p??{}},resourceId:d.resourceId,procedure:d.procedure,queryParams:l}});d.procedure&&d.procedure!=="INSERT"&&d.procedure!=="UPDATE"&&a({id:d.id,type:"REPLY",data:f});}catch(f){a({id:d.id,type:"REJECT",resource:R,message:f.message}),t.error("Error parsing mutation from the client:",f);}}}catch(d){t.error("Error handling message from the client:",d);}}),n.on("close",()=>{t.info("Connection closed",s),delete e[s];for(let h of Array.from(o))h();});}};function Ne(r){let e=`${r.protocol}://${r.hostname}${r.url}`,t=new Headers;return Object.entries(r.headers).forEach(([n,i])=>{i&&t.set(n,Array.isArray(i)?i.join(","):i);}),new Request(e,{method:r.method,headers:t,body:r.body&&r.method!=="GET"?JSON.stringify(r.body):void 0})}var xn=(r,e,t)=>{r.ws(`${(t==null?void 0:t.basePath)??""}/ws`,ze(e)),r.use(`${(t==null?void 0:t.basePath)??""}/`,(n,i)=>{Ee(e)(Ne(n)).then(s=>s.json().then(o=>i.status(s.status).send(o)));});};var de=class r{routes;constructor(e){this.routes=e.routes;}static create(e){return new r(e)}},Ln=r=>de.create({...r}),wt=r=>({handler:e=>({inputValidator:r??zod.z.undefined(),handler:e})}),ye=class r{resourceSchema;middlewares;customMutations;authorization;constructor(e,t,n){this.resourceSchema=e,this.middlewares=new Set,this.customMutations=t??{},this.authorization=n;}use(...e){for(let t of e)this.middlewares.add(t);return this}withMutations(e){return new r(this.resourceSchema,e({mutation:wt}),this.authorization)}handleQuery=async({req:e,batcher:t})=>await this.wrapInMiddlewares(async n=>{var a,s;let i=(s=(a=this.authorization)==null?void 0:a.read)==null?void 0:s.call(a,{ctx:n.context});if(typeof i=="boolean"&&!i)throw new Error("Not authorized");return {data:await t.rawFind({resource:n.resource,commonWhere:z(n.where,typeof i=="object"?i:void 0),uniqueWhere:n.relationalWhere,include:n.include,limit:n.limit,sort:n.sort})}})(e);handleMutation=async({req:e,db:t,schema:n})=>await this.wrapInMiddlewares(async i=>{if(!i.procedure)throw new Error("Procedure is required for mutations");let a=this.customMutations[i.procedure];if(a){let s=a.inputValidator.parse(i.input);return i.input=s,a.handler({req:i,db:t})}else {if(i.procedure==="INSERT"||i.procedure==="UPDATE")return this.handleSet({req:i,db:t,operation:i.procedure,schema:n});throw new Error(`Unknown procedure: ${i.procedure}`)}})(e);handleSet=async({req:e,db:t,operation:n,schema:i})=>{if(!e.input)throw new Error("Payload is required");if(!e.resourceId)throw new Error("ResourceId is required");let a=await t.rawFindById(e.resource,e.resourceId);if(n==="INSERT"&&a)throw new Error("Resource already exists");if(n==="UPDATE"&&!a)throw new Error("Resource not found");return t.transaction(async({trx:s})=>{var p,u,h,g,d,R,f;let[o,c]=this.resourceSchema.mergeMutation("set",e.input,a);if(!c)throw new Error("Mutation rejected");if(n==="INSERT"){let y=await s.rawInsert(e.resource,e.resourceId,o,(p=e.context)==null?void 0:p.messageId),m=w(y);if(m.id=m.id??e.resourceId,(u=this.authorization)!=null&&u.insert){let T=this.authorization.insert({ctx:e.context,value:m});if(typeof T=="boolean"){if(!T)throw new Error("Not authorized")}else {let x=K(T,e.resource,i),v=Object.keys(x).length>0?await s.rawFindById(e.resource,e.resourceId,x):y,L=w(v);if(L.id=L.id??e.resourceId,!O(L,T))throw new Error("Not authorized")}}return {data:y,acceptedValues:c}}if((g=(h=this.authorization)==null?void 0:h.update)!=null&&g.preMutation){let y=w(a);y.id=y.id??e.resourceId;let m=this.authorization.update.preMutation({ctx:e.context,value:y});if(typeof m=="boolean"){if(!m)throw new Error("Not authorized")}else {let T=K(m,e.resource,i),x=Object.keys(T).length>0?await s.rawFindById(e.resource,e.resourceId,T):a,v=w(x);if(v.id=v.id??e.resourceId,!O(v,m))throw new Error("Not authorized")}}let l=await s.rawUpdate(e.resource,e.resourceId,o,(d=e.context)==null?void 0:d.messageId);if((f=(R=this.authorization)==null?void 0:R.update)!=null&&f.postMutation){let y=w(l);y.id=y.id??e.resourceId;let m=this.authorization.update.postMutation({ctx:e.context,value:y});if(typeof m=="boolean"){if(!m)throw new Error("Not authorized")}else {let T=K(m,e.resource,i),x=Object.keys(T).length>0?await s.rawFindById(e.resource,e.resourceId,T):l,v=w(x);if(v.id=v.id??e.resourceId,!O(v,m))throw new Error("Not authorized")}}return {data:l,acceptedValues:c}})};wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},pe=class r{middlewares;constructor(e=[]){this.middlewares=e;}collectionRoute(e,t){return new ye(e,void 0,t).use(...this.middlewares)}use(...e){return new r([...this.middlewares,...e])}static create(){return new r}},On=pe.create;var B=class{async insert(e,t){let n=new Date().toISOString();return w(await this.rawInsert(e.name,t.id,{value:Object.fromEntries(Object.entries(t).map(([i,a])=>[i,{value:a,_meta:{timestamp:n}}]))}))}async update(e,t,n){let i=new Date().toISOString(),{id:a,...s}=n;return w(await this.rawUpdate(e.name,t,{value:Object.fromEntries(Object.entries(s).map(([o,c])=>[o,{value:c,_meta:{timestamp:i}}]))}))}};function J(r,e,t,n){if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error("Resource not found");let a=n.$or,s=n.$and;return (a?t.or:t.and)(a?n.$or.map(o=>J(r,e,t,o)):s?n.$and.map(o=>J(r,e,t,o)):Object.entries(n).map(([o,c])=>{var l,p;if(i.fields[o])return (c==null?void 0:c.$eq)!==void 0?t(`${e}.${o}`,c.$eq===null?"is":"=",c.$eq):(c==null?void 0:c.$in)!==void 0?t(`${e}.${o}`,"in",c.$in):(c==null?void 0:c.$not)!==void 0?((l=c==null?void 0:c.$not)==null?void 0:l.$in)!==void 0?t(`${e}.${o}`,"not in",c.$not.$in):((p=c==null?void 0:c.$not)==null?void 0:p.$eq)!==void 0?t(`${e}.${o}`,c.$not.$eq===null?"is not":"!=",c.$not.$eq):t(`${e}.${o}`,c.$not===null?"is not":"!=",c.$not):(c==null?void 0:c.$gt)!==void 0?t(`${e}.${o}`,">",c.$gt):(c==null?void 0:c.$gte)!==void 0?t(`${e}.${o}`,">=",c.$gte):(c==null?void 0:c.$lt)!==void 0?t(`${e}.${o}`,"<",c.$lt):(c==null?void 0:c.$lte)!==void 0?t(`${e}.${o}`,"<=",c.$lte):t(`${e}.${o}`,c===null?"is":"=",c);if(i.relations[o]){let u=i.relations[o],h=u.entity.name;return u.type==="many"?t.exists(fe(r,h,t.selectFrom(h).select("id").whereRef(u.foreignColumn,"=",`${e}.id`),c)):J(r,h,t,c)}return null}).filter(Boolean))}function Y(r,e,t,n){let i=r[e];if(!i)throw new Error("Resource not found");if(!n)return t;if(n.$and){for(let a of n.$and)t=Y(r,e,t,a);return t}else if(n.$or){for(let a of n.$or)t=Y(r,e,t,a);return t}for(let[a,s]of Object.entries(n)){if(!i.relations[a])continue;let o=i.relations[a],c=o.entity.name,l=o.type==="one"?"id":o.foreignColumn,p=o.type==="one"?o.relationalColumn:"id";t=t.leftJoin(c,`${c}.${l}`,`${e}.${p}`),s instanceof Object&&!Array.isArray(s)&&s!==null&&(t=Y(r,c,t,s));}return t}function fe(r,e,t,n){return !n||Object.keys(n).length===0?t:(t=Y(r,e,t,n),t.where(i=>J(r,e,i,n)))}function X(r,e,t,n){if(!n)return t;if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error(`Resource not found: ${e}`);for(let a of Object.keys(n)){if(!i.relations[a])throw new Error(`Relation ${a} not found in resource ${e}`);let s=i.relations[a],o=s.entity.name,c=n[a],l=s.type==="one"?"id":s.foreignColumn,p=s.type==="one"?s.relationalColumn:"id",u=s.type==="one"?postgres.jsonObjectFrom:postgres.jsonArrayFrom,h=typeof c=="object"&&c!==null;t=t.select(g=>{let d=g.selectFrom(o).selectAll(o).whereRef(`${o}.${l}`,"=",`${e}.${p}`).select(R=>postgres.jsonObjectFrom(R.selectFrom(`${o}_meta`).selectAll(`${o}_meta`).whereRef(`${o}_meta.id`,"=",`${o}.id`)).as("_meta"));return h&&(d=X(r,o,d,c)),u(d).as(a)});}return t}var We="42701",me=class r extends B{db;schema;logger;server;mutationStack=[];constructor(e,t,n,i){super(),this.isKyselyLike(e)?this.db=e:this.db=new kysely.Kysely({dialect:new kysely.PostgresDialect({pool:e})}),this.schema=t,this.logger=n,this.server=i,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async init(e,t,n){var a;this.schema=e,this.logger=t,this.server=n;let i=await this.db.introspection.getTables();for(let[s,o]of Object.entries(e)){let c=i.find(u=>u.name===s);c||await this.db.schema.createTable(s).ifNotExists().execute();let l=`${s}_meta`,p=i.find(u=>u.name===l);p||await this.db.schema.createTable(l).ifNotExists().execute();for(let[u,h]of Object.entries(o.fields)){let g=c==null?void 0:c.columns.find(f=>f.name===u),d=h.getStorageFieldType();g?g.dataType!==d.type&&((a=this.logger)==null||a.warn("Column type mismatch:",u,"expected to have type:",d.type,"but has type:",g.dataType)):(await this.db.schema.alterTable(s).addColumn(u,d.type,f=>{let y=f;return d.unique&&(y=y.unique()),d.nullable||(y=y.notNull()),d.references&&(y=y.references(d.references)),d.primary&&(y=y.primaryKey()),d.default!==void 0&&(y=y.defaultTo(d.default)),y}).execute().catch(f=>{var y;if(f.code!==We)throw (y=this.logger)==null||y.error("Error adding column",u,f),f}),d.index&&await this.db.schema.createIndex(`${s}_${u}_index`).on(s).column(u).execute().catch(()=>{})),(p==null?void 0:p.columns.find(f=>f.name===u))||await this.db.schema.alterTable(l).addColumn(u,"varchar",f=>{let y=f;return d.primary&&(y=y.primaryKey().references(`${s}.${u}`)),y}).execute().catch(f=>{var y;if(f.code!==We)throw (y=this.logger)==null||y.error("Error adding meta column",u,f),f});}}}async rawFindById(e,t,n){if(!this.schema)throw new Error("Schema not initialized");let i=await this.db.selectFrom(e).where("id","=",t).selectAll(e).select(s=>postgres.jsonObjectFrom(s.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));i=X(this.schema,e,i,n);let a=await i.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(e,t,n){let i=await this.rawFindById(e.name,t,n==null?void 0:n.include);if(i)return w(i)}async rawFind(e){if(!this.schema)throw new Error("Schema not initialized");let{resource:t,where:n,include:i,limit:a,sort:s}=e,o=this.db.selectFrom(t).selectAll(t).select(u=>postgres.jsonObjectFrom(u.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));o=fe(this.schema,t,o,n),o=X(this.schema,t,o,i),a!==void 0&&(o=o.limit(a)),s!==void 0&&s.forEach(u=>{o=o.orderBy(u.key,u.direction);});let c=await o.execute(),l=Object.fromEntries(c.map(u=>{let{id:h}=u;return [h,u]}));return Object.keys(l).length===0?{}:Object.entries(l).reduce((u,[h,g])=>(u[h]=this.convertToMaterializedLiveType(g),u),{})}async find(e,t){let n=await this.rawFind({resource:e.name,where:t==null?void 0:t.where,include:t==null?void 0:t.include,limit:t==null?void 0:t.limit,sort:t==null?void 0:t.sort});return Object.fromEntries(Object.entries(n).map(([i,a])=>[i,w(a)]))}async rawInsert(e,t,n,i){var c;let a={},s={};for(let[l,p]of Object.entries(n.value)){let u=(c=p._meta)==null?void 0:c.timestamp;u&&(a[l]=p.value,s[l]=u);}await this.db.insertInto(e).values({...a,id:t}).execute().then(()=>{this.db.insertInto(`${e}_meta`).values({...s,id:t}).execute();});let o=this.buildMutation(e,t,"INSERT",n,i);return o&&this.trackMutation(o,n),n}async rawUpdate(e,t,n,i){var c;let a={},s={};for(let[l,p]of Object.entries(n.value)){let u=(c=p._meta)==null?void 0:c.timestamp;u&&(a[l]=p.value,s[l]=u);}await Promise.all([this.db.updateTable(e).set(a).where("id","=",t).execute(),this.db.insertInto(`${e}_meta`).values({...s,id:t}).onConflict(l=>l.column("id").doUpdateSet(s)).execute()]);let o=this.buildMutation(e,t,"UPDATE",n,i);return o&&this.trackMutation(o,n),n}async transaction(e){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let a=Math.random().toString(36).substring(2,15),s=this.mutationStack,o=[];this.mutationStack=o;let c=await this.db.savepoint(a).execute();try{return await e({trx:this,commit:async()=>{await c.releaseSavepoint(a).execute(),s.push(...o);},rollback:async()=>{await c.rollbackToSavepoint(a).execute(),o.length=0;}}).then(l=>c.isCommitted||c.isRolledBack?l:c.releaseSavepoint(a).execute().then(()=>(s.push(...o),l)))}catch(l){throw await c.rollbackToSavepoint(a).execute().catch(()=>{}),o.length=0,l}finally{this.mutationStack=s;}}let t=[],n=this.mutationStack;this.mutationStack=t;let i=await this.db.startTransaction().execute();try{let a=new r(i,this.schema,this.logger,this.server);return a.mutationStack=t,await e({trx:a,commit:async()=>{await i.commit().execute(),this.notifyMutations(t);},rollback:async()=>{await i.rollback().execute(),t.length=0;}}).then(s=>i.isCommitted||i.isRolledBack?s:i.commit().execute().then(()=>(this.notifyMutations(t),s)))}catch(a){throw await i.rollback().execute(),t.length=0,a}finally{this.mutationStack=n;}}get internalDB(){return this.db}convertToMaterializedLiveType(e){return {value:Object.entries(e).reduce((t,[n,i])=>{var a,s,o;return n==="_meta"||(n==="id"?t[n]={value:i}:Array.isArray(i)?t[n]={value:i.map(c=>this.convertToMaterializedLiveType(c)),_meta:{timestamp:(a=e==null?void 0:e._meta)==null?void 0:a[n]}}:typeof i=="object"&&i!==null&&!(i instanceof Date)?t[n]={...this.convertToMaterializedLiveType(i),_meta:{timestamp:(s=e==null?void 0:e._meta)==null?void 0:s[n]}}:t[n]={value:i,_meta:{timestamp:(o=e==null?void 0:e._meta)==null?void 0:o[n]}}),t},{})}}isKyselyLike(e){if(e instanceof kysely.Kysely)return true;if(!e||typeof e!="object")return false;let t=e,n=typeof t.selectFrom=="function",i=typeof t.startTransaction=="function",a=typeof t.savepoint=="function",s=typeof t.isTransaction=="boolean"||typeof t.isTransaction=="function";return n&&i||a&&s}buildMutation(e,t,n,i,a){var o;let s={};for(let[c,l]of Object.entries(i.value)){if(c==="id")continue;let p=(o=l._meta)==null?void 0:o.timestamp;p&&(s[c]={value:l.value,_meta:{timestamp:p}});}return Object.keys(s).length===0?null:{id:a??G(),type:"MUTATE",resource:e,resourceId:t,procedure:n,payload:s}}trackMutation(e,t){this.db.isTransaction?this.mutationStack.push({mutation:e,entityData:t}):this.notifyMutations([e],t);}notifyMutations(e,t){if(this.server)if(t!==void 0){let n=e;for(let i of n)this.server.notifySubscribers(i,t);}else {let n=e;for(let{mutation:i,entityData:a}of n)this.server.notifySubscribers(i,a);}}};var he=class r{router;storage;schema;middlewares=new Set;logger;contextProvider;mutationSubscriptions=new Set;collectionSubscriptions=new Map;constructor(e){var t;this.router=e.router,this.storage=e.storage,this.schema=e.schema,this.logger=Ie({level:e.logLevel??E.INFO}),(t=e.middlewares)==null||t.forEach(n=>{this.middlewares.add(n);}),this.storage.init(this.schema,this.logger,this),this.contextProvider=e.contextProvider;}static create(e){return new r(e)}handleQuery(e){let t=new Z(this.storage);return this.wrapInMiddlewares(async n=>{var g,d,R;let i=De(n,this.schema,{stepId:"query",collectionName:n.resource,included:Object.keys(n.include??{})}),a={headers:n.headers,cookies:n.cookies,queryParams:n.queryParams,context:n.context},s={};for(let f=0;f<i.length;f++){let y=i[f],m=this.router.routes[y.resource];if(!m)throw new Error("Invalid resource");let T;if(y.getWhere&&y.referenceGetter){let S=y.referenceGetter(s);T=[];for(let M=0;M<S.length;M++)T.push(y.getWhere(S[M]));}else T=[void 0];let x=s[y.prevStepId??""],v=[];if(x)for(let S=0;S<x.length;S++){let M=x[S],j=Object.keys(((g=M==null?void 0:M.result)==null?void 0:g.data)??{});for(let _=0;_<j.length;_++)v.push(j[_]);}let L=[];for(let S=0;S<T.length;S++){let M=T[S],j=v[S];L.push((async()=>{let _=await m.handleQuery({req:{type:"QUERY",...y,...a,where:y.where,relationalWhere:M},batcher:t});return {includedBy:j,result:_}})());}let A=await Promise.allSettled(L),k=[];for(let S=0;S<A.length;S++){let M=A[S];M.status==="fulfilled"&&k.push(M.value);}s[y.stepId]=k;}let o=new Map,c=0;for(let f in s){let y=s[f],m=i[c];c++;for(let T=0;T<y.length;T++){let x=y[T],v=x.result.data;for(let L in v){let A=v[L],k=`${f}.${L}`,S=[];f!=="query"&&x.includedBy&&(S=[`${m.prevStepId}.${x.includedBy}`]);let M=o.get(k);if(M)for(let j=0;j<S.length;j++)M.includedBy.add(S[j]);else o.set(k,{data:A,includedBy:new Set(S),path:f.split(".").slice(-1)[0],isMany:m.isMany??false,collectionName:m.collectionName,included:m.included});}}}let l=Object.fromEntries(o),p={data:{}},u=Object.keys(l);for(let f=u.length-1;f>=0;f--){let y=u[f],m=l[y],T=m.path;if(T==="query"&&(p.data[y.replace("query.","")]=m.data),m.included.length)for(let x=0;x<m.included.length;x++){let v=m.included[x];m.data.value[v]??=((R=(d=this.schema[m.collectionName])==null?void 0:d.relations[v])==null?void 0:R.type)==="many"?{value:[]}:{value:null};}if(m.includedBy.size>0){let x=Array.from(m.includedBy);for(let v=0;v<x.length;v++){let L=x[v],A=l[L];A&&(m.isMany?(A.data.value[T]??={value:[]},A.data.value[T].value.push(m.data)):A.data.value[T]=m.data);}}}return p})(e.req)}async handleMutation(e){let t=await this.wrapInMiddlewares(async n=>{let i=this.router.routes[n.resource];if(!i)throw new Error("Invalid resource");return i.handleMutation({req:n,db:this.storage,schema:this.schema})})(e.req);if(t&&e.req.type==="MUTATE"&&t.acceptedValues&&(e.req.procedure==="INSERT"||e.req.procedure==="UPDATE")&&e.req.resourceId){let i=t.acceptedValues??{},a=e.req,s=a.resourceId;Object.keys(i).length&&s&&this.mutationSubscriptions.forEach(o=>{o({id:e.req.context.messageId,type:"MUTATE",resource:a.resource,payload:i,resourceId:s,procedure:a.procedure});});}return t}use(e){return this.middlewares.add(e),this}context(e){return this.contextProvider=e,this}subscribeToMutations(e,t,n){let i=e.resource,a={query:e,authorizationWhere:n},s=we(a),o=this.collectionSubscriptions.get(i);o||(o=new Map,this.collectionSubscriptions.set(i,o));let c=o.get(s);return c?(c.callbacks.add(t),n!==void 0&&(c.authorizationWhere=n)):o.set(s,{callbacks:new Set([t]),...a}),()=>{var p,u;let l=this.collectionSubscriptions.get(i);l&&((p=l.get(s))==null||p.callbacks.delete(t),((u=l.get(s))==null?void 0:u.callbacks.size)===0&&l.delete(s));}}notifySubscribers(e,t){let n=e.resource,i=this.collectionSubscriptions.get(n);if(i&&t)for(let a of Array.from(i.values())){let s=Te(a.query.where,this.schema[n]),o=z(s,a.authorizationWhere),c=w(t);if(!c)continue;(e.resourceId&&typeof c=="object"&&c!==null&&!("id"in c)||e.resourceId&&typeof c=="object"&&c!==null&&c.id!==e.resourceId)&&(c.id=e.resourceId);let l=Object.keys(o).length>0,p=true;l&&(p=O(c,o)),p&&a.callbacks.forEach(u=>{var h;try{u(e);}catch(g){(h=this.logger)==null||h.error(`Error in mutation subscription for resource ${n}:`,g);}});}}wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},Gn=he.create;function De(r,e,t){let{include:n,where:i,...a}=r,{stepId:s}=t,o=[{...a,...t,where:i}];if(n&&typeof n=="object"&&Object.keys(n).length>0){let c=e[a.resource];if(!c)throw new Error(`Resource ${a.resource} not found`);o.push(...Object.entries(n).flatMap(([l,p])=>{let u=c.relations[l];if(!u)throw new Error(`Relation ${l} not found for resource ${a.resource}`);let h=u.entity.name;return De({...a,resource:h,include:p},e,{getWhere:u.type==="one"?g=>({id:g}):g=>({[u.foreignColumn]:g}),referenceGetter:g=>g[s].flatMap(d=>d.result.data?u.type==="one"?Object.values(d.result.data).map(R=>{var f,y;return (y=(f=R.value)==null?void 0:f[u.relationalColumn])==null?void 0:y.value}):Object.keys(d.result.data):[]),stepId:`${s}.${l}`,prevStepId:s,isMany:u.type==="many",collectionName:h,included:typeof p=="object"?Object.keys(p):[]})}));}return o}function Te(r,e){if(!r||!e||Object.keys(r).length===0)return r;if(r.$and){let n=r.$and.map(i=>Te(i,e)).filter(i=>!!i&&Object.keys(i).length>0);return n.length===0?void 0:n.length===1?n[0]:{$and:n}}if(r.$or){let n=r.$or.map(i=>Te(i,e)).filter(i=>!!i&&Object.keys(i).length>0);return n.length===0?void 0:n.length===1?n[0]:{$or:n}}let t={};for(let[n,i]of Object.entries(r))e.fields[n]&&(t[n]=i);return Object.keys(t).length>0?t:void 0}
|
|
2
|
-
exports.Route=
|
|
1
|
+
'use strict';var J=require('crypto'),jsXxhash=require('js-xxhash'),xt=require('qs'),zod=require('zod'),kysely=require('kysely'),postgres=require('kysely/helpers/postgres');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var J__default=/*#__PURE__*/_interopDefault(J);var xt__default=/*#__PURE__*/_interopDefault(xt);var Ge=Object.create;var we=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var He=Object.getOwnPropertyNames;var Je=Object.getPrototypeOf,Ye=Object.prototype.hasOwnProperty;var Xe=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var et=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of He(e))!Ye.call(r,i)&&i!==t&&we(r,i,{get:()=>e[i],enumerable:!(n=Ze(e,i))||n.enumerable});return r};var Ie=(r,e,t)=>(t=r!=null?Ge(Je(r)):{},et(we(t,"default",{value:r,enumerable:true}),r));var de=Xe(ee=>{Object.defineProperty(ee,"__esModule",{value:true});ee.parse=mt;ee.serialize=ht;var ut=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,lt=/^[\u0021-\u003A\u003C-\u007E]*$/,dt=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,yt=/^[\u0020-\u003A\u003D-\u007E]*$/,pt=Object.prototype.toString,ft=(()=>{let r=function(){};return r.prototype=Object.create(null),r})();function mt(r,e){let t=new ft,n=r.length;if(n<2)return t;let i=(e==null?void 0:e.decode)||Tt,a=0;do{let s=r.indexOf("=",a);if(s===-1)break;let o=r.indexOf(";",a),c=o===-1?n:o;if(s>c){a=r.lastIndexOf(";",s-1)+1;continue}let u=Ce(r,a,s),p=$e(r,s,u),l=r.slice(u,p);if(t[l]===void 0){let h=Ce(r,s+1,c),m=$e(r,c,h),d=i(r.slice(h,m));t[l]=d;}a=c+1;}while(a<n);return t}function Ce(r,e,t){do{let n=r.charCodeAt(e);if(n!==32&&n!==9)return e}while(++e<t);return t}function $e(r,e,t){for(;e>t;){let n=r.charCodeAt(--e);if(n!==32&&n!==9)return e+1}return t}function ht(r,e,t){let n=(t==null?void 0:t.encode)||encodeURIComponent;if(!ut.test(r))throw new TypeError(`argument name is invalid: ${r}`);let i=n(e);if(!lt.test(i))throw new TypeError(`argument val is invalid: ${e}`);let a=r+"="+i;if(!t)return a;if(t.maxAge!==void 0){if(!Number.isInteger(t.maxAge))throw new TypeError(`option maxAge is invalid: ${t.maxAge}`);a+="; Max-Age="+t.maxAge;}if(t.domain){if(!dt.test(t.domain))throw new TypeError(`option domain is invalid: ${t.domain}`);a+="; Domain="+t.domain;}if(t.path){if(!yt.test(t.path))throw new TypeError(`option path is invalid: ${t.path}`);a+="; Path="+t.path;}if(t.expires){if(!gt(t.expires)||!Number.isFinite(t.expires.valueOf()))throw new TypeError(`option expires is invalid: ${t.expires}`);a+="; Expires="+t.expires.toUTCString();}if(t.httpOnly&&(a+="; HttpOnly"),t.secure&&(a+="; Secure"),t.partitioned&&(a+="; Partitioned"),t.priority)switch(typeof t.priority=="string"?t.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${t.priority}`)}if(t.sameSite)switch(typeof t.sameSite=="string"?t.sameSite.toLowerCase():t.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${t.sameSite}`)}return a}function Tt(r){if(r.indexOf("%")===-1)return r;try{return decodeURIComponent(r)}catch{return r}}function gt(r){return pt.call(r)==="[object Date]"}});var Le="0123456789ABCDEFGHJKMNPQRSTVWXYZ",q=32;var tt=16,Ae=10,Me=0xffffffffffff;var V;(function(r){r.Base32IncorrectEncoding="B32_ENC_INVALID",r.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",r.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",r.EncodeTimeNegative="ENC_TIME_NEG",r.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",r.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",r.PRNGDetectFailure="PRNG_DETECT",r.ULIDInvalid="ULID_INVALID",r.Unexpected="UNEXPECTED",r.UUIDInvalid="UUID_INVALID";})(V||(V={}));var _=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name="ULIDError",this.code=e;}};function nt(r){let e=Math.floor(r()*q);return e===q&&(e=q-1),Le.charAt(e)}function rt(r){var n;let e=it(),t=e&&(e.crypto||e.msCrypto)||(typeof J__default.default<"u"?J__default.default:null);if(typeof(t==null?void 0:t.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return t.getRandomValues(i),i[0]/255};if(typeof(t==null?void 0:t.randomBytes)=="function")return ()=>t.randomBytes(1).readUInt8()/255;if((n=J__default.default)!=null&&n.randomBytes)return ()=>J__default.default.randomBytes(1).readUInt8()/255;throw new _(V.PRNGDetectFailure,"Failed to find a reliable PRNG")}function it(){return st()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function at(r,e){let t="";for(;r>0;r--)t=nt(e)+t;return t}function ot(r,e=Ae){if(isNaN(r))throw new _(V.EncodeTimeValueMalformed,`Time must be a number: ${r}`);if(r>Me)throw new _(V.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${Me}: ${r}`);if(r<0)throw new _(V.EncodeTimeNegative,`Time must be positive: ${r}`);if(Number.isInteger(r)===false)throw new _(V.EncodeTimeValueMalformed,`Time must be an integer: ${r}`);let t,n="";for(let i=e;i>0;i--)t=r%q,n=Le.charAt(t)+n,r=(r-t)/q;return n}function st(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function Oe(r,e){let t=rt(),n=Date.now();return ot(n,Ae)+at(tt,t)}var Y=()=>Oe().toLowerCase();var D=(...r)=>{let e=r.filter(t=>!!t);return e.length===0?{}:e.length===1?e[0]:{$and:e}};var I=r=>r?Array.isArray(r.value)?r.value.map(t=>I(t)):typeof r.value!="object"||r.value===null||r.value instanceof Date?r.value:Object.fromEntries(Object.entries(r.value).map(([t,n])=>Array.isArray(n)?[t,n.map(i=>I(i))]:[t,I(n)])):void 0;var je=r=>jsXxhash.xxHash32(JSON.stringify(r)).toString(32),B=(r,e,t)=>{let n={},i=t[e];if(!i)return n;let a=s=>{s.$and?s.$and.forEach(a):s.$or?s.$or.forEach(a):Object.entries(s).forEach(([o,c])=>{var u;if((u=i.relations)!=null&&u[o]&&(n[o]=true,typeof c=="object"&&c!==null&&!Array.isArray(c))){let p=B(c,i.relations[o].entity.name,t);Object.keys(p).length>0&&(n[o]=p);}});};return a(r),n},C=(r,e,t=false)=>Object.entries(e).every(([n,i])=>{if(n==="$and")return i.every(s=>C(r,s,t));if(n==="$or")return i.some(s=>C(r,s,t));let a=(i==null?void 0:i.$eq)!==void 0?i==null?void 0:i.$eq:i;if(typeof i=="object"&&i!==null&&(i==null?void 0:i.$eq)===void 0){if(i.$in!==void 0){let o=r[n];return o===void 0?false:t?!i.$in.includes(o):i.$in.includes(o)}if(i.$not!==void 0&&!t)return C(r,{[n]:i.$not},true);if(i.$gt!==void 0){let o=r[n];return typeof o!="number"?false:t?o<=i.$gt:o>i.$gt}if(i.$gte!==void 0){let o=r[n];return typeof o!="number"?false:t?o<i.$gte:o>=i.$gte}if(i.$lt!==void 0){let o=r[n];return typeof o!="number"?false:t?o>=i.$lt:o<i.$lt}if(i.$lte!==void 0){let o=r[n];return typeof o!="number"?false:t?o>i.$lte:o<=i.$lte}let s=r[n];return !s||typeof s!="object"&&!Array.isArray(s)?false:Array.isArray(s)?t?!s.some(o=>C(o,i,false)):s.some(o=>C(o,i,false)):C(s,i,t)}return t?r[n]!==a:r[n]===a}),z={CRITICAL:0,ERROR:1,WARN:2,INFO:3,DEBUG:4},le=class{level;prefix;constructor(e={}){this.level=e.level??z.INFO,this.prefix=e.prefix?`[${e.prefix}] `:"";}critical(...e){this.level>=z.CRITICAL&&console.error(`${this.prefix}[CRITICAL]`,...e);}error(...e){this.level>=z.ERROR&&console.error(`${this.prefix}[ERROR]`,...e);}warn(...e){this.level>=z.WARN&&console.warn(`${this.prefix}[WARN]`,...e);}info(...e){this.level>=z.INFO&&console.log(`${this.prefix}[INFO]`,...e);}debug(...e){this.level>=z.DEBUG&&console.log(`${this.prefix}[DEBUG]`,...e);}setLevel(e){this.level=e;}getLevel(){return this.level}},Ee=r=>new le(r);var X=class{storage;queue=new Map;scheduled=false;constructor(e){this.storage=e;}async rawFind({resource:e,commonWhere:t,uniqueWhere:n,...i}){return new Promise((a,s)=>{let o=this.getBatchKey({resource:e,commonWhere:t,...i}),c={resource:e,commonWhere:t,uniqueWhere:n,...i,resolve:a,reject:s};this.queue.has(o)||this.queue.set(o,[]);let u=this.queue.get(o);u&&u.push(c),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(e){let{resource:t,commonWhere:n,...i}=e;return `${t}:${JSON.stringify(n??{})}:${JSON.stringify(i??{})}`}async processBatch(){this.scheduled=false;let e=Array.from(this.queue.entries());this.queue.clear();for(let[,t]of e)try{await this.executeBatchedRequests(t);}catch(n){t.forEach(i=>{i.reject(n);});}}async executeBatchedRequests(e){var h;if(e.length===0)return;let t=e[0],{resource:n,commonWhere:i,include:a,sort:s}=t,o=e.length===1?t.limit:void 0,c=e.map(m=>m.uniqueWhere).filter(m=>m!==void 0),u=i,p=(h=Object.entries(c[0]??{})[0])==null?void 0:h[0];if(c.length>0){let m=c.map(d=>d[p]).filter(d=>d!=null);m.length>0&&(u=D(i,{[p]:{$in:m}}));}let l=await this.storage.get({resource:n,where:u,include:a,sort:s,limit:o});for(let m of e){let d=l;if(m.uniqueWhere){let[R,f]=Object.entries(m.uniqueWhere)[0];d=l.filter(y=>{var g;return ((g=y.value[R])==null?void 0:g.value)===f});}m.resolve(d);}}};var Ne=Ie(de());var Q=zod.z.object({resource:zod.z.string(),where:zod.z.record(zod.z.string(),zod.z.any()).optional(),include:zod.z.record(zod.z.string(),zod.z.any()).optional(),lastSyncedAt:zod.z.string().optional(),limit:zod.z.coerce.number().optional(),sort:zod.z.array(zod.z.object({key:zod.z.string(),direction:zod.z.enum(["asc","desc"])})).optional()}),ye=zod.z.record(zod.z.string(),zod.z.object({value:zod.z.string().or(zod.z.number()).or(zod.z.boolean()).or(zod.z.date()).nullable(),_meta:zod.z.object({timestamp:zod.z.string().optional().nullable()}).optional()})),Rt=ye.superRefine((r,e)=>{r.id&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Pe=zod.z.object({id:zod.z.string().optional(),type:zod.z.literal("MUTATE"),resource:zod.z.string(),resourceId:zod.z.string().optional()}),G=Pe.extend({procedure:zod.z.string(),payload:zod.z.any().optional()}),Z=Pe.extend({procedure:zod.z.enum(["INSERT","UPDATE"]),payload:Rt});zod.z.union([Z,G]);var ze=Q.omit({resource:true}),pe=G.omit({id:true,type:true,resource:true,procedure:true}),fe=Z.omit({id:true,type:true,resource:true,procedure:true});zod.z.union([fe,pe]);var me=r=>{if(r==null)return r;if(r==="null")return null;if(Array.isArray(r))return r.map(me);if(typeof r=="object"&&r.constructor===Object){let e={};for(let[t,n]of Object.entries(r))e[t]=me(n);return e}return r},Ve=r=>{let e=r.logger;return async t=>{var n;try{let i=typeof t.headers.getSetCookie=="function"?Object.fromEntries(t.headers):t.headers,a={headers:i,cookies:i.cookie?Ne.default.parse(i.cookie):{}},s=new URL(t.url),o=s.pathname.split("/"),c=s.searchParams,u=me(xt__default.default.parse(c.toString())),p=await((n=r.contextProvider)==null?void 0:n.call(r,{transport:"HTTP",headers:a.headers,cookies:a.cookies,queryParams:u}))??{};if(t.method==="GET"){let l=o[o.length-1],{success:h,data:m,error:d}=ze.safeParse(u);if(!h)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:d},{status:400});let R=await r.handleQuery({req:{...a,...m,type:"QUERY",resource:l,context:p,queryParams:u}});return !R||!R.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(R.data)}if(t.method==="POST")try{let l=o[o.length-1],h=o[o.length-2],m=t.body?await t.json():{},d;if(l==="insert"||l==="update"){let{success:f,data:y,error:g}=fe.safeParse(m);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:g},{status:400});d=y;}else {let{success:f,data:y,error:g}=pe.safeParse(m);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:g},{status:400});d=y;}let R=await r.handleMutation({req:{...a,type:"MUTATE",resource:h,input:d.payload,context:p,resourceId:d.resourceId,procedure:l==="insert"||l==="update"?l.toUpperCase():l,queryParams:{}}});return Response.json(R)}catch(l){return e.error("Error parsing mutation from the client:",l),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(i){return e.error("Unexpected error:",i),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}}};var De=Ie(de());var K=zod.z.string(),vt=Q.extend({id:K,type:zod.z.literal("SUBSCRIBE")}),St=Q.extend({id:K,type:zod.z.literal("QUERY")}),_e=Z.extend({id:K}),wt=G.extend({id:K}),It=zod.z.union([wt,_e]),We=zod.z.union([vt,St,It]),Mt=zod.z.object({id:K,type:zod.z.literal("REJECT"),resource:zod.z.string(),message:zod.z.string().optional()}),Lt=zod.z.object({id:K,type:zod.z.literal("REPLY"),data:zod.z.any()});zod.z.union([Mt,Lt,_e]);zod.z.object({resource:zod.z.string(),data:zod.z.array(ye)});var ke=r=>{let e={},t=r.logger;return (n,i)=>{var l;let a=h=>{n.send(JSON.stringify(h));},s=Y(),o=new Set,c={headers:i.headers,cookies:typeof i.headers.cookie=="string"?De.default.parse(i.headers.cookie):{}},u=xt.parse(i.url.split("?")[1]),p=(l=r.contextProvider)==null?void 0:l.call(r,{transport:"WEBSOCKET",headers:c.headers,cookies:c.cookies,queryParams:u});e[s]=n,t.info("Client connected:",s),n.on("message",async h=>{var m;try{t.debug("Message received from the client:",h);let d=We.parse(JSON.parse(h.toString()));if(d.type==="SUBSCRIBE"){let R=await p??{},f=d.resource,y=r.router.routes[f],g;if((m=y==null?void 0:y.authorization)!=null&&m.read){let S=y.authorization.read({ctx:R});g=typeof S=="object"?S:void 0;}o.add(r.subscribeToMutations(d,S=>{var v;!S.resourceId||!S.payload||!Object.keys(S.payload).length||(v=e[s])==null||v.send(JSON.stringify(S));},g));}else if(d.type==="QUERY"){let{resource:R}=d,f=await r.handleQuery({req:{...c,type:"QUERY",resource:R,context:await p??{},queryParams:u}});if(!f||!f.data)throw new Error("Invalid resource");a({id:d.id,type:"REPLY",data:{resource:R,data:(f.data??[]).map(y=>y.value)}});}else if(d.type==="MUTATE"){let{resource:R}=d;t.debug("Received mutation from client:",d);try{let f=await r.handleMutation({req:{...c,type:"MUTATE",resource:R,input:d.payload,context:{messageId:d.id,...await p??{}},resourceId:d.resourceId,procedure:d.procedure,queryParams:u}});d.procedure&&d.procedure!=="INSERT"&&d.procedure!=="UPDATE"&&a({id:d.id,type:"REPLY",data:f});}catch(f){a({id:d.id,type:"REJECT",resource:R,message:f.message}),t.error("Error parsing mutation from the client:",f);}}}catch(d){t.error("Error handling message from the client:",d);}}),n.on("close",()=>{t.info("Connection closed",s),delete e[s];for(let h of Array.from(o))h();});}};function Ke(r){let e=`${r.protocol}://${r.hostname}${r.url}`,t=new Headers;return Object.entries(r.headers).forEach(([n,i])=>{i&&t.set(n,Array.isArray(i)?i.join(","):i);}),new Request(e,{method:r.method,headers:t,body:r.body&&r.method!=="GET"?JSON.stringify(r.body):void 0})}var Ln=(r,e,t)=>{r.ws(`${(t==null?void 0:t.basePath)??""}/ws`,ke(e)),r.use(`${(t==null?void 0:t.basePath)??""}/`,(n,i)=>{Ve(e)(Ke(n)).then(s=>s.json().then(o=>i.status(s.status).send(o)));});};var he=class r{routes;constructor(e){this.routes=e.routes;}static create(e){return new r(e)}},$n=r=>he.create({...r}),jt=r=>({handler:e=>({inputValidator:r??zod.z.undefined(),handler:e})}),Te=class r{resourceSchema;middlewares;customMutations;authorization;constructor(e,t,n){this.resourceSchema=e,this.middlewares=new Set,this.customMutations=t??{},this.authorization=n;}use(...e){for(let t of e)this.middlewares.add(t);return this}withMutations(e){return new r(this.resourceSchema,e({mutation:jt}),this.authorization)}handleQuery=async({req:e,batcher:t})=>await this.wrapInMiddlewares(async n=>{var a,s;let i=(s=(a=this.authorization)==null?void 0:a.read)==null?void 0:s.call(a,{ctx:n.context});if(typeof i=="boolean"&&!i)throw new Error("Not authorized");return {data:await t.rawFind({resource:n.resource,commonWhere:D(n.where,typeof i=="object"?i:void 0),uniqueWhere:n.relationalWhere,include:n.include,limit:n.limit,sort:n.sort})}})(e);handleMutation=async({req:e,db:t,schema:n})=>await this.wrapInMiddlewares(async i=>{if(!i.procedure)throw new Error("Procedure is required for mutations");let a=this.customMutations[i.procedure];if(a){let s=a.inputValidator.parse(i.input);return i.input=s,a.handler({req:i,db:t})}else {if(i.procedure==="INSERT"||i.procedure==="UPDATE")return this.handleSet({req:i,db:t,operation:i.procedure,schema:n});throw new Error(`Unknown procedure: ${i.procedure}`)}})(e);handleSet=async({req:e,db:t,operation:n,schema:i})=>{if(!e.input)throw new Error("Payload is required");if(!e.resourceId)throw new Error("ResourceId is required");let a=await t.rawFindById(e.resource,e.resourceId);if(n==="INSERT"&&a)throw new Error("Resource already exists");if(n==="UPDATE"&&!a)throw new Error("Resource not found");return t.transaction(async({trx:s})=>{var p,l,h,m,d,R,f;let[o,c]=this.resourceSchema.mergeMutation("set",e.input,a);if(!c)throw new Error("Mutation rejected");if(n==="INSERT"){let y=await s.rawInsert(e.resource,e.resourceId,o,(p=e.context)==null?void 0:p.messageId),g=I(y);if(g.id=g.id??e.resourceId,(l=this.authorization)!=null&&l.insert){let S=this.authorization.insert({ctx:e.context,value:g});if(typeof S=="boolean"){if(!S)throw new Error("Not authorized")}else {let v=B(S,e.resource,i),x=Object.keys(v).length>0?await s.rawFindById(e.resource,e.resourceId,v):y,b=I(x);if(b.id=b.id??e.resourceId,!C(b,S))throw new Error("Not authorized")}}return {data:y,acceptedValues:c}}if((m=(h=this.authorization)==null?void 0:h.update)!=null&&m.preMutation){let y=I(a);y.id=y.id??e.resourceId;let g=this.authorization.update.preMutation({ctx:e.context,value:y});if(typeof g=="boolean"){if(!g)throw new Error("Not authorized")}else {let S=B(g,e.resource,i),v=Object.keys(S).length>0?await s.rawFindById(e.resource,e.resourceId,S):a,x=I(v);if(x.id=x.id??e.resourceId,!C(x,g))throw new Error("Not authorized")}}let u=await s.rawUpdate(e.resource,e.resourceId,o,(d=e.context)==null?void 0:d.messageId);if((f=(R=this.authorization)==null?void 0:R.update)!=null&&f.postMutation){let y=I(u);y.id=y.id??e.resourceId;let g=this.authorization.update.postMutation({ctx:e.context,value:y});if(typeof g=="boolean"){if(!g)throw new Error("Not authorized")}else {let S=B(g,e.resource,i),v=Object.keys(S).length>0?await s.rawFindById(e.resource,e.resourceId,S):u,x=I(v);if(x.id=x.id??e.resourceId,!C(x,g))throw new Error("Not authorized")}}return {data:u,acceptedValues:c}})};wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},ge=class r{middlewares;constructor(e=[]){this.middlewares=e;}collectionRoute(e,t){return new Te(e,void 0,t).use(...this.middlewares)}use(...e){return new r([...this.middlewares,...e])}static create(){return new r}},Pn=ge.create;var H=class{async insert(e,t){let n=new Date().toISOString();return I(await this.rawInsert(e.name,t.id,{value:Object.fromEntries(Object.entries(t).map(([i,a])=>[i,{value:a,_meta:{timestamp:n}}]))}))}async update(e,t,n){let i=new Date().toISOString(),{id:a,...s}=n;return I(await this.rawUpdate(e.name,t,{value:Object.fromEntries(Object.entries(s).map(([o,c])=>[o,{value:c,_meta:{timestamp:i}}]))}))}};function te(r,e,t,n){if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error("Resource not found");let a=n.$or,s=n.$and;return (a?t.or:t.and)(a?n.$or.map(o=>te(r,e,t,o)):s?n.$and.map(o=>te(r,e,t,o)):Object.entries(n).map(([o,c])=>{var u,p;if(i.fields[o])return (c==null?void 0:c.$eq)!==void 0?t(`${e}.${o}`,c.$eq===null?"is":"=",c.$eq):(c==null?void 0:c.$in)!==void 0?t(`${e}.${o}`,"in",c.$in):(c==null?void 0:c.$not)!==void 0?((u=c==null?void 0:c.$not)==null?void 0:u.$in)!==void 0?t(`${e}.${o}`,"not in",c.$not.$in):((p=c==null?void 0:c.$not)==null?void 0:p.$eq)!==void 0?t(`${e}.${o}`,c.$not.$eq===null?"is not":"!=",c.$not.$eq):t(`${e}.${o}`,c.$not===null?"is not":"!=",c.$not):(c==null?void 0:c.$gt)!==void 0?t(`${e}.${o}`,">",c.$gt):(c==null?void 0:c.$gte)!==void 0?t(`${e}.${o}`,">=",c.$gte):(c==null?void 0:c.$lt)!==void 0?t(`${e}.${o}`,"<",c.$lt):(c==null?void 0:c.$lte)!==void 0?t(`${e}.${o}`,"<=",c.$lte):t(`${e}.${o}`,c===null?"is":"=",c);if(i.relations[o]){let l=i.relations[o],h=l.entity.name;return l.type==="many"?t.exists(Re(r,h,t.selectFrom(h).select("id").whereRef(l.foreignColumn,"=",`${e}.id`),c)):te(r,h,t,c)}return null}).filter(Boolean))}function ne(r,e,t,n){let i=r[e];if(!i)throw new Error("Resource not found");if(!n)return t;if(n.$and){for(let a of n.$and)t=ne(r,e,t,a);return t}else if(n.$or){for(let a of n.$or)t=ne(r,e,t,a);return t}for(let[a,s]of Object.entries(n)){if(!i.relations[a])continue;let o=i.relations[a],c=o.entity.name,u=o.type==="one"?"id":o.foreignColumn,p=o.type==="one"?o.relationalColumn:"id";t=t.leftJoin(c,`${c}.${u}`,`${e}.${p}`),s instanceof Object&&!Array.isArray(s)&&s!==null&&(t=ne(r,c,t,s));}return t}function Re(r,e,t,n){return !n||Object.keys(n).length===0?t:(t=ne(r,e,t,n),t.where(i=>te(r,e,i,n)))}function re(r,e,t,n){if(!n)return t;if(!r)throw new Error("Schema not initialized");let i=r[e];if(!i)throw new Error(`Resource not found: ${e}`);for(let a of Object.keys(n)){if(!i.relations[a])throw new Error(`Relation ${a} not found in resource ${e}`);let s=i.relations[a],o=s.entity.name,c=n[a],u=s.type==="one"?"id":s.foreignColumn,p=s.type==="one"?s.relationalColumn:"id",l=s.type==="one"?postgres.jsonObjectFrom:postgres.jsonArrayFrom,h=typeof c=="object"&&c!==null;t=t.select(m=>{let d=m.selectFrom(o).selectAll(o).whereRef(`${o}.${u}`,"=",`${e}.${p}`).select(R=>postgres.jsonObjectFrom(R.selectFrom(`${o}_meta`).selectAll(`${o}_meta`).whereRef(`${o}_meta.id`,"=",`${o}.id`)).as("_meta"));return h&&(d=re(r,o,d,c)),l(d).as(a)});}return t}var Be="42701",be=class r extends H{db;schema;logger;server;mutationStack=[];constructor(e,t,n,i){super(),this.isKyselyLike(e)?this.db=e:this.db=new kysely.Kysely({dialect:new kysely.PostgresDialect({pool:e})}),this.schema=t,this.logger=n,this.server=i,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async init(e,t,n){var a;this.schema=e,this.logger=t,this.server=n;let i=await this.db.introspection.getTables();for(let[s,o]of Object.entries(e)){let c=i.find(l=>l.name===s);c||await this.db.schema.createTable(s).ifNotExists().execute();let u=`${s}_meta`,p=i.find(l=>l.name===u);p||await this.db.schema.createTable(u).ifNotExists().execute();for(let[l,h]of Object.entries(o.fields)){let m=c==null?void 0:c.columns.find(f=>f.name===l),d=h.getStorageFieldType();m?m.dataType!==d.type&&((a=this.logger)==null||a.warn("Column type mismatch:",l,"expected to have type:",d.type,"but has type:",m.dataType)):(await this.db.schema.alterTable(s).addColumn(l,d.type,f=>{let y=f;return d.unique&&(y=y.unique()),d.nullable||(y=y.notNull()),d.references&&(y=y.references(d.references)),d.primary&&(y=y.primaryKey()),d.default!==void 0&&(y=y.defaultTo(d.default)),y}).execute().catch(f=>{var y;if(f.code!==Be)throw (y=this.logger)==null||y.error("Error adding column",l,f),f}),d.index&&await this.db.schema.createIndex(`${s}_${l}_index`).on(s).column(l).execute().catch(()=>{})),(p==null?void 0:p.columns.find(f=>f.name===l))||await this.db.schema.alterTable(u).addColumn(l,"varchar",f=>{let y=f;return d.primary&&(y=y.primaryKey().references(`${s}.${l}`)),y}).execute().catch(f=>{var y;if(f.code!==Be)throw (y=this.logger)==null||y.error("Error adding meta column",l,f),f});}}}async rawFindById(e,t,n){if(!this.schema)throw new Error("Schema not initialized");let i=await this.db.selectFrom(e).where("id","=",t).selectAll(e).select(s=>postgres.jsonObjectFrom(s.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));i=re(this.schema,e,i,n);let a=await i.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(e,t,n){let i=await this.rawFindById(e.name,t,n==null?void 0:n.include);if(i)return I(i)}async get(e){if(!this.schema)throw new Error("Schema not initialized");let{resource:t,where:n,include:i,limit:a,sort:s}=e,o=this.db.selectFrom(t).selectAll(t).select(u=>postgres.jsonObjectFrom(u.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));o=Re(this.schema,t,o,n),o=re(this.schema,t,o,i),a!==void 0&&(o=o.limit(a)),s!==void 0&&s.forEach(u=>{o=o.orderBy(u.key,u.direction);});let c=await o.execute();return c.length===0?[]:c.map(u=>this.convertToMaterializedLiveType(u))}async find(e,t){return (await this.get({resource:e.name,where:t==null?void 0:t.where,include:t==null?void 0:t.include,limit:t==null?void 0:t.limit,sort:t==null?void 0:t.sort})).map(i=>I(i))}async rawInsert(e,t,n,i){var c;let a={},s={};for(let[u,p]of Object.entries(n.value)){let l=(c=p._meta)==null?void 0:c.timestamp;l&&(a[u]=p.value,s[u]=l);}await this.db.insertInto(e).values({...a,id:t}).execute().then(()=>{this.db.insertInto(`${e}_meta`).values({...s,id:t}).execute();});let o=this.buildMutation(e,t,"INSERT",n,i);return o&&this.trackMutation(o,n),n}async rawUpdate(e,t,n,i){var c;let a={},s={};for(let[u,p]of Object.entries(n.value)){let l=(c=p._meta)==null?void 0:c.timestamp;l&&(a[u]=p.value,s[u]=l);}await Promise.all([this.db.updateTable(e).set(a).where("id","=",t).execute(),this.db.insertInto(`${e}_meta`).values({...s,id:t}).onConflict(u=>u.column("id").doUpdateSet(s)).execute()]);let o=this.buildMutation(e,t,"UPDATE",n,i);return o&&this.trackMutation(o,n),n}async transaction(e){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let a=Math.random().toString(36).substring(2,15),s=this.mutationStack,o=[];this.mutationStack=o;let c=await this.db.savepoint(a).execute();try{return await e({trx:this,commit:async()=>{await c.releaseSavepoint(a).execute(),s.push(...o);},rollback:async()=>{await c.rollbackToSavepoint(a).execute(),o.length=0;}}).then(u=>c.isCommitted||c.isRolledBack?u:c.releaseSavepoint(a).execute().then(()=>(s.push(...o),u)))}catch(u){throw await c.rollbackToSavepoint(a).execute().catch(()=>{}),o.length=0,u}finally{this.mutationStack=s;}}let t=[],n=this.mutationStack;this.mutationStack=t;let i=await this.db.startTransaction().execute();try{let a=new r(i,this.schema,this.logger,this.server);return a.mutationStack=t,await e({trx:a,commit:async()=>{await i.commit().execute(),this.notifyMutations(t);},rollback:async()=>{await i.rollback().execute(),t.length=0;}}).then(s=>i.isCommitted||i.isRolledBack?s:i.commit().execute().then(()=>(this.notifyMutations(t),s)))}catch(a){throw await i.rollback().execute(),t.length=0,a}finally{this.mutationStack=n;}}get internalDB(){return this.db}convertToMaterializedLiveType(e){return {value:Object.entries(e).reduce((t,[n,i])=>{var a,s,o;return n==="_meta"||(n==="id"?t[n]={value:i}:Array.isArray(i)?t[n]={value:i.map(c=>this.convertToMaterializedLiveType(c)),_meta:{timestamp:(a=e==null?void 0:e._meta)==null?void 0:a[n]}}:typeof i=="object"&&i!==null&&!(i instanceof Date)?t[n]={...this.convertToMaterializedLiveType(i),_meta:{timestamp:(s=e==null?void 0:e._meta)==null?void 0:s[n]}}:t[n]={value:i,_meta:{timestamp:(o=e==null?void 0:e._meta)==null?void 0:o[n]}}),t},{})}}isKyselyLike(e){if(e instanceof kysely.Kysely)return true;if(!e||typeof e!="object")return false;let t=e,n=typeof t.selectFrom=="function",i=typeof t.startTransaction=="function",a=typeof t.savepoint=="function",s=typeof t.isTransaction=="boolean"||typeof t.isTransaction=="function";return n&&i||a&&s}buildMutation(e,t,n,i,a){var o;let s={};for(let[c,u]of Object.entries(i.value)){if(c==="id")continue;let p=(o=u._meta)==null?void 0:o.timestamp;p&&(s[c]={value:u.value,_meta:{timestamp:p}});}return Object.keys(s).length===0?null:{id:a??Y(),type:"MUTATE",resource:e,resourceId:t,procedure:n,payload:s}}trackMutation(e,t){this.db.isTransaction?this.mutationStack.push({mutation:e,entityData:t}):this.notifyMutations([e],t);}notifyMutations(e,t){if(this.server)if(t!==void 0){let n=e;for(let i of n)this.server.notifySubscribers(i,t);}else {let n=e;for(let{mutation:i,entityData:a}of n)this.server.notifySubscribers(i,a);}}};var xe=class r{router;storage;schema;middlewares=new Set;logger;contextProvider;mutationSubscriptions=new Set;collectionSubscriptions=new Map;constructor(e){var t;this.router=e.router,this.storage=e.storage,this.schema=e.schema,this.logger=Ee({level:e.logLevel??z.INFO}),(t=e.middlewares)==null||t.forEach(n=>{this.middlewares.add(n);}),this.storage.init(this.schema,this.logger,this),this.contextProvider=e.contextProvider;}static create(e){return new r(e)}handleQuery(e){let t=new X(this.storage);return this.wrapInMiddlewares(async n=>{var m,d,R,f,y,g,S;let i=Qe(n,this.schema,{stepId:"query",collectionName:n.resource,included:Object.keys(n.include??{})}),a={headers:n.headers,cookies:n.cookies,queryParams:n.queryParams,context:n.context},s={};for(let v=0;v<i.length;v++){let x=i[v],b=this.router.routes[x.resource];if(!b)throw new Error("Invalid resource");let A;if(x.getWhere&&x.referenceGetter){let w=x.referenceGetter(s);A=[];for(let M=0;M<w.length;M++)A.push(x.getWhere(w[M]));}else A=[void 0];let O=s[x.prevStepId??""],j=[];if(O)for(let w=0;w<O.length;w++){let M=O[w],N=((m=M==null?void 0:M.result)==null?void 0:m.data)??[];for(let $=0;$<N.length;$++){let ie=N[$],Se=(R=(d=ie==null?void 0:ie.value)==null?void 0:d.id)==null?void 0:R.value;Se&&j.push(Se);}}let P=[];for(let w=0;w<A.length;w++){let M=A[w],N=j[w];P.push((async()=>{let $=await b.handleQuery({req:{type:"QUERY",...x,...a,where:x.where,relationalWhere:M},batcher:t});return {includedBy:N,result:$}})());}let E=await Promise.allSettled(P),F=[];for(let w=0;w<E.length;w++){let M=E[w];M.status==="fulfilled"&&F.push(M.value);}s[x.stepId]=F;}let o=new Map,c=0;for(let v in s){let x=s[v],b=i[c];c++;for(let A=0;A<x.length;A++){let O=x[A],j=O.result.data;for(let P=0;P<j.length;P++){let E=j[P],F=(y=(f=E==null?void 0:E.value)==null?void 0:f.id)==null?void 0:y.value;if(!F)continue;let w=`${v}.${F}`,M=[];v!=="query"&&O.includedBy&&(M=[`${b.prevStepId}.${O.includedBy}`]);let N=o.get(w);if(N)for(let $=0;$<M.length;$++)N.includedBy.add(M[$]);else o.set(w,{data:E,includedBy:new Set(M),path:v.split(".").slice(-1)[0],isMany:b.isMany??false,collectionName:b.collectionName,included:b.included});}}}let u=Object.fromEntries(o),p={data:[]},l=Object.keys(u);for(let v=l.length-1;v>=0;v--){let x=l[v],b=u[x],A=b.path;if(A==="query"&&p.data.push(b.data),b.included.length)for(let O=0;O<b.included.length;O++){let j=b.included[O];b.data.value[j]??=((S=(g=this.schema[b.collectionName])==null?void 0:g.relations[j])==null?void 0:S.type)==="many"?{value:[]}:{value:null};}if(b.includedBy.size>0){let O=Array.from(b.includedBy);for(let j=0;j<O.length;j++){let P=O[j],E=u[P];E&&(b.isMany?(E.data.value[A]??={value:[]},E.data.value[A].value.push(b.data)):E.data.value[A]=b.data);}}}return p})(e.req)}async handleMutation(e){let t=await this.wrapInMiddlewares(async n=>{let i=this.router.routes[n.resource];if(!i)throw new Error("Invalid resource");return i.handleMutation({req:n,db:this.storage,schema:this.schema})})(e.req);if(t&&e.req.type==="MUTATE"&&t.acceptedValues&&(e.req.procedure==="INSERT"||e.req.procedure==="UPDATE")&&e.req.resourceId){let i=t.acceptedValues??{},a=e.req,s=a.resourceId;Object.keys(i).length&&s&&this.mutationSubscriptions.forEach(o=>{o({id:e.req.context.messageId,type:"MUTATE",resource:a.resource,payload:i,resourceId:s,procedure:a.procedure});});}return t}use(e){return this.middlewares.add(e),this}context(e){return this.contextProvider=e,this}subscribeToMutations(e,t,n){let i=e.resource,a={query:e,authorizationWhere:n},s=je(a),o=this.collectionSubscriptions.get(i);o||(o=new Map,this.collectionSubscriptions.set(i,o));let c=o.get(s);return c?(c.callbacks.add(t),n!==void 0&&(c.authorizationWhere=n)):o.set(s,{callbacks:new Set([t]),...a}),()=>{var p,l;let u=this.collectionSubscriptions.get(i);u&&((p=u.get(s))==null||p.callbacks.delete(t),((l=u.get(s))==null?void 0:l.callbacks.size)===0&&u.delete(s));}}notifySubscribers(e,t){let n=e.resource,i=this.collectionSubscriptions.get(n);if(i&&t)for(let a of Array.from(i.values())){let s=ve(a.query.where,this.schema[n]),o=D(s,a.authorizationWhere),c=I(t);if(!c)continue;(e.resourceId&&typeof c=="object"&&c!==null&&!("id"in c)||e.resourceId&&typeof c=="object"&&c!==null&&c.id!==e.resourceId)&&(c.id=e.resourceId);let u=Object.keys(o).length>0,p=true;u&&(p=C(c,o)),p&&a.callbacks.forEach(l=>{var h;try{l(e);}catch(m){(h=this.logger)==null||h.error(`Error in mutation subscription for resource ${n}:`,m);}});}}wrapInMiddlewares(e){return t=>Array.from(this.middlewares.values()).reduceRight((n,i)=>a=>i({req:a,next:n}),e)(t)}},er=xe.create;function Qe(r,e,t){let{include:n,where:i,...a}=r,{stepId:s}=t,o=[{...a,...t,where:i}];if(n&&typeof n=="object"&&Object.keys(n).length>0){let c=e[a.resource];if(!c)throw new Error(`Resource ${a.resource} not found`);o.push(...Object.entries(n).flatMap(([u,p])=>{let l=c.relations[u];if(!l)throw new Error(`Relation ${u} not found for resource ${a.resource}`);let h=l.entity.name;return Qe({...a,resource:h,include:p},e,{getWhere:l.type==="one"?m=>({id:m}):m=>({[l.foreignColumn]:m}),referenceGetter:m=>m[s].flatMap(d=>{let R=d.result.data??[];return l.type==="one"?R.map(f=>{var y,g;return (g=(y=f.value)==null?void 0:y[l.relationalColumn])==null?void 0:g.value}).filter(f=>f!==void 0):R.map(f=>{var y,g;return (g=(y=f.value)==null?void 0:y.id)==null?void 0:g.value}).filter(f=>f!==void 0)}),stepId:`${s}.${u}`,prevStepId:s,isMany:l.type==="many",collectionName:h,included:typeof p=="object"?Object.keys(p):[]})}));}return o}function ve(r,e){if(!r||!e||Object.keys(r).length===0)return r;if(r.$and){let n=r.$and.map(i=>ve(i,e)).filter(i=>!!i&&Object.keys(i).length>0);return n.length===0?void 0:n.length===1?n[0]:{$and:n}}if(r.$or){let n=r.$or.map(i=>ve(i,e)).filter(i=>!!i&&Object.keys(i).length>0);return n.length===0?void 0:n.length===1?n[0]:{$or:n}}let t={};for(let[n,i]of Object.entries(r))e.fields[n]&&(t[n]=i);return Object.keys(t).length>0?t:void 0}
|
|
2
|
+
exports.Route=Te;exports.RouteFactory=ge;exports.Router=he;exports.SQLStorage=be;exports.Server=xe;exports.Storage=H;exports.expressAdapter=Ln;exports.routeFactory=Pn;exports.router=$n;exports.server=er;
|
package/dist/server.d.cts
CHANGED
|
@@ -59,7 +59,7 @@ declare const router: <TSchema extends Schema<any>, TRoutes extends Record<keyof
|
|
|
59
59
|
}) => Router<TRoutes>;
|
|
60
60
|
type AnyRouter = Router<any>;
|
|
61
61
|
type QueryResult<TShape extends LiveObjectAny> = {
|
|
62
|
-
data:
|
|
62
|
+
data: MaterializedLiveType<TShape>[];
|
|
63
63
|
};
|
|
64
64
|
type MutationResult<TShape extends LiveObjectAny> = {
|
|
65
65
|
data: MaterializedLiveType<TShape>;
|
|
@@ -114,16 +114,27 @@ declare class RouteFactory {
|
|
|
114
114
|
declare const routeFactory: typeof RouteFactory.create;
|
|
115
115
|
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
116
116
|
|
|
117
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
118
|
+
|
|
119
|
+
interface DataSource {
|
|
120
|
+
get(query: RawQueryRequest): Awaitable<any[]>;
|
|
121
|
+
}
|
|
122
|
+
|
|
117
123
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
118
124
|
|
|
119
|
-
declare abstract class Storage {
|
|
125
|
+
declare abstract class Storage implements DataSource {
|
|
120
126
|
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
121
127
|
include?: IncludeClause<T>;
|
|
122
128
|
}): Promise<InferLiveObject<T> | undefined>;
|
|
123
129
|
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
124
130
|
where?: WhereClause<T>;
|
|
125
131
|
include?: IncludeClause<T>;
|
|
126
|
-
|
|
132
|
+
limit?: number;
|
|
133
|
+
sort?: {
|
|
134
|
+
key: string;
|
|
135
|
+
direction: "asc" | "desc";
|
|
136
|
+
}[];
|
|
137
|
+
}): Promise<InferLiveObject<T>[]>;
|
|
127
138
|
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
128
139
|
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<InferLiveObject<T>>;
|
|
129
140
|
abstract transaction<T>(fn: (opts: {
|
|
@@ -153,7 +164,7 @@ declare class SQLStorage extends Storage {
|
|
|
153
164
|
key: string;
|
|
154
165
|
direction: "asc" | "desc";
|
|
155
166
|
}[];
|
|
156
|
-
}): Promise<
|
|
167
|
+
}): Promise<InferLiveObject<T>[]>;
|
|
157
168
|
transaction<T>(fn: (opts: {
|
|
158
169
|
trx: Storage;
|
|
159
170
|
commit: () => Promise<void>;
|
package/dist/server.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ declare const router: <TSchema extends Schema<any>, TRoutes extends Record<keyof
|
|
|
59
59
|
}) => Router<TRoutes>;
|
|
60
60
|
type AnyRouter = Router<any>;
|
|
61
61
|
type QueryResult<TShape extends LiveObjectAny> = {
|
|
62
|
-
data:
|
|
62
|
+
data: MaterializedLiveType<TShape>[];
|
|
63
63
|
};
|
|
64
64
|
type MutationResult<TShape extends LiveObjectAny> = {
|
|
65
65
|
data: MaterializedLiveType<TShape>;
|
|
@@ -114,16 +114,27 @@ declare class RouteFactory {
|
|
|
114
114
|
declare const routeFactory: typeof RouteFactory.create;
|
|
115
115
|
type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
|
|
116
116
|
|
|
117
|
+
/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
|
|
118
|
+
|
|
119
|
+
interface DataSource {
|
|
120
|
+
get(query: RawQueryRequest): Awaitable<any[]>;
|
|
121
|
+
}
|
|
122
|
+
|
|
117
123
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
118
124
|
|
|
119
|
-
declare abstract class Storage {
|
|
125
|
+
declare abstract class Storage implements DataSource {
|
|
120
126
|
abstract findOne<T extends LiveObjectAny>(resource: T, id: string, options?: {
|
|
121
127
|
include?: IncludeClause<T>;
|
|
122
128
|
}): Promise<InferLiveObject<T> | undefined>;
|
|
123
129
|
abstract find<T extends LiveObjectAny>(resource: T, options?: {
|
|
124
130
|
where?: WhereClause<T>;
|
|
125
131
|
include?: IncludeClause<T>;
|
|
126
|
-
|
|
132
|
+
limit?: number;
|
|
133
|
+
sort?: {
|
|
134
|
+
key: string;
|
|
135
|
+
direction: "asc" | "desc";
|
|
136
|
+
}[];
|
|
137
|
+
}): Promise<InferLiveObject<T>[]>;
|
|
127
138
|
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
128
139
|
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<InferLiveObject<T>>;
|
|
129
140
|
abstract transaction<T>(fn: (opts: {
|
|
@@ -153,7 +164,7 @@ declare class SQLStorage extends Storage {
|
|
|
153
164
|
key: string;
|
|
154
165
|
direction: "asc" | "desc";
|
|
155
166
|
}[];
|
|
156
|
-
}): Promise<
|
|
167
|
+
}): Promise<InferLiveObject<T>[]>;
|
|
157
168
|
transaction<T>(fn: (opts: {
|
|
158
169
|
trx: Storage;
|
|
159
170
|
commit: () => Promise<void>;
|
package/dist/server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {a,b,t,w,x,z as z$2,y,v}from'./chunk-3SQDLIFN.js';import V from'node:crypto';import Ye,{parse}from'qs';import {z as z$1}from'zod';import {Kysely,PostgresDialect}from'kysely';import {jsonObjectFrom,jsonArrayFrom}from'kysely/helpers/postgres';var H=a(Q=>{Object.defineProperty(Q,"__esModule",{value:true});Q.parse=Qe;Q.serialize=Ge;var Ue=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Be=/^[\u0021-\u003A\u003C-\u007E]*$/,_e=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Ve=/^[\u0020-\u003A\u003D-\u007E]*$/,Fe=Object.prototype.toString,qe=(()=>{let i=function(){};return i.prototype=Object.create(null),i})();function Qe(i,t){let e=new qe,r=i.length;if(r<2)return e;let n=(t==null?void 0:t.decode)||Ze,a=0;do{let s=i.indexOf("=",a);if(s===-1)break;let c=i.indexOf(";",a),o=c===-1?r:c;if(s>o){a=i.lastIndexOf(";",s-1)+1;continue}let l=he(i,a,s),f=ge(i,s,l),u=i.slice(l,f);if(e[u]===void 0){let h=he(i,s+1,o),T=ge(i,o,h),d=n(i.slice(h,T));e[u]=d;}a=o+1;}while(a<r);return e}function he(i,t,e){do{let r=i.charCodeAt(t);if(r!==32&&r!==9)return t}while(++t<e);return e}function ge(i,t,e){for(;t>e;){let r=i.charCodeAt(--t);if(r!==32&&r!==9)return t+1}return e}function Ge(i,t,e){let r=(e==null?void 0:e.encode)||encodeURIComponent;if(!Ue.test(i))throw new TypeError(`argument name is invalid: ${i}`);let n=r(t);if(!Be.test(n))throw new TypeError(`argument val is invalid: ${t}`);let a=i+"="+n;if(!e)return a;if(e.maxAge!==void 0){if(!Number.isInteger(e.maxAge))throw new TypeError(`option maxAge is invalid: ${e.maxAge}`);a+="; Max-Age="+e.maxAge;}if(e.domain){if(!_e.test(e.domain))throw new TypeError(`option domain is invalid: ${e.domain}`);a+="; Domain="+e.domain;}if(e.path){if(!Ve.test(e.path))throw new TypeError(`option path is invalid: ${e.path}`);a+="; Path="+e.path;}if(e.expires){if(!Ke(e.expires)||!Number.isFinite(e.expires.valueOf()))throw new TypeError(`option expires is invalid: ${e.expires}`);a+="; Expires="+e.expires.toUTCString();}if(e.httpOnly&&(a+="; HttpOnly"),e.secure&&(a+="; Secure"),e.partitioned&&(a+="; Partitioned"),e.priority)switch(typeof e.priority=="string"?e.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${e.priority}`)}if(e.sameSite)switch(typeof e.sameSite=="string"?e.sameSite.toLowerCase():e.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${e.sameSite}`)}return a}function Ze(i){if(i.indexOf("%")===-1)return i;try{return decodeURIComponent(i)}catch{return i}}function Ke(i){return Fe.call(i)==="[object Date]"}});var ye="0123456789ABCDEFGHJKMNPQRSTVWXYZ",N=32;var $e=16,fe=10,pe=0xffffffffffff;var O;(function(i){i.Base32IncorrectEncoding="B32_ENC_INVALID",i.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",i.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",i.EncodeTimeNegative="ENC_TIME_NEG",i.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",i.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",i.PRNGDetectFailure="PRNG_DETECT",i.ULIDInvalid="ULID_INVALID",i.Unexpected="UNEXPECTED",i.UUIDInvalid="UUID_INVALID";})(O||(O={}));var L=class extends Error{constructor(t,e){super(`${e} (${t})`),this.name="ULIDError",this.code=t;}};function ze(i){let t=Math.floor(i()*N);return t===N&&(t=N-1),ye.charAt(t)}function Pe(i){var r;let t=ke(),e=t&&(t.crypto||t.msCrypto)||(typeof V<"u"?V:null);if(typeof(e==null?void 0:e.getRandomValues)=="function")return ()=>{let n=new Uint8Array(1);return e.getRandomValues(n),n[0]/255};if(typeof(e==null?void 0:e.randomBytes)=="function")return ()=>e.randomBytes(1).readUInt8()/255;if((r=V)!=null&&r.randomBytes)return ()=>V.randomBytes(1).readUInt8()/255;throw new L(O.PRNGDetectFailure,"Failed to find a reliable PRNG")}function ke(){return De()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Ne(i,t){let e="";for(;i>0;i--)e=ze(t)+e;return e}function We(i,t=fe){if(isNaN(i))throw new L(O.EncodeTimeValueMalformed,`Time must be a number: ${i}`);if(i>pe)throw new L(O.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${pe}: ${i}`);if(i<0)throw new L(O.EncodeTimeNegative,`Time must be positive: ${i}`);if(Number.isInteger(i)===false)throw new L(O.EncodeTimeValueMalformed,`Time must be an integer: ${i}`);let e,r="";for(let n=t;n>0;n--)e=i%N,r=ye.charAt(e)+r,i=(i-e)/N;return r}function De(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function me(i,t){let e=Pe(),r=Date.now();return We(r,fe)+Ne($e,e)}var F=()=>me().toLowerCase();var $=(...i)=>{let t=i.filter(e=>!!e);return t.length===0?{}:t.length===1?t[0]:{$and:t}};var q=class{storage;queue=new Map;scheduled=false;constructor(t){this.storage=t;}async rawFind({resource:t,commonWhere:e,uniqueWhere:r,...n}){return new Promise((a,s)=>{let c=this.getBatchKey({resource:t,commonWhere:e,...n}),o={resource:t,commonWhere:e,uniqueWhere:r,...n,resolve:a,reject:s};this.queue.has(c)||this.queue.set(c,[]);let l=this.queue.get(c);l&&l.push(o),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(t){let{resource:e,commonWhere:r,...n}=t;return `${e}:${JSON.stringify(r??{})}:${JSON.stringify(n??{})}`}async processBatch(){this.scheduled=false;let t=Array.from(this.queue.entries());this.queue.clear();for(let[,e]of t)try{await this.executeBatchedRequests(e);}catch(r){e.forEach(n=>{n.reject(r);});}}async executeBatchedRequests(t){var h,T;if(t.length===0)return;let e=t[0],{resource:r,commonWhere:n,include:a,sort:s}=e,c=t.length===1?e.limit:void 0,o=t.map(d=>d.uniqueWhere).filter(d=>d!==void 0),l=n,f=(h=Object.entries(o[0]??{})[0])==null?void 0:h[0];if(o.length>0){let d=o.map(R=>R[f]).filter(R=>R!=null);d.length>0&&(l=$(n,{[f]:{$in:d}}));}let u=await this.storage.rawFind({resource:r,where:l,include:a,sort:s,limit:c});for(let d of t){let R={};if(d.uniqueWhere){let[y,p]=Object.entries(d.uniqueWhere)[0];for(let[m,g]of Object.entries(u))((T=g.value[y])==null?void 0:T.value)===p&&(R[m]=g);}else Object.assign(R,u);d.resolve(R);}}};var be=b(H(),1);var W=z$1.object({resource:z$1.string(),where:z$1.record(z$1.string(),z$1.any()).optional(),include:z$1.record(z$1.string(),z$1.any()).optional(),lastSyncedAt:z$1.string().optional(),limit:z$1.coerce.number().optional(),sort:z$1.array(z$1.object({key:z$1.string(),direction:z$1.enum(["asc","desc"])})).optional()}),J=z$1.record(z$1.string(),z$1.object({value:z$1.string().or(z$1.number()).or(z$1.boolean()).or(z$1.date()).nullable(),_meta:z$1.object({timestamp:z$1.string().optional().nullable()}).optional()})),He=J.superRefine((i,t)=>{i.id&&t.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Te=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string(),resourceId:z$1.string().optional()}),D=Te.extend({procedure:z$1.string(),payload:z$1.any().optional()}),U=Te.extend({procedure:z$1.enum(["INSERT","UPDATE"]),payload:He});z$1.union([U,D]);var Re=W.omit({resource:true}),Y=D.omit({id:true,type:true,resource:true,procedure:true}),X=U.omit({id:true,type:true,resource:true,procedure:true});z$1.union([X,Y]);var ee=i=>{if(i==null)return i;if(i==="null")return null;if(Array.isArray(i))return i.map(ee);if(typeof i=="object"&&i.constructor===Object){let t={};for(let[e,r]of Object.entries(i))t[e]=ee(r);return t}return i},Se=i=>{let t=i.logger;return async e=>{var r;try{let n=typeof e.headers.getSetCookie=="function"?Object.fromEntries(e.headers):e.headers,a={headers:n,cookies:n.cookie?be.default.parse(n.cookie):{}},s=new URL(e.url),c=s.pathname.split("/"),o=s.searchParams,l=ee(Ye.parse(o.toString())),f=await((r=i.contextProvider)==null?void 0:r.call(i,{transport:"HTTP",headers:a.headers,cookies:a.cookies,queryParams:l}))??{};if(e.method==="GET"){let u=c[c.length-1],{success:h,data:T,error:d}=Re.safeParse(l);if(!h)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:d},{status:400});let R=await i.handleQuery({req:{...a,...T,type:"QUERY",resource:u,context:f,queryParams:l}});return !R||!R.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(R.data)}if(e.method==="POST")try{let u=c[c.length-1],h=c[c.length-2],T=e.body?await e.json():{},d;if(u==="insert"||u==="update"){let{success:y,data:p,error:m}=X.safeParse(T);if(!y)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:m},{status:400});d=p;}else {let{success:y,data:p,error:m}=Y.safeParse(T);if(!y)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:m},{status:400});d=p;}let R=await i.handleMutation({req:{...a,type:"MUTATE",resource:h,input:d.payload,context:f,resourceId:d.resourceId,procedure:u==="insert"||u==="update"?u.toUpperCase():u,queryParams:{}}});return Response.json(R)}catch(u){return t.error("Error parsing mutation from the client:",u),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(n){return t.error("Unexpected error:",n),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}}};var Me=b(H(),1);var z=z$1.string(),Xe=W.extend({id:z,type:z$1.literal("SUBSCRIBE")}),et=W.extend({id:z,type:z$1.literal("QUERY")}),we=U.extend({id:z}),tt=D.extend({id:z}),rt=z$1.union([tt,we]),xe=z$1.union([Xe,et,rt]),nt=z$1.object({id:z,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),it=z$1.object({id:z,type:z$1.literal("REPLY"),data:z$1.any()});z$1.union([nt,it,we]);z$1.object({resource:z$1.string(),data:z$1.record(z$1.string(),J)});var Ie=i=>{let t={},e=i.logger;return (r,n)=>{var u;let a=h=>{r.send(JSON.stringify(h));},s=F(),c=new Set,o={headers:n.headers,cookies:typeof n.headers.cookie=="string"?Me.default.parse(n.headers.cookie):{}},l=parse(n.url.split("?")[1]),f=(u=i.contextProvider)==null?void 0:u.call(i,{transport:"WEBSOCKET",headers:o.headers,cookies:o.cookies,queryParams:l});t[s]=r,e.info("Client connected:",s),r.on("message",async h=>{var T;try{e.debug("Message received from the client:",h);let d=xe.parse(JSON.parse(h.toString()));if(d.type==="SUBSCRIBE"){let R=await f??{},y=d.resource,p=i.router.routes[y],m;if((T=p==null?void 0:p.authorization)!=null&&T.read){let g=p.authorization.read({ctx:R});m=typeof g=="object"?g:void 0;}c.add(i.subscribeToMutations(d,g=>{var S;!g.resourceId||!g.payload||!Object.keys(g.payload).length||(S=t[s])==null||S.send(JSON.stringify(g));},m));}else if(d.type==="QUERY"){let{resource:R}=d,y=await i.handleQuery({req:{...o,type:"QUERY",resource:R,context:await f??{},queryParams:l}});if(!y||!y.data)throw new Error("Invalid resource");a({id:d.id,type:"REPLY",data:{resource:R,data:Object.fromEntries(Object.entries(y.data??{}).map(([p,m])=>[p,m.value]))}});}else if(d.type==="MUTATE"){let{resource:R}=d;e.debug("Received mutation from client:",d);try{let y=await i.handleMutation({req:{...o,type:"MUTATE",resource:R,input:d.payload,context:{messageId:d.id,...await f??{}},resourceId:d.resourceId,procedure:d.procedure,queryParams:l}});d.procedure&&d.procedure!=="INSERT"&&d.procedure!=="UPDATE"&&a({id:d.id,type:"REPLY",data:y});}catch(y){a({id:d.id,type:"REJECT",resource:R,message:y.message}),e.error("Error parsing mutation from the client:",y);}}}catch(d){e.error("Error handling message from the client:",d);}}),r.on("close",()=>{e.info("Connection closed",s),delete t[s];for(let h of Array.from(c))h();});}};function ve(i){let t=`${i.protocol}://${i.hostname}${i.url}`,e=new Headers;return Object.entries(i.headers).forEach(([r,n])=>{n&&e.set(r,Array.isArray(n)?n.join(","):n);}),new Request(t,{method:i.method,headers:e,body:i.body&&i.method!=="GET"?JSON.stringify(i.body):void 0})}var Ut=(i,t,e)=>{i.ws(`${(e==null?void 0:e.basePath)??""}/ws`,Ie(t)),i.use(`${(e==null?void 0:e.basePath)??""}/`,(r,n)=>{Se(t)(ve(r)).then(s=>s.json().then(c=>n.status(s.status).send(c)));});};var te=class i{routes;constructor(t){this.routes=t.routes;}static create(t){return new i(t)}},Qt=i=>te.create({...i}),st=i=>({handler:t=>({inputValidator:i??z$1.undefined(),handler:t})}),re=class i{resourceSchema;middlewares;customMutations;authorization;constructor(t,e,r){this.resourceSchema=t,this.middlewares=new Set,this.customMutations=e??{},this.authorization=r;}use(...t){for(let e of t)this.middlewares.add(e);return this}withMutations(t){return new i(this.resourceSchema,t({mutation:st}),this.authorization)}handleQuery=async({req:t,batcher:e})=>await this.wrapInMiddlewares(async r=>{var a,s;let n=(s=(a=this.authorization)==null?void 0:a.read)==null?void 0:s.call(a,{ctx:r.context});if(typeof n=="boolean"&&!n)throw new Error("Not authorized");return {data:await e.rawFind({resource:r.resource,commonWhere:$(r.where,typeof n=="object"?n:void 0),uniqueWhere:r.relationalWhere,include:r.include,limit:r.limit,sort:r.sort})}})(t);handleMutation=async({req:t,db:e,schema:r})=>await this.wrapInMiddlewares(async n=>{if(!n.procedure)throw new Error("Procedure is required for mutations");let a=this.customMutations[n.procedure];if(a){let s=a.inputValidator.parse(n.input);return n.input=s,a.handler({req:n,db:e})}else {if(n.procedure==="INSERT"||n.procedure==="UPDATE")return this.handleSet({req:n,db:e,operation:n.procedure,schema:r});throw new Error(`Unknown procedure: ${n.procedure}`)}})(t);handleSet=async({req:t$1,db:e,operation:r,schema:n})=>{if(!t$1.input)throw new Error("Payload is required");if(!t$1.resourceId)throw new Error("ResourceId is required");let a=await e.rawFindById(t$1.resource,t$1.resourceId);if(r==="INSERT"&&a)throw new Error("Resource already exists");if(r==="UPDATE"&&!a)throw new Error("Resource not found");return e.transaction(async({trx:s})=>{var f,u,h,T,d,R,y;let[c,o]=this.resourceSchema.mergeMutation("set",t$1.input,a);if(!o)throw new Error("Mutation rejected");if(r==="INSERT"){let p=await s.rawInsert(t$1.resource,t$1.resourceId,c,(f=t$1.context)==null?void 0:f.messageId),m=t(p);if(m.id=m.id??t$1.resourceId,(u=this.authorization)!=null&&u.insert){let g=this.authorization.insert({ctx:t$1.context,value:m});if(typeof g=="boolean"){if(!g)throw new Error("Not authorized")}else {let S=w(g,t$1.resource,n),w$1=Object.keys(S).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,S):p,E=t(w$1);if(E.id=E.id??t$1.resourceId,!x(E,g))throw new Error("Not authorized")}}return {data:p,acceptedValues:o}}if((T=(h=this.authorization)==null?void 0:h.update)!=null&&T.preMutation){let p=t(a);p.id=p.id??t$1.resourceId;let m=this.authorization.update.preMutation({ctx:t$1.context,value:p});if(typeof m=="boolean"){if(!m)throw new Error("Not authorized")}else {let g=w(m,t$1.resource,n),S=Object.keys(g).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,g):a,w$1=t(S);if(w$1.id=w$1.id??t$1.resourceId,!x(w$1,m))throw new Error("Not authorized")}}let l=await s.rawUpdate(t$1.resource,t$1.resourceId,c,(d=t$1.context)==null?void 0:d.messageId);if((y=(R=this.authorization)==null?void 0:R.update)!=null&&y.postMutation){let p=t(l);p.id=p.id??t$1.resourceId;let m=this.authorization.update.postMutation({ctx:t$1.context,value:p});if(typeof m=="boolean"){if(!m)throw new Error("Not authorized")}else {let g=w(m,t$1.resource,n),S=Object.keys(g).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,g):l,w$1=t(S);if(w$1.id=w$1.id??t$1.resourceId,!x(w$1,m))throw new Error("Not authorized")}}return {data:l,acceptedValues:o}})};wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},ne=class i{middlewares;constructor(t=[]){this.middlewares=t;}collectionRoute(t,e){return new re(t,void 0,e).use(...this.middlewares)}use(...t){return new i([...this.middlewares,...t])}static create(){return new i}},Gt=ne.create;var B=class{async insert(t$1,e){let r=new Date().toISOString();return t(await this.rawInsert(t$1.name,e.id,{value:Object.fromEntries(Object.entries(e).map(([n,a])=>[n,{value:a,_meta:{timestamp:r}}]))}))}async update(t$1,e,r){let n=new Date().toISOString(),{id:a,...s}=r;return t(await this.rawUpdate(t$1.name,e,{value:Object.fromEntries(Object.entries(s).map(([c,o])=>[c,{value:o,_meta:{timestamp:n}}]))}))}};function G(i,t,e,r){if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error("Resource not found");let a=r.$or,s=r.$and;return (a?e.or:e.and)(a?r.$or.map(c=>G(i,t,e,c)):s?r.$and.map(c=>G(i,t,e,c)):Object.entries(r).map(([c,o])=>{var l,f;if(n.fields[c])return (o==null?void 0:o.$eq)!==void 0?e(`${t}.${c}`,o.$eq===null?"is":"=",o.$eq):(o==null?void 0:o.$in)!==void 0?e(`${t}.${c}`,"in",o.$in):(o==null?void 0:o.$not)!==void 0?((l=o==null?void 0:o.$not)==null?void 0:l.$in)!==void 0?e(`${t}.${c}`,"not in",o.$not.$in):((f=o==null?void 0:o.$not)==null?void 0:f.$eq)!==void 0?e(`${t}.${c}`,o.$not.$eq===null?"is not":"!=",o.$not.$eq):e(`${t}.${c}`,o.$not===null?"is not":"!=",o.$not):(o==null?void 0:o.$gt)!==void 0?e(`${t}.${c}`,">",o.$gt):(o==null?void 0:o.$gte)!==void 0?e(`${t}.${c}`,">=",o.$gte):(o==null?void 0:o.$lt)!==void 0?e(`${t}.${c}`,"<",o.$lt):(o==null?void 0:o.$lte)!==void 0?e(`${t}.${c}`,"<=",o.$lte):e(`${t}.${c}`,o===null?"is":"=",o);if(n.relations[c]){let u=n.relations[c],h=u.entity.name;return u.type==="many"?e.exists(ie(i,h,e.selectFrom(h).select("id").whereRef(u.foreignColumn,"=",`${t}.id`),o)):G(i,h,e,o)}return null}).filter(Boolean))}function Z(i,t,e,r){let n=i[t];if(!n)throw new Error("Resource not found");if(!r)return e;if(r.$and){for(let a of r.$and)e=Z(i,t,e,a);return e}else if(r.$or){for(let a of r.$or)e=Z(i,t,e,a);return e}for(let[a,s]of Object.entries(r)){if(!n.relations[a])continue;let c=n.relations[a],o=c.entity.name,l=c.type==="one"?"id":c.foreignColumn,f=c.type==="one"?c.relationalColumn:"id";e=e.leftJoin(o,`${o}.${l}`,`${t}.${f}`),s instanceof Object&&!Array.isArray(s)&&s!==null&&(e=Z(i,o,e,s));}return e}function ie(i,t,e,r){return !r||Object.keys(r).length===0?e:(e=Z(i,t,e,r),e.where(n=>G(i,t,n,r)))}function K(i,t,e,r){if(!r)return e;if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error(`Resource not found: ${t}`);for(let a of Object.keys(r)){if(!n.relations[a])throw new Error(`Relation ${a} not found in resource ${t}`);let s=n.relations[a],c=s.entity.name,o=r[a],l=s.type==="one"?"id":s.foreignColumn,f=s.type==="one"?s.relationalColumn:"id",u=s.type==="one"?jsonObjectFrom:jsonArrayFrom,h=typeof o=="object"&&o!==null;e=e.select(T=>{let d=T.selectFrom(c).selectAll(c).whereRef(`${c}.${l}`,"=",`${t}.${f}`).select(R=>jsonObjectFrom(R.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return h&&(d=K(i,c,d,o)),u(d).as(a)});}return e}var Oe="42701",ae=class i extends B{db;schema;logger;server;mutationStack=[];constructor(t,e,r,n){super(),this.isKyselyLike(t)?this.db=t:this.db=new Kysely({dialect:new PostgresDialect({pool:t})}),this.schema=e,this.logger=r,this.server=n,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async init(t,e,r){var a;this.schema=t,this.logger=e,this.server=r;let n=await this.db.introspection.getTables();for(let[s,c]of Object.entries(t)){let o=n.find(u=>u.name===s);o||await this.db.schema.createTable(s).ifNotExists().execute();let l=`${s}_meta`,f=n.find(u=>u.name===l);f||await this.db.schema.createTable(l).ifNotExists().execute();for(let[u,h]of Object.entries(c.fields)){let T=o==null?void 0:o.columns.find(y=>y.name===u),d=h.getStorageFieldType();T?T.dataType!==d.type&&((a=this.logger)==null||a.warn("Column type mismatch:",u,"expected to have type:",d.type,"but has type:",T.dataType)):(await this.db.schema.alterTable(s).addColumn(u,d.type,y=>{let p=y;return d.unique&&(p=p.unique()),d.nullable||(p=p.notNull()),d.references&&(p=p.references(d.references)),d.primary&&(p=p.primaryKey()),d.default!==void 0&&(p=p.defaultTo(d.default)),p}).execute().catch(y=>{var p;if(y.code!==Oe)throw (p=this.logger)==null||p.error("Error adding column",u,y),y}),d.index&&await this.db.schema.createIndex(`${s}_${u}_index`).on(s).column(u).execute().catch(()=>{})),(f==null?void 0:f.columns.find(y=>y.name===u))||await this.db.schema.alterTable(l).addColumn(u,"varchar",y=>{let p=y;return d.primary&&(p=p.primaryKey().references(`${s}.${u}`)),p}).execute().catch(y=>{var p;if(y.code!==Oe)throw (p=this.logger)==null||p.error("Error adding meta column",u,y),y});}}}async rawFindById(t,e,r){if(!this.schema)throw new Error("Schema not initialized");let n=await this.db.selectFrom(t).where("id","=",e).selectAll(t).select(s=>jsonObjectFrom(s.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));n=K(this.schema,t,n,r);let a=await n.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(t$1,e,r){let n=await this.rawFindById(t$1.name,e,r==null?void 0:r.include);if(n)return t(n)}async rawFind(t){if(!this.schema)throw new Error("Schema not initialized");let{resource:e,where:r,include:n,limit:a,sort:s}=t,c=this.db.selectFrom(e).selectAll(e).select(u=>jsonObjectFrom(u.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));c=ie(this.schema,e,c,r),c=K(this.schema,e,c,n),a!==void 0&&(c=c.limit(a)),s!==void 0&&s.forEach(u=>{c=c.orderBy(u.key,u.direction);});let o=await c.execute(),l=Object.fromEntries(o.map(u=>{let{id:h}=u;return [h,u]}));return Object.keys(l).length===0?{}:Object.entries(l).reduce((u,[h,T])=>(u[h]=this.convertToMaterializedLiveType(T),u),{})}async find(t$1,e){let r=await this.rawFind({resource:t$1.name,where:e==null?void 0:e.where,include:e==null?void 0:e.include,limit:e==null?void 0:e.limit,sort:e==null?void 0:e.sort});return Object.fromEntries(Object.entries(r).map(([n,a])=>[n,t(a)]))}async rawInsert(t,e,r,n){var o;let a={},s={};for(let[l,f]of Object.entries(r.value)){let u=(o=f._meta)==null?void 0:o.timestamp;u&&(a[l]=f.value,s[l]=u);}await this.db.insertInto(t).values({...a,id:e}).execute().then(()=>{this.db.insertInto(`${t}_meta`).values({...s,id:e}).execute();});let c=this.buildMutation(t,e,"INSERT",r,n);return c&&this.trackMutation(c,r),r}async rawUpdate(t,e,r,n){var o;let a={},s={};for(let[l,f]of Object.entries(r.value)){let u=(o=f._meta)==null?void 0:o.timestamp;u&&(a[l]=f.value,s[l]=u);}await Promise.all([this.db.updateTable(t).set(a).where("id","=",e).execute(),this.db.insertInto(`${t}_meta`).values({...s,id:e}).onConflict(l=>l.column("id").doUpdateSet(s)).execute()]);let c=this.buildMutation(t,e,"UPDATE",r,n);return c&&this.trackMutation(c,r),r}async transaction(t){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let a=Math.random().toString(36).substring(2,15),s=this.mutationStack,c=[];this.mutationStack=c;let o=await this.db.savepoint(a).execute();try{return await t({trx:this,commit:async()=>{await o.releaseSavepoint(a).execute(),s.push(...c);},rollback:async()=>{await o.rollbackToSavepoint(a).execute(),c.length=0;}}).then(l=>o.isCommitted||o.isRolledBack?l:o.releaseSavepoint(a).execute().then(()=>(s.push(...c),l)))}catch(l){throw await o.rollbackToSavepoint(a).execute().catch(()=>{}),c.length=0,l}finally{this.mutationStack=s;}}let e=[],r=this.mutationStack;this.mutationStack=e;let n=await this.db.startTransaction().execute();try{let a=new i(n,this.schema,this.logger,this.server);return a.mutationStack=e,await t({trx:a,commit:async()=>{await n.commit().execute(),this.notifyMutations(e);},rollback:async()=>{await n.rollback().execute(),e.length=0;}}).then(s=>n.isCommitted||n.isRolledBack?s:n.commit().execute().then(()=>(this.notifyMutations(e),s)))}catch(a){throw await n.rollback().execute(),e.length=0,a}finally{this.mutationStack=r;}}get internalDB(){return this.db}convertToMaterializedLiveType(t){return {value:Object.entries(t).reduce((e,[r,n])=>{var a,s,c;return r==="_meta"||(r==="id"?e[r]={value:n}:Array.isArray(n)?e[r]={value:n.map(o=>this.convertToMaterializedLiveType(o)),_meta:{timestamp:(a=t==null?void 0:t._meta)==null?void 0:a[r]}}:typeof n=="object"&&n!==null&&!(n instanceof Date)?e[r]={...this.convertToMaterializedLiveType(n),_meta:{timestamp:(s=t==null?void 0:t._meta)==null?void 0:s[r]}}:e[r]={value:n,_meta:{timestamp:(c=t==null?void 0:t._meta)==null?void 0:c[r]}}),e},{})}}isKyselyLike(t){if(t instanceof Kysely)return true;if(!t||typeof t!="object")return false;let e=t,r=typeof e.selectFrom=="function",n=typeof e.startTransaction=="function",a=typeof e.savepoint=="function",s=typeof e.isTransaction=="boolean"||typeof e.isTransaction=="function";return r&&n||a&&s}buildMutation(t,e,r,n,a){var c;let s={};for(let[o,l]of Object.entries(n.value)){if(o==="id")continue;let f=(c=l._meta)==null?void 0:c.timestamp;f&&(s[o]={value:l.value,_meta:{timestamp:f}});}return Object.keys(s).length===0?null:{id:a??F(),type:"MUTATE",resource:t,resourceId:e,procedure:r,payload:s}}trackMutation(t,e){this.db.isTransaction?this.mutationStack.push({mutation:t,entityData:e}):this.notifyMutations([t],e);}notifyMutations(t,e){if(this.server)if(e!==void 0){let r=t;for(let n of r)this.server.notifySubscribers(n,e);}else {let r=t;for(let{mutation:n,entityData:a}of r)this.server.notifySubscribers(n,a);}}};var oe=class i{router;storage;schema;middlewares=new Set;logger;contextProvider;mutationSubscriptions=new Set;collectionSubscriptions=new Map;constructor(t){var e;this.router=t.router,this.storage=t.storage,this.schema=t.schema,this.logger=z$2({level:t.logLevel??y.INFO}),(e=t.middlewares)==null||e.forEach(r=>{this.middlewares.add(r);}),this.storage.init(this.schema,this.logger,this),this.contextProvider=t.contextProvider;}static create(t){return new i(t)}handleQuery(t){let e=new q(this.storage);return this.wrapInMiddlewares(async r=>{var T,d,R;let n=Le(r,this.schema,{stepId:"query",collectionName:r.resource,included:Object.keys(r.include??{})}),a={headers:r.headers,cookies:r.cookies,queryParams:r.queryParams,context:r.context},s={};for(let y=0;y<n.length;y++){let p=n[y],m=this.router.routes[p.resource];if(!m)throw new Error("Invalid resource");let g;if(p.getWhere&&p.referenceGetter){let x=p.referenceGetter(s);g=[];for(let I=0;I<x.length;I++)g.push(p.getWhere(x[I]));}else g=[void 0];let S=s[p.prevStepId??""],w=[];if(S)for(let x=0;x<S.length;x++){let I=S[x],j=Object.keys(((T=I==null?void 0:I.result)==null?void 0:T.data)??{});for(let k=0;k<j.length;k++)w.push(j[k]);}let E=[];for(let x=0;x<g.length;x++){let I=g[x],j=w[x];E.push((async()=>{let k=await m.handleQuery({req:{type:"QUERY",...p,...a,where:p.where,relationalWhere:I},batcher:e});return {includedBy:j,result:k}})());}let A=await Promise.allSettled(E),P=[];for(let x=0;x<A.length;x++){let I=A[x];I.status==="fulfilled"&&P.push(I.value);}s[p.stepId]=P;}let c=new Map,o=0;for(let y in s){let p=s[y],m=n[o];o++;for(let g=0;g<p.length;g++){let S=p[g],w=S.result.data;for(let E in w){let A=w[E],P=`${y}.${E}`,x=[];y!=="query"&&S.includedBy&&(x=[`${m.prevStepId}.${S.includedBy}`]);let I=c.get(P);if(I)for(let j=0;j<x.length;j++)I.includedBy.add(x[j]);else c.set(P,{data:A,includedBy:new Set(x),path:y.split(".").slice(-1)[0],isMany:m.isMany??false,collectionName:m.collectionName,included:m.included});}}}let l=Object.fromEntries(c),f={data:{}},u=Object.keys(l);for(let y=u.length-1;y>=0;y--){let p=u[y],m=l[p],g=m.path;if(g==="query"&&(f.data[p.replace("query.","")]=m.data),m.included.length)for(let S=0;S<m.included.length;S++){let w=m.included[S];m.data.value[w]??=((R=(d=this.schema[m.collectionName])==null?void 0:d.relations[w])==null?void 0:R.type)==="many"?{value:[]}:{value:null};}if(m.includedBy.size>0){let S=Array.from(m.includedBy);for(let w=0;w<S.length;w++){let E=S[w],A=l[E];A&&(m.isMany?(A.data.value[g]??={value:[]},A.data.value[g].value.push(m.data)):A.data.value[g]=m.data);}}}return f})(t.req)}async handleMutation(t){let e=await this.wrapInMiddlewares(async r=>{let n=this.router.routes[r.resource];if(!n)throw new Error("Invalid resource");return n.handleMutation({req:r,db:this.storage,schema:this.schema})})(t.req);if(e&&t.req.type==="MUTATE"&&e.acceptedValues&&(t.req.procedure==="INSERT"||t.req.procedure==="UPDATE")&&t.req.resourceId){let n=e.acceptedValues??{},a=t.req,s=a.resourceId;Object.keys(n).length&&s&&this.mutationSubscriptions.forEach(c=>{c({id:t.req.context.messageId,type:"MUTATE",resource:a.resource,payload:n,resourceId:s,procedure:a.procedure});});}return e}use(t){return this.middlewares.add(t),this}context(t){return this.contextProvider=t,this}subscribeToMutations(t,e,r){let n=t.resource,a={query:t,authorizationWhere:r},s=v(a),c=this.collectionSubscriptions.get(n);c||(c=new Map,this.collectionSubscriptions.set(n,c));let o=c.get(s);return o?(o.callbacks.add(e),r!==void 0&&(o.authorizationWhere=r)):c.set(s,{callbacks:new Set([e]),...a}),()=>{var f,u;let l=this.collectionSubscriptions.get(n);l&&((f=l.get(s))==null||f.callbacks.delete(e),((u=l.get(s))==null?void 0:u.callbacks.size)===0&&l.delete(s));}}notifySubscribers(t$1,e){let r=t$1.resource,n=this.collectionSubscriptions.get(r);if(n&&e)for(let a of Array.from(n.values())){let s=se(a.query.where,this.schema[r]),c=$(s,a.authorizationWhere),o=t(e);if(!o)continue;(t$1.resourceId&&typeof o=="object"&&o!==null&&!("id"in o)||t$1.resourceId&&typeof o=="object"&&o!==null&&o.id!==t$1.resourceId)&&(o.id=t$1.resourceId);let l=Object.keys(c).length>0,f=true;l&&(f=x(o,c)),f&&a.callbacks.forEach(u=>{var h;try{u(t$1);}catch(T){(h=this.logger)==null||h.error(`Error in mutation subscription for resource ${r}:`,T);}});}}wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},yr=oe.create;function Le(i,t,e){let{include:r,where:n,...a}=i,{stepId:s}=e,c=[{...a,...e,where:n}];if(r&&typeof r=="object"&&Object.keys(r).length>0){let o=t[a.resource];if(!o)throw new Error(`Resource ${a.resource} not found`);c.push(...Object.entries(r).flatMap(([l,f])=>{let u=o.relations[l];if(!u)throw new Error(`Relation ${l} not found for resource ${a.resource}`);let h=u.entity.name;return Le({...a,resource:h,include:f},t,{getWhere:u.type==="one"?T=>({id:T}):T=>({[u.foreignColumn]:T}),referenceGetter:T=>T[s].flatMap(d=>d.result.data?u.type==="one"?Object.values(d.result.data).map(R=>{var y,p;return (p=(y=R.value)==null?void 0:y[u.relationalColumn])==null?void 0:p.value}):Object.keys(d.result.data):[]),stepId:`${s}.${l}`,prevStepId:s,isMany:u.type==="many",collectionName:h,included:typeof f=="object"?Object.keys(f):[]})}));}return c}function se(i,t){if(!i||!t||Object.keys(i).length===0)return i;if(i.$and){let r=i.$and.map(n=>se(n,t)).filter(n=>!!n&&Object.keys(n).length>0);return r.length===0?void 0:r.length===1?r[0]:{$and:r}}if(i.$or){let r=i.$or.map(n=>se(n,t)).filter(n=>!!n&&Object.keys(n).length>0);return r.length===0?void 0:r.length===1?r[0]:{$or:r}}let e={};for(let[r,n]of Object.entries(i))t.fields[r]&&(e[r]=n);return Object.keys(e).length>0?e:void 0}
|
|
2
|
-
export{
|
|
1
|
+
import {a,b,t,w,x,z as z$1,y,v}from'./chunk-3SQDLIFN.js';import G from'node:crypto';import it,{parse}from'qs';import {z}from'zod';import {Kysely,PostgresDialect}from'kysely';import {jsonObjectFrom,jsonArrayFrom}from'kysely/helpers/postgres';var te=a(H=>{Object.defineProperty(H,"__esModule",{value:true});H.parse=Ye;H.serialize=Xe;var Fe=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,Ge=/^[\u0021-\u003A\u003C-\u007E]*$/,Ze=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,Ke=/^[\u0020-\u003A\u003D-\u007E]*$/,He=Object.prototype.toString,Je=(()=>{let i=function(){};return i.prototype=Object.create(null),i})();function Ye(i,t){let e=new Je,r=i.length;if(r<2)return e;let n=(t==null?void 0:t.decode)||et,a=0;do{let s=i.indexOf("=",a);if(s===-1)break;let c=i.indexOf(";",a),o=c===-1?r:c;if(s>o){a=i.lastIndexOf(";",s-1)+1;continue}let u=we(i,a,s),y=xe(i,s,u),d=i.slice(u,y);if(e[d]===void 0){let h=we(i,s+1,o),m=xe(i,o,h),l=n(i.slice(h,m));e[d]=l;}a=o+1;}while(a<r);return e}function we(i,t,e){do{let r=i.charCodeAt(t);if(r!==32&&r!==9)return t}while(++t<e);return e}function xe(i,t,e){for(;t>e;){let r=i.charCodeAt(--t);if(r!==32&&r!==9)return t+1}return e}function Xe(i,t,e){let r=(e==null?void 0:e.encode)||encodeURIComponent;if(!Fe.test(i))throw new TypeError(`argument name is invalid: ${i}`);let n=r(t);if(!Ge.test(n))throw new TypeError(`argument val is invalid: ${t}`);let a=i+"="+n;if(!e)return a;if(e.maxAge!==void 0){if(!Number.isInteger(e.maxAge))throw new TypeError(`option maxAge is invalid: ${e.maxAge}`);a+="; Max-Age="+e.maxAge;}if(e.domain){if(!Ze.test(e.domain))throw new TypeError(`option domain is invalid: ${e.domain}`);a+="; Domain="+e.domain;}if(e.path){if(!Ke.test(e.path))throw new TypeError(`option path is invalid: ${e.path}`);a+="; Path="+e.path;}if(e.expires){if(!tt(e.expires)||!Number.isFinite(e.expires.valueOf()))throw new TypeError(`option expires is invalid: ${e.expires}`);a+="; Expires="+e.expires.toUTCString();}if(e.httpOnly&&(a+="; HttpOnly"),e.secure&&(a+="; Secure"),e.partitioned&&(a+="; Partitioned"),e.priority)switch(typeof e.priority=="string"?e.priority.toLowerCase():void 0){case "low":a+="; Priority=Low";break;case "medium":a+="; Priority=Medium";break;case "high":a+="; Priority=High";break;default:throw new TypeError(`option priority is invalid: ${e.priority}`)}if(e.sameSite)switch(typeof e.sameSite=="string"?e.sameSite.toLowerCase():e.sameSite){case true:case "strict":a+="; SameSite=Strict";break;case "lax":a+="; SameSite=Lax";break;case "none":a+="; SameSite=None";break;default:throw new TypeError(`option sameSite is invalid: ${e.sameSite}`)}return a}function et(i){if(i.indexOf("%")===-1)return i;try{return decodeURIComponent(i)}catch{return i}}function tt(i){return He.call(i)==="[object Date]"}});var Re="0123456789ABCDEFGHJKMNPQRSTVWXYZ",B=32;var De=16,be=10,Te=0xffffffffffff;var P;(function(i){i.Base32IncorrectEncoding="B32_ENC_INVALID",i.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",i.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",i.EncodeTimeNegative="ENC_TIME_NEG",i.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",i.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",i.PRNGDetectFailure="PRNG_DETECT",i.ULIDInvalid="ULID_INVALID",i.Unexpected="UNEXPECTED",i.UUIDInvalid="UUID_INVALID";})(P||(P={}));var k=class extends Error{constructor(t,e){super(`${e} (${t})`),this.name="ULIDError",this.code=t;}};function Ue(i){let t=Math.floor(i()*B);return t===B&&(t=B-1),Re.charAt(t)}function Be(i){var r;let t=_e(),e=t&&(t.crypto||t.msCrypto)||(typeof G<"u"?G:null);if(typeof(e==null?void 0:e.getRandomValues)=="function")return ()=>{let n=new Uint8Array(1);return e.getRandomValues(n),n[0]/255};if(typeof(e==null?void 0:e.randomBytes)=="function")return ()=>e.randomBytes(1).readUInt8()/255;if((r=G)!=null&&r.randomBytes)return ()=>G.randomBytes(1).readUInt8()/255;throw new k(P.PRNGDetectFailure,"Failed to find a reliable PRNG")}function _e(){return Qe()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Ve(i,t){let e="";for(;i>0;i--)e=Ue(t)+e;return e}function qe(i,t=be){if(isNaN(i))throw new k(P.EncodeTimeValueMalformed,`Time must be a number: ${i}`);if(i>Te)throw new k(P.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${Te}: ${i}`);if(i<0)throw new k(P.EncodeTimeNegative,`Time must be positive: ${i}`);if(Number.isInteger(i)===false)throw new k(P.EncodeTimeValueMalformed,`Time must be an integer: ${i}`);let e,r="";for(let n=t;n>0;n--)e=i%B,r=Re.charAt(e)+r,i=(i-e)/B;return r}function Qe(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function Se(i,t){let e=Be(),r=Date.now();return qe(r,be)+Ve(De,e)}var Z=()=>Se().toLowerCase();var W=(...i)=>{let t=i.filter(e=>!!e);return t.length===0?{}:t.length===1?t[0]:{$and:t}};var K=class{storage;queue=new Map;scheduled=false;constructor(t){this.storage=t;}async rawFind({resource:t,commonWhere:e,uniqueWhere:r,...n}){return new Promise((a,s)=>{let c=this.getBatchKey({resource:t,commonWhere:e,...n}),o={resource:t,commonWhere:e,uniqueWhere:r,...n,resolve:a,reject:s};this.queue.has(c)||this.queue.set(c,[]);let u=this.queue.get(c);u&&u.push(o),this.scheduled||(this.scheduled=true,setImmediate(()=>{this.processBatch();}));})}getBatchKey(t){let{resource:e,commonWhere:r,...n}=t;return `${e}:${JSON.stringify(r??{})}:${JSON.stringify(n??{})}`}async processBatch(){this.scheduled=false;let t=Array.from(this.queue.entries());this.queue.clear();for(let[,e]of t)try{await this.executeBatchedRequests(e);}catch(r){e.forEach(n=>{n.reject(r);});}}async executeBatchedRequests(t){var h;if(t.length===0)return;let e=t[0],{resource:r,commonWhere:n,include:a,sort:s}=e,c=t.length===1?e.limit:void 0,o=t.map(m=>m.uniqueWhere).filter(m=>m!==void 0),u=n,y=(h=Object.entries(o[0]??{})[0])==null?void 0:h[0];if(o.length>0){let m=o.map(l=>l[y]).filter(l=>l!=null);m.length>0&&(u=W(n,{[y]:{$in:m}}));}let d=await this.storage.get({resource:r,where:u,include:a,sort:s,limit:c});for(let m of t){let l=d;if(m.uniqueWhere){let[R,f]=Object.entries(m.uniqueWhere)[0];l=d.filter(p=>{var T;return ((T=p.value[R])==null?void 0:T.value)===f});}m.resolve(l);}}};var ve=b(te(),1);var _=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()}),re=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()})),rt=re.superRefine((i,t)=>{i.id&&t.addIssue({code:z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),Me=z.object({id:z.string().optional(),type:z.literal("MUTATE"),resource:z.string(),resourceId:z.string().optional()}),V=Me.extend({procedure:z.string(),payload:z.any().optional()}),q=Me.extend({procedure:z.enum(["INSERT","UPDATE"]),payload:rt});z.union([q,V]);var Ie=_.omit({resource:true}),ne=V.omit({id:true,type:true,resource:true,procedure:true}),ie=q.omit({id:true,type:true,resource:true,procedure:true});z.union([ie,ne]);var ae=i=>{if(i==null)return i;if(i==="null")return null;if(Array.isArray(i))return i.map(ae);if(typeof i=="object"&&i.constructor===Object){let t={};for(let[e,r]of Object.entries(i))t[e]=ae(r);return t}return i},Ae=i=>{let t=i.logger;return async e=>{var r;try{let n=typeof e.headers.getSetCookie=="function"?Object.fromEntries(e.headers):e.headers,a={headers:n,cookies:n.cookie?ve.default.parse(n.cookie):{}},s=new URL(e.url),c=s.pathname.split("/"),o=s.searchParams,u=ae(it.parse(o.toString())),y=await((r=i.contextProvider)==null?void 0:r.call(i,{transport:"HTTP",headers:a.headers,cookies:a.cookies,queryParams:u}))??{};if(e.method==="GET"){let d=c[c.length-1],{success:h,data:m,error:l}=Ie.safeParse(u);if(!h)return Response.json({message:"Invalid query",code:"INVALID_QUERY",details:l},{status:400});let R=await i.handleQuery({req:{...a,...m,type:"QUERY",resource:d,context:y,queryParams:u}});return !R||!R.data?Response.json({message:"Invalid resource",code:"INVALID_RESOURCE"},{status:400}):Response.json(R.data)}if(e.method==="POST")try{let d=c[c.length-1],h=c[c.length-2],m=e.body?await e.json():{},l;if(d==="insert"||d==="update"){let{success:f,data:p,error:T}=ie.safeParse(m);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:T},{status:400});l=p;}else {let{success:f,data:p,error:T}=ne.safeParse(m);if(!f)return Response.json({message:"Invalid mutation",code:"INVALID_REQUEST",details:T},{status:400});l=p;}let R=await i.handleMutation({req:{...a,type:"MUTATE",resource:h,input:l.payload,context:y,resourceId:l.resourceId,procedure:d==="insert"||d==="update"?d.toUpperCase():d,queryParams:{}}});return Response.json(R)}catch(d){return t.error("Error parsing mutation from the client:",d),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}return Response.json({message:"Not found",code:"NOT_FOUND"},{status:404})}catch(n){return t.error("Unexpected error:",n),Response.json({message:"Internal server error",code:"INTERNAL_SERVER_ERROR"},{status:500})}}};var je=b(te(),1);var D=z.string(),at=_.extend({id:D,type:z.literal("SUBSCRIBE")}),ot=_.extend({id:D,type:z.literal("QUERY")}),Ee=q.extend({id:D}),st=V.extend({id:D}),ct=z.union([st,Ee]),Le=z.union([at,ot,ct]),ut=z.object({id:D,type:z.literal("REJECT"),resource:z.string(),message:z.string().optional()}),dt=z.object({id:D,type:z.literal("REPLY"),data:z.any()});z.union([ut,dt,Ee]);z.object({resource:z.string(),data:z.array(re)});var Oe=i=>{let t={},e=i.logger;return (r,n)=>{var d;let a=h=>{r.send(JSON.stringify(h));},s=Z(),c=new Set,o={headers:n.headers,cookies:typeof n.headers.cookie=="string"?je.default.parse(n.headers.cookie):{}},u=parse(n.url.split("?")[1]),y=(d=i.contextProvider)==null?void 0:d.call(i,{transport:"WEBSOCKET",headers:o.headers,cookies:o.cookies,queryParams:u});t[s]=r,e.info("Client connected:",s),r.on("message",async h=>{var m;try{e.debug("Message received from the client:",h);let l=Le.parse(JSON.parse(h.toString()));if(l.type==="SUBSCRIBE"){let R=await y??{},f=l.resource,p=i.router.routes[f],T;if((m=p==null?void 0:p.authorization)!=null&&m.read){let x=p.authorization.read({ctx:R});T=typeof x=="object"?x:void 0;}c.add(i.subscribeToMutations(l,x=>{var w;!x.resourceId||!x.payload||!Object.keys(x.payload).length||(w=t[s])==null||w.send(JSON.stringify(x));},T));}else if(l.type==="QUERY"){let{resource:R}=l,f=await i.handleQuery({req:{...o,type:"QUERY",resource:R,context:await y??{},queryParams:u}});if(!f||!f.data)throw new Error("Invalid resource");a({id:l.id,type:"REPLY",data:{resource:R,data:(f.data??[]).map(p=>p.value)}});}else if(l.type==="MUTATE"){let{resource:R}=l;e.debug("Received mutation from client:",l);try{let f=await i.handleMutation({req:{...o,type:"MUTATE",resource:R,input:l.payload,context:{messageId:l.id,...await y??{}},resourceId:l.resourceId,procedure:l.procedure,queryParams:u}});l.procedure&&l.procedure!=="INSERT"&&l.procedure!=="UPDATE"&&a({id:l.id,type:"REPLY",data:f});}catch(f){a({id:l.id,type:"REJECT",resource:R,message:f.message}),e.error("Error parsing mutation from the client:",f);}}}catch(l){e.error("Error handling message from the client:",l);}}),r.on("close",()=>{e.info("Connection closed",s),delete t[s];for(let h of Array.from(c))h();});}};function Ce(i){let t=`${i.protocol}://${i.hostname}${i.url}`,e=new Headers;return Object.entries(i.headers).forEach(([r,n])=>{n&&e.set(r,Array.isArray(n)?n.join(","):n);}),new Request(t,{method:i.method,headers:e,body:i.body&&i.method!=="GET"?JSON.stringify(i.body):void 0})}var Ft=(i,t,e)=>{i.ws(`${(e==null?void 0:e.basePath)??""}/ws`,Oe(t)),i.use(`${(e==null?void 0:e.basePath)??""}/`,(r,n)=>{Ae(t)(Ce(r)).then(s=>s.json().then(c=>n.status(s.status).send(c)));});};var oe=class i{routes;constructor(t){this.routes=t.routes;}static create(t){return new i(t)}},Yt=i=>oe.create({...i}),yt=i=>({handler:t=>({inputValidator:i??z.undefined(),handler:t})}),se=class i{resourceSchema;middlewares;customMutations;authorization;constructor(t,e,r){this.resourceSchema=t,this.middlewares=new Set,this.customMutations=e??{},this.authorization=r;}use(...t){for(let e of t)this.middlewares.add(e);return this}withMutations(t){return new i(this.resourceSchema,t({mutation:yt}),this.authorization)}handleQuery=async({req:t,batcher:e})=>await this.wrapInMiddlewares(async r=>{var a,s;let n=(s=(a=this.authorization)==null?void 0:a.read)==null?void 0:s.call(a,{ctx:r.context});if(typeof n=="boolean"&&!n)throw new Error("Not authorized");return {data:await e.rawFind({resource:r.resource,commonWhere:W(r.where,typeof n=="object"?n:void 0),uniqueWhere:r.relationalWhere,include:r.include,limit:r.limit,sort:r.sort})}})(t);handleMutation=async({req:t,db:e,schema:r})=>await this.wrapInMiddlewares(async n=>{if(!n.procedure)throw new Error("Procedure is required for mutations");let a=this.customMutations[n.procedure];if(a){let s=a.inputValidator.parse(n.input);return n.input=s,a.handler({req:n,db:e})}else {if(n.procedure==="INSERT"||n.procedure==="UPDATE")return this.handleSet({req:n,db:e,operation:n.procedure,schema:r});throw new Error(`Unknown procedure: ${n.procedure}`)}})(t);handleSet=async({req:t$1,db:e,operation:r,schema:n})=>{if(!t$1.input)throw new Error("Payload is required");if(!t$1.resourceId)throw new Error("ResourceId is required");let a=await e.rawFindById(t$1.resource,t$1.resourceId);if(r==="INSERT"&&a)throw new Error("Resource already exists");if(r==="UPDATE"&&!a)throw new Error("Resource not found");return e.transaction(async({trx:s})=>{var y,d,h,m,l,R,f;let[c,o]=this.resourceSchema.mergeMutation("set",t$1.input,a);if(!o)throw new Error("Mutation rejected");if(r==="INSERT"){let p=await s.rawInsert(t$1.resource,t$1.resourceId,c,(y=t$1.context)==null?void 0:y.messageId),T=t(p);if(T.id=T.id??t$1.resourceId,(d=this.authorization)!=null&&d.insert){let x$1=this.authorization.insert({ctx:t$1.context,value:T});if(typeof x$1=="boolean"){if(!x$1)throw new Error("Not authorized")}else {let w$1=w(x$1,t$1.resource,n),S=Object.keys(w$1).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,w$1):p,b=t(S);if(b.id=b.id??t$1.resourceId,!x(b,x$1))throw new Error("Not authorized")}}return {data:p,acceptedValues:o}}if((m=(h=this.authorization)==null?void 0:h.update)!=null&&m.preMutation){let p=t(a);p.id=p.id??t$1.resourceId;let T=this.authorization.update.preMutation({ctx:t$1.context,value:p});if(typeof T=="boolean"){if(!T)throw new Error("Not authorized")}else {let x$1=w(T,t$1.resource,n),w$1=Object.keys(x$1).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,x$1):a,S=t(w$1);if(S.id=S.id??t$1.resourceId,!x(S,T))throw new Error("Not authorized")}}let u=await s.rawUpdate(t$1.resource,t$1.resourceId,c,(l=t$1.context)==null?void 0:l.messageId);if((f=(R=this.authorization)==null?void 0:R.update)!=null&&f.postMutation){let p=t(u);p.id=p.id??t$1.resourceId;let T=this.authorization.update.postMutation({ctx:t$1.context,value:p});if(typeof T=="boolean"){if(!T)throw new Error("Not authorized")}else {let x$1=w(T,t$1.resource,n),w$1=Object.keys(x$1).length>0?await s.rawFindById(t$1.resource,t$1.resourceId,x$1):u,S=t(w$1);if(S.id=S.id??t$1.resourceId,!x(S,T))throw new Error("Not authorized")}}return {data:u,acceptedValues:o}})};wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},ce=class i{middlewares;constructor(t=[]){this.middlewares=t;}collectionRoute(t,e){return new se(t,void 0,e).use(...this.middlewares)}use(...t){return new i([...this.middlewares,...t])}static create(){return new i}},Xt=ce.create;var Q=class{async insert(t$1,e){let r=new Date().toISOString();return t(await this.rawInsert(t$1.name,e.id,{value:Object.fromEntries(Object.entries(e).map(([n,a])=>[n,{value:a,_meta:{timestamp:r}}]))}))}async update(t$1,e,r){let n=new Date().toISOString(),{id:a,...s}=r;return t(await this.rawUpdate(t$1.name,e,{value:Object.fromEntries(Object.entries(s).map(([c,o])=>[c,{value:o,_meta:{timestamp:n}}]))}))}};function J(i,t,e,r){if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error("Resource not found");let a=r.$or,s=r.$and;return (a?e.or:e.and)(a?r.$or.map(c=>J(i,t,e,c)):s?r.$and.map(c=>J(i,t,e,c)):Object.entries(r).map(([c,o])=>{var u,y;if(n.fields[c])return (o==null?void 0:o.$eq)!==void 0?e(`${t}.${c}`,o.$eq===null?"is":"=",o.$eq):(o==null?void 0:o.$in)!==void 0?e(`${t}.${c}`,"in",o.$in):(o==null?void 0:o.$not)!==void 0?((u=o==null?void 0:o.$not)==null?void 0:u.$in)!==void 0?e(`${t}.${c}`,"not in",o.$not.$in):((y=o==null?void 0:o.$not)==null?void 0:y.$eq)!==void 0?e(`${t}.${c}`,o.$not.$eq===null?"is not":"!=",o.$not.$eq):e(`${t}.${c}`,o.$not===null?"is not":"!=",o.$not):(o==null?void 0:o.$gt)!==void 0?e(`${t}.${c}`,">",o.$gt):(o==null?void 0:o.$gte)!==void 0?e(`${t}.${c}`,">=",o.$gte):(o==null?void 0:o.$lt)!==void 0?e(`${t}.${c}`,"<",o.$lt):(o==null?void 0:o.$lte)!==void 0?e(`${t}.${c}`,"<=",o.$lte):e(`${t}.${c}`,o===null?"is":"=",o);if(n.relations[c]){let d=n.relations[c],h=d.entity.name;return d.type==="many"?e.exists(ue(i,h,e.selectFrom(h).select("id").whereRef(d.foreignColumn,"=",`${t}.id`),o)):J(i,h,e,o)}return null}).filter(Boolean))}function Y(i,t,e,r){let n=i[t];if(!n)throw new Error("Resource not found");if(!r)return e;if(r.$and){for(let a of r.$and)e=Y(i,t,e,a);return e}else if(r.$or){for(let a of r.$or)e=Y(i,t,e,a);return e}for(let[a,s]of Object.entries(r)){if(!n.relations[a])continue;let c=n.relations[a],o=c.entity.name,u=c.type==="one"?"id":c.foreignColumn,y=c.type==="one"?c.relationalColumn:"id";e=e.leftJoin(o,`${o}.${u}`,`${t}.${y}`),s instanceof Object&&!Array.isArray(s)&&s!==null&&(e=Y(i,o,e,s));}return e}function ue(i,t,e,r){return !r||Object.keys(r).length===0?e:(e=Y(i,t,e,r),e.where(n=>J(i,t,n,r)))}function X(i,t,e,r){if(!r)return e;if(!i)throw new Error("Schema not initialized");let n=i[t];if(!n)throw new Error(`Resource not found: ${t}`);for(let a of Object.keys(r)){if(!n.relations[a])throw new Error(`Relation ${a} not found in resource ${t}`);let s=n.relations[a],c=s.entity.name,o=r[a],u=s.type==="one"?"id":s.foreignColumn,y=s.type==="one"?s.relationalColumn:"id",d=s.type==="one"?jsonObjectFrom:jsonArrayFrom,h=typeof o=="object"&&o!==null;e=e.select(m=>{let l=m.selectFrom(c).selectAll(c).whereRef(`${c}.${u}`,"=",`${t}.${y}`).select(R=>jsonObjectFrom(R.selectFrom(`${c}_meta`).selectAll(`${c}_meta`).whereRef(`${c}_meta.id`,"=",`${c}.id`)).as("_meta"));return h&&(l=X(i,c,l,o)),d(l).as(a)});}return e}var ke="42701",de=class i extends Q{db;schema;logger;server;mutationStack=[];constructor(t,e,r,n){super(),this.isKyselyLike(t)?this.db=t:this.db=new Kysely({dialect:new PostgresDialect({pool:t})}),this.schema=e,this.logger=r,this.server=n,this.rawInsert=this.rawInsert.bind(this),this.rawUpdate=this.rawUpdate.bind(this);}async init(t,e,r){var a;this.schema=t,this.logger=e,this.server=r;let n=await this.db.introspection.getTables();for(let[s,c]of Object.entries(t)){let o=n.find(d=>d.name===s);o||await this.db.schema.createTable(s).ifNotExists().execute();let u=`${s}_meta`,y=n.find(d=>d.name===u);y||await this.db.schema.createTable(u).ifNotExists().execute();for(let[d,h]of Object.entries(c.fields)){let m=o==null?void 0:o.columns.find(f=>f.name===d),l=h.getStorageFieldType();m?m.dataType!==l.type&&((a=this.logger)==null||a.warn("Column type mismatch:",d,"expected to have type:",l.type,"but has type:",m.dataType)):(await this.db.schema.alterTable(s).addColumn(d,l.type,f=>{let p=f;return l.unique&&(p=p.unique()),l.nullable||(p=p.notNull()),l.references&&(p=p.references(l.references)),l.primary&&(p=p.primaryKey()),l.default!==void 0&&(p=p.defaultTo(l.default)),p}).execute().catch(f=>{var p;if(f.code!==ke)throw (p=this.logger)==null||p.error("Error adding column",d,f),f}),l.index&&await this.db.schema.createIndex(`${s}_${d}_index`).on(s).column(d).execute().catch(()=>{})),(y==null?void 0:y.columns.find(f=>f.name===d))||await this.db.schema.alterTable(u).addColumn(d,"varchar",f=>{let p=f;return l.primary&&(p=p.primaryKey().references(`${s}.${d}`)),p}).execute().catch(f=>{var p;if(f.code!==ke)throw (p=this.logger)==null||p.error("Error adding meta column",d,f),f});}}}async rawFindById(t,e,r){if(!this.schema)throw new Error("Schema not initialized");let n=await this.db.selectFrom(t).where("id","=",e).selectAll(t).select(s=>jsonObjectFrom(s.selectFrom(`${t}_meta`).selectAll(`${t}_meta`).whereRef(`${t}_meta.id`,"=",`${t}.id`)).as("_meta"));n=X(this.schema,t,n,r);let a=await n.executeTakeFirst();if(a)return this.convertToMaterializedLiveType(a)}async findOne(t$1,e,r){let n=await this.rawFindById(t$1.name,e,r==null?void 0:r.include);if(n)return t(n)}async get(t){if(!this.schema)throw new Error("Schema not initialized");let{resource:e,where:r,include:n,limit:a,sort:s}=t,c=this.db.selectFrom(e).selectAll(e).select(u=>jsonObjectFrom(u.selectFrom(`${e}_meta`).selectAll(`${e}_meta`).whereRef(`${e}_meta.id`,"=",`${e}.id`)).as("_meta"));c=ue(this.schema,e,c,r),c=X(this.schema,e,c,n),a!==void 0&&(c=c.limit(a)),s!==void 0&&s.forEach(u=>{c=c.orderBy(u.key,u.direction);});let o=await c.execute();return o.length===0?[]:o.map(u=>this.convertToMaterializedLiveType(u))}async find(t$1,e){return (await this.get({resource:t$1.name,where:e==null?void 0:e.where,include:e==null?void 0:e.include,limit:e==null?void 0:e.limit,sort:e==null?void 0:e.sort})).map(n=>t(n))}async rawInsert(t,e,r,n){var o;let a={},s={};for(let[u,y]of Object.entries(r.value)){let d=(o=y._meta)==null?void 0:o.timestamp;d&&(a[u]=y.value,s[u]=d);}await this.db.insertInto(t).values({...a,id:e}).execute().then(()=>{this.db.insertInto(`${t}_meta`).values({...s,id:e}).execute();});let c=this.buildMutation(t,e,"INSERT",r,n);return c&&this.trackMutation(c,r),r}async rawUpdate(t,e,r,n){var o;let a={},s={};for(let[u,y]of Object.entries(r.value)){let d=(o=y._meta)==null?void 0:o.timestamp;d&&(a[u]=y.value,s[u]=d);}await Promise.all([this.db.updateTable(t).set(a).where("id","=",e).execute(),this.db.insertInto(`${t}_meta`).values({...s,id:e}).onConflict(u=>u.column("id").doUpdateSet(s)).execute()]);let c=this.buildMutation(t,e,"UPDATE",r,n);return c&&this.trackMutation(c,r),r}async transaction(t){if(!this.schema)throw new Error("Schema not initialized");if(this.db.isTransaction){let a=Math.random().toString(36).substring(2,15),s=this.mutationStack,c=[];this.mutationStack=c;let o=await this.db.savepoint(a).execute();try{return await t({trx:this,commit:async()=>{await o.releaseSavepoint(a).execute(),s.push(...c);},rollback:async()=>{await o.rollbackToSavepoint(a).execute(),c.length=0;}}).then(u=>o.isCommitted||o.isRolledBack?u:o.releaseSavepoint(a).execute().then(()=>(s.push(...c),u)))}catch(u){throw await o.rollbackToSavepoint(a).execute().catch(()=>{}),c.length=0,u}finally{this.mutationStack=s;}}let e=[],r=this.mutationStack;this.mutationStack=e;let n=await this.db.startTransaction().execute();try{let a=new i(n,this.schema,this.logger,this.server);return a.mutationStack=e,await t({trx:a,commit:async()=>{await n.commit().execute(),this.notifyMutations(e);},rollback:async()=>{await n.rollback().execute(),e.length=0;}}).then(s=>n.isCommitted||n.isRolledBack?s:n.commit().execute().then(()=>(this.notifyMutations(e),s)))}catch(a){throw await n.rollback().execute(),e.length=0,a}finally{this.mutationStack=r;}}get internalDB(){return this.db}convertToMaterializedLiveType(t){return {value:Object.entries(t).reduce((e,[r,n])=>{var a,s,c;return r==="_meta"||(r==="id"?e[r]={value:n}:Array.isArray(n)?e[r]={value:n.map(o=>this.convertToMaterializedLiveType(o)),_meta:{timestamp:(a=t==null?void 0:t._meta)==null?void 0:a[r]}}:typeof n=="object"&&n!==null&&!(n instanceof Date)?e[r]={...this.convertToMaterializedLiveType(n),_meta:{timestamp:(s=t==null?void 0:t._meta)==null?void 0:s[r]}}:e[r]={value:n,_meta:{timestamp:(c=t==null?void 0:t._meta)==null?void 0:c[r]}}),e},{})}}isKyselyLike(t){if(t instanceof Kysely)return true;if(!t||typeof t!="object")return false;let e=t,r=typeof e.selectFrom=="function",n=typeof e.startTransaction=="function",a=typeof e.savepoint=="function",s=typeof e.isTransaction=="boolean"||typeof e.isTransaction=="function";return r&&n||a&&s}buildMutation(t,e,r,n,a){var c;let s={};for(let[o,u]of Object.entries(n.value)){if(o==="id")continue;let y=(c=u._meta)==null?void 0:c.timestamp;y&&(s[o]={value:u.value,_meta:{timestamp:y}});}return Object.keys(s).length===0?null:{id:a??Z(),type:"MUTATE",resource:t,resourceId:e,procedure:r,payload:s}}trackMutation(t,e){this.db.isTransaction?this.mutationStack.push({mutation:t,entityData:e}):this.notifyMutations([t],e);}notifyMutations(t,e){if(this.server)if(e!==void 0){let r=t;for(let n of r)this.server.notifySubscribers(n,e);}else {let r=t;for(let{mutation:n,entityData:a}of r)this.server.notifySubscribers(n,a);}}};var le=class i{router;storage;schema;middlewares=new Set;logger;contextProvider;mutationSubscriptions=new Set;collectionSubscriptions=new Map;constructor(t){var e;this.router=t.router,this.storage=t.storage,this.schema=t.schema,this.logger=z$1({level:t.logLevel??y.INFO}),(e=t.middlewares)==null||e.forEach(r=>{this.middlewares.add(r);}),this.storage.init(this.schema,this.logger,this),this.contextProvider=t.contextProvider;}static create(t){return new i(t)}handleQuery(t){let e=new K(this.storage);return this.wrapInMiddlewares(async r=>{var m,l,R,f,p,T,x;let n=Ne(r,this.schema,{stepId:"query",collectionName:r.resource,included:Object.keys(r.include??{})}),a={headers:r.headers,cookies:r.cookies,queryParams:r.queryParams,context:r.context},s={};for(let w=0;w<n.length;w++){let S=n[w],b=this.router.routes[S.resource];if(!b)throw new Error("Invalid resource");let A;if(S.getWhere&&S.referenceGetter){let M=S.referenceGetter(s);A=[];for(let I=0;I<M.length;I++)A.push(S.getWhere(M[I]));}else A=[void 0];let L=s[S.prevStepId??""],j=[];if(L)for(let M=0;M<L.length;M++){let I=L[M],z=((m=I==null?void 0:I.result)==null?void 0:m.data)??[];for(let C=0;C<z.length;C++){let ee=z[C],ye=(R=(l=ee==null?void 0:ee.value)==null?void 0:l.id)==null?void 0:R.value;ye&&j.push(ye);}}let $=[];for(let M=0;M<A.length;M++){let I=A[M],z=j[M];$.push((async()=>{let C=await b.handleQuery({req:{type:"QUERY",...S,...a,where:S.where,relationalWhere:I},batcher:e});return {includedBy:z,result:C}})());}let O=await Promise.allSettled($),U=[];for(let M=0;M<O.length;M++){let I=O[M];I.status==="fulfilled"&&U.push(I.value);}s[S.stepId]=U;}let c=new Map,o=0;for(let w in s){let S=s[w],b=n[o];o++;for(let A=0;A<S.length;A++){let L=S[A],j=L.result.data;for(let $=0;$<j.length;$++){let O=j[$],U=(p=(f=O==null?void 0:O.value)==null?void 0:f.id)==null?void 0:p.value;if(!U)continue;let M=`${w}.${U}`,I=[];w!=="query"&&L.includedBy&&(I=[`${b.prevStepId}.${L.includedBy}`]);let z=c.get(M);if(z)for(let C=0;C<I.length;C++)z.includedBy.add(I[C]);else c.set(M,{data:O,includedBy:new Set(I),path:w.split(".").slice(-1)[0],isMany:b.isMany??false,collectionName:b.collectionName,included:b.included});}}}let u=Object.fromEntries(c),y={data:[]},d=Object.keys(u);for(let w=d.length-1;w>=0;w--){let S=d[w],b=u[S],A=b.path;if(A==="query"&&y.data.push(b.data),b.included.length)for(let L=0;L<b.included.length;L++){let j=b.included[L];b.data.value[j]??=((x=(T=this.schema[b.collectionName])==null?void 0:T.relations[j])==null?void 0:x.type)==="many"?{value:[]}:{value:null};}if(b.includedBy.size>0){let L=Array.from(b.includedBy);for(let j=0;j<L.length;j++){let $=L[j],O=u[$];O&&(b.isMany?(O.data.value[A]??={value:[]},O.data.value[A].value.push(b.data)):O.data.value[A]=b.data);}}}return y})(t.req)}async handleMutation(t){let e=await this.wrapInMiddlewares(async r=>{let n=this.router.routes[r.resource];if(!n)throw new Error("Invalid resource");return n.handleMutation({req:r,db:this.storage,schema:this.schema})})(t.req);if(e&&t.req.type==="MUTATE"&&e.acceptedValues&&(t.req.procedure==="INSERT"||t.req.procedure==="UPDATE")&&t.req.resourceId){let n=e.acceptedValues??{},a=t.req,s=a.resourceId;Object.keys(n).length&&s&&this.mutationSubscriptions.forEach(c=>{c({id:t.req.context.messageId,type:"MUTATE",resource:a.resource,payload:n,resourceId:s,procedure:a.procedure});});}return e}use(t){return this.middlewares.add(t),this}context(t){return this.contextProvider=t,this}subscribeToMutations(t,e,r){let n=t.resource,a={query:t,authorizationWhere:r},s=v(a),c=this.collectionSubscriptions.get(n);c||(c=new Map,this.collectionSubscriptions.set(n,c));let o=c.get(s);return o?(o.callbacks.add(e),r!==void 0&&(o.authorizationWhere=r)):c.set(s,{callbacks:new Set([e]),...a}),()=>{var y,d;let u=this.collectionSubscriptions.get(n);u&&((y=u.get(s))==null||y.callbacks.delete(e),((d=u.get(s))==null?void 0:d.callbacks.size)===0&&u.delete(s));}}notifySubscribers(t$1,e){let r=t$1.resource,n=this.collectionSubscriptions.get(r);if(n&&e)for(let a of Array.from(n.values())){let s=pe(a.query.where,this.schema[r]),c=W(s,a.authorizationWhere),o=t(e);if(!o)continue;(t$1.resourceId&&typeof o=="object"&&o!==null&&!("id"in o)||t$1.resourceId&&typeof o=="object"&&o!==null&&o.id!==t$1.resourceId)&&(o.id=t$1.resourceId);let u=Object.keys(c).length>0,y=true;u&&(y=x(o,c)),y&&a.callbacks.forEach(d=>{var h;try{d(t$1);}catch(m){(h=this.logger)==null||h.error(`Error in mutation subscription for resource ${r}:`,m);}});}}wrapInMiddlewares(t){return e=>Array.from(this.middlewares.values()).reduceRight((r,n)=>a=>n({req:a,next:r}),t)(e)}},Rr=le.create;function Ne(i,t,e){let{include:r,where:n,...a}=i,{stepId:s}=e,c=[{...a,...e,where:n}];if(r&&typeof r=="object"&&Object.keys(r).length>0){let o=t[a.resource];if(!o)throw new Error(`Resource ${a.resource} not found`);c.push(...Object.entries(r).flatMap(([u,y])=>{let d=o.relations[u];if(!d)throw new Error(`Relation ${u} not found for resource ${a.resource}`);let h=d.entity.name;return Ne({...a,resource:h,include:y},t,{getWhere:d.type==="one"?m=>({id:m}):m=>({[d.foreignColumn]:m}),referenceGetter:m=>m[s].flatMap(l=>{let R=l.result.data??[];return d.type==="one"?R.map(f=>{var p,T;return (T=(p=f.value)==null?void 0:p[d.relationalColumn])==null?void 0:T.value}).filter(f=>f!==void 0):R.map(f=>{var p,T;return (T=(p=f.value)==null?void 0:p.id)==null?void 0:T.value}).filter(f=>f!==void 0)}),stepId:`${s}.${u}`,prevStepId:s,isMany:d.type==="many",collectionName:h,included:typeof y=="object"?Object.keys(y):[]})}));}return c}function pe(i,t){if(!i||!t||Object.keys(i).length===0)return i;if(i.$and){let r=i.$and.map(n=>pe(n,t)).filter(n=>!!n&&Object.keys(n).length>0);return r.length===0?void 0:r.length===1?r[0]:{$and:r}}if(i.$or){let r=i.$or.map(n=>pe(n,t)).filter(n=>!!n&&Object.keys(n).length>0);return r.length===0?void 0:r.length===1?r[0]:{$or:r}}let e={};for(let[r,n]of Object.entries(i))t.fields[r]&&(e[r]=n);return Object.keys(e).length>0?e:void 0}
|
|
2
|
+
export{se as Route,ce as RouteFactory,oe as Router,de as SQLStorage,le as Server,Q as Storage,Ft as expressAdapter,Xt as routeFactory,Yt as router,Rr as server};
|