@live-state/sync 0.0.1-alpha.2 → 0.0.1-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ var R="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var c;(function(e){e.Base32IncorrectEncoding="B32_ENC_INVALID",e.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",e.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",e.EncodeTimeNegative="ENC_TIME_NEG",e.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",e.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",e.PRNGDetectFailure="PRNG_DETECT",e.ULIDInvalid="ULID_INVALID",e.Unexpected="UNEXPECTED",e.UUIDInvalid="UUID_INVALID";})(c||(c={}));var l=class extends Error{constructor(t,n){super(`${n} (${t})`),this.name="ULIDError",this.code=t;}};function L(e){let t=Math.floor(e()*32);return t===32&&(t=31),R.charAt(t)}function I(e){let t=M(),n=t&&(t.crypto||t.msCrypto)||null;if(typeof(n==null?void 0:n.getRandomValues)=="function")return ()=>{let i=new Uint8Array(1);return n.getRandomValues(i),i[0]/255};if(typeof(n==null?void 0:n.randomBytes)=="function")return ()=>n.randomBytes(1).readUInt8()/255;throw new l(c.PRNGDetectFailure,"Failed to find a reliable PRNG")}function M(){return A()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function E(e,t){let n="";for(;e>0;e--)n=L(t)+n;return n}function _(e,t=10){if(isNaN(e))throw new l(c.EncodeTimeValueMalformed,`Time must be a number: ${e}`);if(e>0xffffffffffff)throw new l(c.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${0xffffffffffff}: ${e}`);if(e<0)throw new l(c.EncodeTimeNegative,`Time must be positive: ${e}`);if(Number.isInteger(e)===false)throw new l(c.EncodeTimeValueMalformed,`Time must be an integer: ${e}`);let n,i="";for(let a=t;a>0;a--)n=e%32,i=R.charAt(n)+i,e=(e-n)/32;return i}function A(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function x(e,t){let n=I(),i=Date.now();return _(i,10)+E(16,n)}var S=()=>x().toLowerCase(),j=(e,t)=>typeof e=="function"?e(t):e;var b=e=>{if(e)return Array.isArray(e.value)?e.value.map(t=>b(t)):typeof e.value!="object"?e.value:Object.fromEntries(Object.entries(e.value).map(([t,n])=>[t,b(n)]))};var w=(e,t,n=[])=>new Proxy(e,{get:(i,a)=>{var y,h;if(a==="__isProxy__")return true;let r=(y=t.get)==null?void 0:y.call(t,i,[...n,a]);if(r!==void 0)return r;let o=i,s=a;return (h=o[s])!=null&&h.__isProxy__||(o[s]=w(typeof o[s]=="object"?o[s]:function(){},t,[...n,a])),o[s]},apply:(i,a,r)=>{var o;return (o=t.apply)==null?void 0:o.call(t,i,n,r)}});export{S as a,j as b,b as c,w as d};
package/dist/client.d.ts CHANGED
@@ -1,333 +1,3 @@
1
- import { ZodTypeAny, z } from 'zod';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
-
4
- type Promisify<T> = T extends Promise<any> ? T : Promise<T>;
5
-
6
- type LiveTypeMeta = {};
7
- type MutationType = "set";
8
- type StorageFieldType = {
9
- type: string;
10
- nullable: boolean;
11
- default?: any;
12
- unique?: boolean;
13
- index?: boolean;
14
- primary?: boolean;
15
- references?: string;
16
- };
17
- declare abstract class LiveType<Value = any, Meta extends LiveTypeMeta = LiveTypeMeta, EncodeInput = Partial<Value> | Value, DecodeInput = {
18
- value: Value;
19
- _meta: keyof Meta extends never ? never : Meta;
20
- }> {
21
- readonly _value: Value;
22
- readonly _meta: Meta;
23
- readonly _encodeInput: EncodeInput;
24
- readonly _decodeInput: DecodeInput;
25
- abstract encodeMutation(mutationType: MutationType, input: EncodeInput, timestamp: string): DecodeInput;
26
- /**
27
- * Merges the materialized shape with the encoded mutation
28
- * @param mutationType The type of mutation
29
- * @param encodedMutation The encoded mutation
30
- * @param materializedShape The materialized shape
31
- * @returns A tuple of the new materialized shape and the accepted diff
32
- */
33
- abstract mergeMutation(mutationType: MutationType, encodedMutation: DecodeInput, materializedShape?: MaterializedLiveType<LiveType<Value, Meta>>): [MaterializedLiveType<LiveType<Value, Meta>>, DecodeInput | null];
34
- abstract getStorageFieldType(): StorageFieldType;
35
- }
36
- type LiveTypeAny = LiveType<any, LiveTypeMeta, any, any>;
37
- type InferLiveType<T extends LiveTypeAny> = T["_value"] extends Record<string, LiveTypeAny> ? {
38
- [K in keyof T["_value"]]: InferLiveType<T["_value"][K]>;
39
- } : T["_value"];
40
- type InferIndex<T extends LiveTypeAny> = string;
41
-
42
- declare class OptionalLiveType<T extends LiveTypeAny> extends LiveType<T["_value"] | undefined, T["_meta"], T["_encodeInput"], T["_decodeInput"]> {
43
- readonly inner: T;
44
- constructor(inner: T);
45
- encodeMutation(mutationType: MutationType, input: T["_value"] | undefined, timestamp: string): T["_decodeInput"];
46
- mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] | undefined, T["_meta"], T["_value"] | Partial<T["_value"] | undefined>, T["_decodeInput"]>> | undefined): [
47
- MaterializedLiveType<LiveType<T["_value"] | undefined, T["_meta"], T["_value"] | Partial<T["_value"] | undefined>, T["_decodeInput"]>>,
48
- T["_decodeInput"] | null
49
- ];
50
- getStorageFieldType(): StorageFieldType;
51
- }
52
- type LiveAtomicTypeMeta = {
53
- timestamp: string;
54
- } & LiveTypeMeta;
55
- declare class LiveAtomicType<Value> extends LiveType<Value, LiveAtomicTypeMeta, Value, {
56
- value: Value;
57
- _meta: LiveAtomicTypeMeta;
58
- }> {
59
- readonly storageType: string;
60
- readonly convertFunc?: (value: any) => Value;
61
- readonly isIndex: boolean;
62
- readonly isUnique: boolean;
63
- readonly defaultValue?: Value;
64
- readonly foreignReference?: string;
65
- readonly isPrimary: boolean;
66
- constructor(storageType: string, convertFunc?: (value: any) => Value, index?: boolean, unique?: boolean, defaultValue?: Value, references?: string, primary?: boolean);
67
- encodeMutation(mutationType: MutationType, input: Value, timestamp: string): {
68
- value: Value;
69
- _meta: LiveAtomicTypeMeta;
70
- };
71
- mergeMutation(mutationType: MutationType, encodedMutation: {
72
- value: Value;
73
- _meta: LiveAtomicTypeMeta;
74
- }, materializedShape?: MaterializedLiveType<LiveType<Value, LiveAtomicTypeMeta, Value | Partial<Value>, {
75
- value: Value;
76
- _meta: LiveAtomicTypeMeta;
77
- }>>): [
78
- MaterializedLiveType<LiveType<Value, LiveAtomicTypeMeta, Value | Partial<Value>, {
79
- value: Value;
80
- _meta: LiveAtomicTypeMeta;
81
- }>>,
82
- {
83
- value: Value;
84
- _meta: LiveAtomicTypeMeta;
85
- } | null
86
- ];
87
- getStorageFieldType(): StorageFieldType;
88
- unique(): LiveAtomicType<Value>;
89
- index(): LiveAtomicType<Value>;
90
- default(value: Value): LiveAtomicType<Value>;
91
- primary(): LiveAtomicType<Value>;
92
- optional(): OptionalLiveType<this>;
93
- }
94
- declare class LiveString extends LiveAtomicType<string> {
95
- private constructor();
96
- static create(): LiveString;
97
- static createId(): LiveAtomicType<string>;
98
- static createReference(foreignField: `${string}.${string}`): LiveString;
99
- }
100
-
101
- type InferLiveObjectWithoutRelations<T extends LiveObjectAny> = {
102
- [K in keyof T["fields"]]: InferLiveType<T["fields"][K]>;
103
- };
104
- type InferLiveObject<T extends LiveObjectAny> = InferLiveObjectWithoutRelations<T> & {
105
- [K in keyof T["relations"]]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
106
- };
107
- type InferRelationalColumns<T extends Record<string, RelationAny>> = {
108
- [K in keyof T as T[K] extends Relation<any, any, any, infer ColumnName, any, any> ? ColumnName extends string ? ColumnName : never : never]: T[K]["type"] extends "one" ? T[K] extends Relation<infer Entity, any, any, any, any, any> ? T[K]["required"] extends true ? InferIndex<Entity> : InferIndex<Entity> | undefined : never : never;
109
- };
110
- type InferLiveObjectWithRelationalIds<T extends LiveObjectAny> = keyof T["relations"] extends string ? InferLiveObjectWithoutRelations<T> & InferRelationalColumns<T["relations"]> : InferLiveObjectWithoutRelations<T>;
111
- type LiveObjectMutationInput<TSchema extends LiveObjectAny> = Partial<InferLiveObjectWithRelationalIds<TSchema>>;
112
- declare class LiveObject<TName extends string, TSchema extends Record<string, LiveTypeAny>, TRelations extends Record<string, RelationAny>> extends LiveType<TSchema, LiveTypeMeta, LiveObjectMutationInput<any>, Record<string, MaterializedLiveType<LiveTypeAny>>> {
113
- readonly name: TName;
114
- readonly fields: TSchema;
115
- readonly relations: TRelations;
116
- constructor(name: TName, fields: TSchema, relations?: TRelations);
117
- encodeMutation(_mutationType: MutationType, input: LiveObjectMutationInput<this>, timestamp: string): Record<string, any>;
118
- mergeMutation(mutationType: MutationType, encodedMutations: Record<string, MaterializedLiveType<LiveTypeAny>>, materializedShape?: MaterializedLiveType<this> | undefined): [MaterializedLiveType<this>, Record<string, any> | null];
119
- setRelations<TRelations extends Record<string, RelationAny>>(relations: TRelations): LiveObject<this["name"], this["fields"], TRelations>;
120
- getStorageFieldType(): StorageFieldType;
121
- static create<TName extends string, TSchema extends Record<string, LiveTypeAny>>(name: TName, schema: TSchema): LiveObject<TName, TSchema, never>;
122
- }
123
- type LiveObjectAny = LiveObject<string, Record<string, LiveTypeAny>, any>;
124
- declare class Relation<TEntity extends LiveObjectAny, TSourceEntity extends LiveObjectAny, TType extends "one" | "many", TRelationalColumn extends keyof TSourceEntity["fields"], TForeignColumn extends keyof TEntity["fields"], TRequired extends boolean> extends LiveType<InferIndex<TEntity>, {
125
- timestamp: string;
126
- } & LiveTypeMeta> {
127
- readonly entity: TEntity;
128
- readonly type: TType;
129
- readonly required: TRequired;
130
- readonly relationalColumn?: TRelationalColumn;
131
- readonly foreignColumn?: TForeignColumn;
132
- readonly sourceEntity: TSourceEntity;
133
- private constructor();
134
- encodeMutation(mutationType: MutationType, input: string, timestamp: string): {
135
- value: string;
136
- _meta: {
137
- timestamp: string;
138
- };
139
- };
140
- mergeMutation(mutationType: MutationType, encodedMutation: {
141
- value: string;
142
- _meta: {
143
- timestamp: string;
144
- };
145
- }, materializedShape?: MaterializedLiveType<LiveString> | undefined): [
146
- MaterializedLiveType<LiveString>,
147
- {
148
- value: string;
149
- _meta: {
150
- timestamp: string;
151
- };
152
- } | null
153
- ];
154
- getStorageFieldType(): StorageFieldType;
155
- static createOneFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TOriginEntity["fields"], TRequired extends boolean = false>(entity: TEntity, column: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "one", TColumn, never, TRequired>;
156
- static createManyFactory<TOriginEntity extends LiveObjectAny>(): <TEntity extends LiveObjectAny, TColumn extends keyof TEntity["fields"], TRequired extends boolean = false>(entity: TEntity, foreignColumn: TColumn, required?: TRequired) => Relation<TEntity, TOriginEntity, "many", never, TColumn, TRequired>;
157
- }
158
- type RelationAny = Relation<LiveObjectAny, LiveObjectAny, any, any, any, any>;
159
- type MaterializedLiveType<T extends LiveTypeAny> = {
160
- value: T["_value"] extends Record<string, LiveTypeAny> ? {
161
- [K in keyof T["_value"]]: MaterializedLiveType<T["_value"][K]>;
162
- } : T["_value"];
163
- _meta: T["_meta"];
164
- };
165
- type ExtractObjectValues<T> = T[keyof T];
166
- type RelationsDecl<TObjectName extends string = string, TRelations extends Record<string, RelationAny> = Record<string, RelationAny>> = {
167
- $type: "relations";
168
- objectName: TObjectName;
169
- relations: TRelations;
170
- };
171
- type ParseRelationsFromSchema<TRawSchema extends RawSchema, TObjectName extends string> = ExtractObjectValues<{
172
- [K in keyof TRawSchema]: TRawSchema[K] extends RelationsDecl<infer TObjectName_, any> ? TObjectName_ extends TObjectName ? {
173
- [K2 in keyof TRawSchema[K]["relations"]]: Relation<ParseObjectFromSchema<TRawSchema, TRawSchema[K]["relations"][K2]["entity"]["name"]>, TRawSchema[K]["relations"][K2]["sourceEntity"], TRawSchema[K]["relations"][K2]["type"], Exclude<TRawSchema[K]["relations"][K2]["relationalColumn"], undefined>, Exclude<TRawSchema[K]["relations"][K2]["foreignColumn"], undefined>, TRawSchema[K]["relations"][K2]["required"]>;
174
- } : never : never;
175
- }>;
176
- type ParseObjectFromSchema<TRawSchema extends RawSchema, TObjectName extends string> = ExtractObjectValues<{
177
- [K in keyof TRawSchema]: TRawSchema[K] extends LiveObjectAny ? TRawSchema[K]["name"] extends TObjectName ? LiveObject<TRawSchema[K]["name"], TRawSchema[K]["fields"], ParseRelationsFromSchema<TRawSchema, TRawSchema[K]["name"]>> : never : never;
178
- }>;
179
- type RawSchema = Record<string, LiveObjectAny | RelationsDecl>;
180
- type Schema<TRawSchema extends RawSchema> = {
181
- [K in keyof TRawSchema as TRawSchema[K] extends LiveObjectAny ? TRawSchema[K]["name"] : never]: TRawSchema[K] extends LiveObjectAny ? ParseObjectFromSchema<TRawSchema, TRawSchema[K]["name"]> : never;
182
- };
183
-
184
- type RouteRecord = Record<string, AnyRoute>;
185
- declare class Router<TRoutes extends RouteRecord> {
186
- readonly routes: TRoutes;
187
- private constructor();
188
- static create<TRoutes extends RouteRecord>(opts: {
189
- routes: TRoutes;
190
- }): Router<TRoutes>;
191
- }
192
- type AnyRouter = Router<RouteRecord>;
193
- type RequestHandler<TInput, TResult, TSchema extends Schema<any> = Schema<any>> = (opts: {
194
- req: Request<TInput>;
195
- db: Storage;
196
- schema: TSchema;
197
- }) => Promise<TResult>;
198
- type Mutation<TInputValidator extends ZodTypeAny, // TODO use StandardSchema instead
199
- THandler extends RequestHandler<z.infer<TInputValidator>, any, any>> = {
200
- inputValidator: TInputValidator;
201
- handler: THandler;
202
- };
203
- declare const mutationCreator: <TInputValidator extends ZodTypeAny>(validator?: TInputValidator) => {
204
- handler: <THandler extends RequestHandler<z.infer<TInputValidator>, any, any>>(handler: THandler) => Mutation<TInputValidator, THandler>;
205
- };
206
- declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, RequestHandler<any, any>>>> {
207
- readonly _resourceSchema: TResourceSchema;
208
- readonly resourceName: TResourceSchema["name"];
209
- readonly middlewares: Set<TMiddleware>;
210
- readonly customMutations: TCustomMutations;
211
- constructor(resourceName: TResourceSchema["name"], customMutations?: TCustomMutations);
212
- private handleFind;
213
- private handleSet;
214
- handleRequest(opts: {
215
- req: Request;
216
- db: Storage;
217
- schema: Schema<any>;
218
- }): Promise<any>;
219
- use(middleware: TMiddleware): this;
220
- withMutations<T extends Record<string, Mutation<any, RequestHandler<any, any>>>>(mutationFactory: (opts: {
221
- mutation: typeof mutationCreator;
222
- }) => T): Route<TResourceSchema, TMiddleware, T>;
223
- }
224
- type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>>;
225
-
226
- declare abstract class Storage {
227
- abstract updateSchema(opts: Schema<any>): Promise<void>;
228
- abstract findById<T extends LiveObjectAny>(resourceName: string, id: string): Promise<MaterializedLiveType<T> | undefined>;
229
- abstract find<T extends LiveObjectAny>(resourceName: string, where?: Record<string, any>): Promise<Record<string, MaterializedLiveType<T>>>;
230
- abstract upsert<T extends LiveObjectAny>(resourceName: string, resourceId: string, value: MaterializedLiveType<T>): Promise<MaterializedLiveType<T>>;
231
- }
232
-
233
- type Request<TInput = any> = {
234
- headers: Record<string, string>;
235
- cookies: Record<string, string>;
236
- resourceName: string;
237
- procedure?: string;
238
- context: Record<string, any>;
239
- where?: Record<string, any>;
240
- type: "QUERY" | "MUTATE";
241
- resourceId?: string;
242
- input?: TInput;
243
- };
244
- type NextFunction<T> = (req: Request) => Promise<T> | T;
245
- type Middleware<T> = (opts: {
246
- req: Request;
247
- next: NextFunction<T>;
248
- }) => ReturnType<NextFunction<T>>;
249
-
250
- type Simplify<T> = T extends Record<string, any> ? {
251
- [K in keyof T]: Simplify<T[K]>;
252
- } : T;
253
-
254
- type Observable<T> = {
255
- [K in keyof T]: Observable<T[K]>;
256
- } & {
257
- get: () => T;
258
- subscribe: (callback: (value: T) => void) => () => void;
259
- subscribeToRemote: () => () => void;
260
- };
261
-
262
- type WebSocketClientEventMap = WebSocketEventMap & {
263
- connectionChange: {
264
- open: boolean;
265
- };
266
- };
267
- declare class WebSocketClient {
268
- private ws;
269
- private url;
270
- private autoConnect;
271
- private autoReconnect;
272
- private reconnectTimeout;
273
- private reconnectLimit?;
274
- private reconnectAttempts;
275
- private eventListeners;
276
- private reconnectTimer;
277
- private intentionallyDisconnected;
278
- constructor(options: {
279
- url: string;
280
- autoConnect?: boolean;
281
- autoReconnect?: boolean;
282
- reconnectTimeout?: number;
283
- reconnectLimit?: number;
284
- });
285
- connected(): boolean;
286
- connect(): void;
287
- disconnect(): void;
288
- addEventListener<K extends keyof WebSocketClientEventMap>(event: K, callback: (event: WebSocketClientEventMap[K]) => void): void;
289
- removeEventListener<K extends keyof WebSocketClientEventMap>(event: K, callback: (event: WebSocketClientEventMap[K]) => void): void;
290
- send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
291
- private handleOpen;
292
- private handleClose;
293
- private handleError;
294
- private handleMessage;
295
- private scheduleReconnect;
296
- private dispatchEvent;
297
- }
298
-
299
- declare const useLiveQuery: <T extends Observable<U>, U>(observable: T, opts?: {
300
- subscribeToRemote?: boolean;
301
- }) => Simplify<ReturnType<T["get"]>>;
302
- declare const SubscriptionProvider: ({ children, client, }: {
303
- children: React.ReactNode;
304
- client: Client<AnyRouter>["client"];
305
- }) => react_jsx_runtime.JSX.Element;
306
-
307
- type RawObjPool = Record<string, Record<string, MaterializedLiveType<LiveObjectAny> | undefined> | undefined>;
308
- type ClientState<TRouter extends AnyRouter> = {
309
- [K in keyof TRouter["routes"]]: Record<InferIndex<TRouter["routes"][K]["_resourceSchema"]>, InferLiveObject<TRouter["routes"][K]["_resourceSchema"]>> | undefined;
310
- };
311
- type Client<TRouter extends AnyRouter> = {
312
- client: {
313
- ws: WebSocketClient;
314
- subscribeToRemote: (resourceType?: string[]) => () => void;
315
- };
316
- store: Observable<ClientState<TRouter>> & {
317
- [K in keyof TRouter["routes"]]: {
318
- insert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => void;
319
- update: (id: string, value: Omit<Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>, "id">) => void;
320
- };
321
- } & {
322
- [K in keyof TRouter["routes"]]: {
323
- [K2 in keyof TRouter["routes"][K]["customMutations"]]: (input: z.infer<TRouter["routes"][K]["customMutations"][K2]["inputValidator"]>) => Promisify<ReturnType<TRouter["routes"][K]["customMutations"][K2]["handler"]>>;
324
- };
325
- };
326
- };
327
- type ClientOptions = {
328
- url: string;
329
- schema: Schema<any>;
330
- };
331
- declare const createClient: <TRouter extends AnyRouter>(opts: ClientOptions) => Client<TRouter>;
332
-
333
- export { type Client, type ClientOptions, type ClientState, type RawObjPool, SubscriptionProvider, createClient, useLiveQuery };
1
+ import 'zod';
2
+ export { c as Client, C as ClientOptions, b as ClientState, O as ObservableClientState, R as RawObjPool, e as SubscriptionProvider, d as createClient, u as useLiveQuery } from './index-NDRWVwih.js';
3
+ import 'react/jsx-runtime';
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import {z as z$1}from'zod';import {useState,useEffect}from'react';import {jsx,Fragment}from'react/jsx-runtime';z$1.object({type:z$1.literal("QUERY"),resource:z$1.string(),where:z$1.record(z$1.any()).optional(),include:z$1.record(z$1.any()).optional()});var O=z$1.record(z$1.object({value:z$1.string().or(z$1.number()).or(z$1.boolean()).or(z$1.date()),_meta:z$1.object({timestamp:z$1.string().optional()}).optional()})).superRefine((r,e)=>{r.id&&e.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),D=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string()}),I=D.extend({procedure:z$1.string(),payload:z$1.any()}),j=D.extend({resourceId:z$1.string(),payload:O});z$1.union([I,j]);var T=z$1.string(),G=z$1.object({id:T,type:z$1.literal("SUBSCRIBE"),resource:z$1.string()}),W=z$1.object({id:T,type:z$1.literal("SYNC"),lastSyncedAt:z$1.string().optional(),resources:z$1.string().array().optional(),where:z$1.record(z$1.any()).optional()}),P=j.extend({id:T}),z=I.extend({id:T}),q=z$1.union([z,P]);z$1.union([G,W,q]);var Z=z$1.object({id:T,type:z$1.literal("SYNC"),resource:z$1.string(),data:z$1.record(O)}),$=z$1.object({id:T,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),B=z$1.object({id:T,type:z$1.literal("REPLY"),data:z$1.any()}),F=z$1.union([Z,$,B,P]);var k="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var h;(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";})(h||(h={}));var v=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name="ULIDError",this.code=e;}};function H(r){let e=Math.floor(r()*32);return e===32&&(e=31),k.charAt(e)}function X(r){let e=J(),t=e&&(e.crypto||e.msCrypto)||null;if(typeof(t==null?void 0:t.getRandomValues)=="function")return ()=>{let n=new Uint8Array(1);return t.getRandomValues(n),n[0]/255};if(typeof(t==null?void 0:t.randomBytes)=="function")return ()=>t.randomBytes(1).readUInt8()/255;throw new v(h.PRNGDetectFailure,"Failed to find a reliable PRNG")}function J(){return ee()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Y(r,e){let t="";for(;r>0;r--)t=H(e)+t;return t}function Q(r,e=10){if(isNaN(r))throw new v(h.EncodeTimeValueMalformed,`Time must be a number: ${r}`);if(r>0xffffffffffff)throw new v(h.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${0xffffffffffff}: ${r}`);if(r<0)throw new v(h.EncodeTimeNegative,`Time must be positive: ${r}`);if(Number.isInteger(r)===false)throw new v(h.EncodeTimeValueMalformed,`Time must be an integer: ${r}`);let t,n="";for(let i=e;i>0;i--)t=r%32,n=k.charAt(t)+n,r=(r-t)/32;return n}function ee(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function U(r,e){let t=X(),n=Date.now();return Q(n,10)+Y(16,t)}var g=()=>U().toLowerCase();var S=r=>{if(r)return Array.isArray(r.value)?r.value.map(e=>S(e)):typeof r.value!="object"?r.value:Object.fromEntries(Object.entries(r.value).map(([e,t])=>[e,S(t)]))};var x=class{nodes;constructor(){this.nodes=new Map;}createNode(e,t,n){if(this.nodes.has(e))throw new Error(`Node with id ${e} already exists`);let i={id:e,type:t,referencedBy:new Map(n.map(o=>[o,new Set])),references:new Map,subscriptions:new Set};return this.nodes.set(e,i),i}getNode(e){return this.nodes.get(e)}hasNode(e){return this.nodes.has(e)}createLink(e,t,n){let i=this.nodes.get(e),o=this.nodes.get(t);if(!i)throw new Error(`Source node with id ${e} does not exist`);if(!o)throw new Error(`Target node with id ${t} does not exist`);i.references.set(n,t);let s=o.referencedBy.get(n);s&&s instanceof Set?s.add(e):o.referencedBy.set(n,e),this.notifySubscribers(t);}removeLink(e,t){let n=this.nodes.get(e);if(!n)throw new Error(`Node with id ${e} does not exist`);let i=n.references.get(t);if(!i)return;n.references.delete(t);let o=this.nodes.get(i);if(!o)return;let s=o.referencedBy.get(t);s&&(s instanceof Set?s.delete(e):o.referencedBy.delete(t),this.notifySubscribers(i)),this.notifySubscribers(e);}subscribe(e,t){let n=this.nodes.get(e);if(!n)throw new Error(`Node with id ${e} does not exist`);return n.subscriptions.add(t),()=>{n.subscriptions.delete(t);}}removeNode(e){let t=this.nodes.get(e);t&&(Array.from(t.referencedBy.entries()).forEach(([n,i])=>{(i instanceof Set?Array.from(i.values()):[i]).forEach(s=>{let a=this.nodes.get(s);!a||!a.references.get(n)||(a.references.delete(n),this.notifySubscribers(s));});}),this.nodes.delete(e));}updateNode(e,t){let n=this.nodes.get(e);if(!n)throw new Error(`Node with id ${e} does not exist`);t(n),this.notifySubscribers(e);}notifySubscribers(e){let t=this.nodes.get(e);t&&Array.from(t.subscriptions).forEach(n=>{try{n(e);}catch(i){console.error(`Error in node subscription for node ${e}:`,i);}});}getAllNodes(){return Array.from(this.nodes.values())}};var C=(r,e,t=[])=>new Proxy(r,{get:(n,i)=>{var l,y;if(i==="__isProxy__")return true;let o=(l=e.get)==null?void 0:l.call(e,n,[...t,i]);if(o!==void 0)return o;let s=n,a=i;return (y=s[a])!=null&&y.__isProxy__||(s[a]=C(typeof s[a]=="object"?s[a]:function(){},e,[...t,i])),s[a]},apply:(n,i,o)=>{var s;return (s=e.apply)==null?void 0:s.call(e,n,t,o)}});var w=class{ws=null;url;autoConnect;autoReconnect;reconnectTimeout;reconnectLimit;reconnectAttempts=0;eventListeners=new Map;reconnectTimer=null;intentionallyDisconnected=false;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.autoConnect&&this.connect();}connected(){var e;return ((e=this.ws)==null?void 0:e.readyState)===WebSocket.OPEN}connect(){this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||(this.intentionallyDisconnected=false,this.ws=new WebSocket(this.url),this.ws.addEventListener("open",this.handleOpen.bind(this)),this.ws.addEventListener("close",this.handleClose.bind(this)),this.ws.addEventListener("error",this.handleError.bind(this)),this.ws.addEventListener("message",this.handleMessage.bind(this)));}disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.intentionallyDisconnected=true,this.ws&&(this.ws.close(),this.ws=null);}addEventListener(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t);}removeEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.get(e).delete(t);}send(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e);else throw new Error("WebSocket is not open")}handleOpen(e){this.reconnectAttempts=0,this.dispatchEvent("open",e),this.dispatchEvent("connectionChange",{open:true});}handleClose(e){this.dispatchEvent("close",e),this.dispatchEvent("connectionChange",{open:false}),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect();}handleError(e){this.dispatchEvent("error",e);}handleMessage(e){this.dispatchEvent("message",e);}scheduleReconnect(){this.reconnectLimit&&this.reconnectAttempts>=this.reconnectLimit||(this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.connect();},this.reconnectTimeout));}dispatchEvent(e,t){this.eventListeners.has(e)&&this.eventListeners.get(e).forEach(n=>{n(t);});}};var Ue=(r,e)=>{let[t,n]=useState(()=>r.get());return useEffect(()=>{if(e!=null&&e.subscribeToRemote)return r.subscribeToRemote()},[e==null?void 0:e.subscribeToRemote]),useEffect(()=>r.subscribe(()=>{let i=r.get();n(i);}),[]),t},Ge=({children:r,client:e})=>(useEffect(()=>{e.subscribeToRemote();},[]),jsx(Fragment,{children:r}));var V=class{url;ws;schema;rawObjPool={};optimisticMutationStack={};optimisticObjGraph=new x;optimisticRawObjPool={};resourceTypeSubscriptions={};routeSubscriptions={};replyHandlers={};constructor(e){this.url=e.url,this.schema=e.schema,this.ws=new w({url:e.url,autoConnect:true,autoReconnect:true,reconnectTimeout:5e3}),this.ws.addEventListener("message",t=>{this.handleServerMessage(t.data);}),this.ws.addEventListener("connectionChange",t=>{t.open&&(this.sendWsMessage({id:g(),type:"SYNC"}),Object.entries(this.routeSubscriptions).forEach(([n,i])=>{i>0&&this.sendWsMessage({id:g(),type:"SUBSCRIBE",resource:n});}),Object.values(this.optimisticMutationStack).forEach(n=>{n.forEach(i=>this.sendWsMessage(i));}));});}get(e){if(e.length===0)throw new Error("Path must not be empty");if(e.length===1)return Object.fromEntries(Object.entries(this.optimisticRawObjPool[e[0]]??{}).map(([n,i])=>[n,S(i)]));let t=this.getFullObject(e[0],e[1]);if(!t)throw new Error("Object of type "+e[0]+" not found with id "+e[1]);return S(t)}handleServerMessage(e){try{console.log("Message received from the server:",e);let t=F.parse(JSON.parse(e));if(console.log("Parsed message:",t),t.type==="MUTATE"){let{resource:n}=t;try{this.addMutation(n,t);}catch(i){console.error("Error parsing mutation from the server:",i);}}else if(t.type==="SYNC"){let{resource:n,data:i}=t;console.log("Syncing resource:",i,t),Object.entries(i).forEach(([o,s])=>{this.addMutation(n,{id:o,type:"MUTATE",resource:n,resourceId:o,payload:s});});}else if(t.type!=="REJECT"){if(t.type==="REPLY"){let{id:n,data:i}=t;if(!this.replyHandlers[n])return;clearTimeout(this.replyHandlers[n].timeoutHandle),this.replyHandlers[n].handler(i);}}}catch(t){console.error("Error parsing message from the server:",t);}}subscribeToRemote(e){return this.routeSubscriptions[e]=(this.routeSubscriptions[e]??0)+1,this.sendWsMessage({id:g(),type:"SUBSCRIBE",resource:e}),()=>{this.routeSubscriptions[e]-=1,this.routeSubscriptions[e];}}subscribeToSlice(e,t){if(e.length===1)return this.resourceTypeSubscriptions[e[0]]||(this.resourceTypeSubscriptions[e[0]]=new Set),this.resourceTypeSubscriptions[e[0]].add(t),()=>{this.resourceTypeSubscriptions[e[0]].delete(t);};if(e.length===2){if(!this.optimisticObjGraph.getNode(e[1]))throw new Error("Node not found");return this.optimisticObjGraph.subscribe(e[1],t)}throw new Error("Not implemented")}mutate(e,t,n){let i={id:g(),type:"MUTATE",resource:e,payload:this.schema[e].encodeMutation("set",n,new Date().toISOString()),resourceId:t};this.addMutation(e,i,true),this.sendWsMessage(i);}genericMutate(e,t,n){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let i={id:g(),type:"MUTATE",resource:e,procedure:t,payload:n};return this.sendWsMessage(i),new Promise((o,s)=>{this.replyHandlers[i.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[i.id],s(new Error("Reply timeout"));},5e3),handler:a=>{delete this.replyHandlers[i.id],o(a);}};})}sendWsMessage(e){this.ws&&this.ws.connected()&&this.ws.send(JSON.stringify(e));}addMutation(e,t,n=false){var a,l,y,E;let i=this.schema[e];if(console.log("Adding mutation",t),!i)throw new Error("Schema not found");n?(this.optimisticMutationStack[e]||(this.optimisticMutationStack[e]=[]),this.optimisticMutationStack[e].push(t)):this.optimisticMutationStack[e]&&(this.optimisticMutationStack[e]=this.optimisticMutationStack[e].filter(d=>d.id!==t.id)),this.optimisticObjGraph.getNode(t.resourceId)||this.optimisticObjGraph.createNode(t.resourceId,e,Object.values(i.relations).flatMap(d=>d.type==="many"?[d.foreignColumn]:[]));let o=((a=this.optimisticRawObjPool[e])==null?void 0:a[t.resourceId])??((l=this.rawObjPool[e])==null?void 0:l[t.resourceId]);n||(this.rawObjPool[e]??={},this.rawObjPool[e][t.resourceId]={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}}),this.optimisticRawObjPool[e]??={};let s=(this.optimisticMutationStack[e]??[]).reduce((d,p)=>p.resourceId!==p.resourceId?d:this.schema[e].mergeMutation("set",p.payload,d)[0],(y=this.rawObjPool[e])==null?void 0:y[t.resourceId]);if(s&&(this.optimisticRawObjPool[e][t.resourceId]={value:{...s.value,id:{value:t.resourceId}}}),Object.keys(i.relations).length>0){let d=Object.fromEntries(Object.entries(i.relations).flatMap(([p,m])=>m.type==="one"?[[m.relationalColumn,p]]:[]));Object.entries(t.payload).forEach(([p,m])=>{if(!d[p])return;let[,f]=i.relations[d[p]].mergeMutation("set",m,o==null?void 0:o.value[p]);f&&this.optimisticObjGraph.createLink(t.resourceId,f.value,p);});}(E=this.resourceTypeSubscriptions[e])==null||E.forEach(d=>d()),this.optimisticObjGraph.notifySubscribers(t.resourceId);}getFullObject(e,t){var o;let n=this.optimisticObjGraph.getNode(t);if(!n)return;let i=(o=this.optimisticRawObjPool[e])==null?void 0:o[t];if(i)return {value:{...i.value,...Object.fromEntries(Array.from(n.referencedBy.entries()).map(([s,a])=>{var m;let l=a instanceof Set,y=l?Array.from(a.values()).flatMap(f=>{let M=this.optimisticObjGraph.getNode(f);return M?[M]:[]}):this.optimisticObjGraph.getNode(a);if(!y)return [s,void 0];let[E,d]=Object.entries(this.schema[e].relations).find(f=>f[1].relationalColumn===s||f[1].foreignColumn===s)??[],p=d==null?void 0:d.entity.name;return !p||!d?[s,l?[]:void 0]:[E,{value:l?y.map(f=>{var M;return (M=this.optimisticRawObjPool[p])==null?void 0:M[f.id]}):(m=this.optimisticRawObjPool[p])==null?void 0:m[y.id]}]}))}}}},dt=r=>{let e=new V(r);return {client:{ws:e.ws,subscribeToRemote:t=>{let n=[];for(let i of t??Object.keys(e.schema))n.push(e.subscribeToRemote(i));return ()=>{n.forEach(i=>i());}}},store:C(()=>{},{apply:(t,n,i)=>{let o=n.slice(0,-1),s=n[n.length-1];if(s==="get")return e.get(o);if(s==="subscribe")return e.subscribeToSlice(o,i[0]);if(s==="subscribeToRemote")return e.subscribeToRemote(o[0]);if(s==="insert"){let{id:a,...l}=i[0];return e.mutate(o[0],a,l)}if(s==="update"){let[a,l]=i;return e.mutate(o[0],a,l)}return e.genericMutate(o[0],s,i[0])}})}};export{Ge as SubscriptionProvider,dt as createClient,Ue as useLiveQuery};
1
+ import {d,a,c,b as b$1}from'./chunk-NIWX45UD.js';import {z as z$1}from'zod';import {stringify}from'qs';import {useState,useEffect}from'react';import {jsx,Fragment}from'react/jsx-runtime';z$1.object({type:z$1.literal("QUERY"),resource:z$1.string(),where:z$1.record(z$1.any()).optional(),include:z$1.record(z$1.any()).optional()});var T=z$1.record(z$1.object({value:z$1.string().or(z$1.number()).or(z$1.boolean()).or(z$1.date()),_meta:z$1.object({timestamp:z$1.string().optional()}).optional()})).superRefine((l,e)=>{l.id&&e.addIssue({code:z$1.ZodIssueCode.custom,message:"Payload cannot have an id"});}),x=z$1.object({id:z$1.string().optional(),type:z$1.literal("MUTATE"),resource:z$1.string()}),R=x.extend({procedure:z$1.string(),payload:z$1.any().optional()}),O=x.extend({resourceId:z$1.string(),payload:T});z$1.union([R,O]);var b=z$1.string(),k=z$1.object({id:b,type:z$1.literal("SUBSCRIBE"),resource:z$1.string()}),G=z$1.object({id:b,type:z$1.literal("SYNC"),lastSyncedAt:z$1.string().optional(),resources:z$1.string().array().optional(),where:z$1.record(z$1.any()).optional()}),A=O.extend({id:b}),W=R.extend({id:b}),K=z$1.union([W,A]);z$1.union([k,G,K]);var z=z$1.object({id:b,type:z$1.literal("SYNC"),resource:z$1.string(),data:z$1.record(T)}),I=z$1.object({id:b,type:z$1.literal("REJECT"),resource:z$1.string(),message:z$1.string().optional()}),B=z$1.object({id:b,type:z$1.literal("REPLY"),data:z$1.any()}),P=z$1.union([z,I,B,A]);var S=class{nodes;constructor(){this.nodes=new Map;}createNode(e,t,i){if(this.nodes.has(e))throw new Error(`Node with id ${e} already exists`);let r={id:e,type:t,referencedBy:new Map(i.map(s=>[s,new Set])),references:new Map,subscriptions:new Set};return this.nodes.set(e,r),r}getNode(e){return this.nodes.get(e)}hasNode(e){return this.nodes.has(e)}createLink(e,t,i){let r=this.nodes.get(e),s=this.nodes.get(t);if(!r)throw new Error(`Source node with id ${e} does not exist`);if(!s)throw new Error(`Target node with id ${t} does not exist`);r.references.set(i,t);let n=s.referencedBy.get(i);n&&n instanceof Set?n.add(e):s.referencedBy.set(i,e),this.notifySubscribers(t);}removeLink(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);let r=i.references.get(t);if(!r)return;i.references.delete(t);let s=this.nodes.get(r);if(!s)return;let n=s.referencedBy.get(t);n&&(n instanceof Set?n.delete(e):s.referencedBy.delete(t),this.notifySubscribers(r)),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,r])=>{(r instanceof Set?Array.from(r.values()):[r]).forEach(n=>{let d=this.nodes.get(n);!d||!d.references.get(i)||(d.references.delete(i),this.notifySubscribers(n));});}),this.nodes.delete(e));}updateNode(e,t){let i=this.nodes.get(e);if(!i)throw new Error(`Node with id ${e} does not exist`);t(i),this.notifySubscribers(e);}notifySubscribers(e){let t=this.nodes.get(e);t&&Array.from(t.subscriptions).forEach(i=>{try{i(e);}catch(r){console.error(`Error in node subscription for node ${e}:`,r);}});}getAllNodes(){return Array.from(this.nodes.values())}};var M=class{ws=null;url;autoConnect;autoReconnect;reconnectTimeout;reconnectLimit;reconnectAttempts=0;eventListeners=new Map;reconnectTimer=null;intentionallyDisconnected=false;credentials;constructor(e){this.url=e.url,this.autoConnect=e.autoConnect??false,this.autoReconnect=e.autoReconnect??false,this.reconnectTimeout=e.reconnectTimeout??5e3,this.reconnectLimit=e.reconnectLimit,this.credentials=e.credentials,this.autoConnect&&this.connect();}connected(){var e;return ((e=this.ws)==null?void 0:e.readyState)===WebSocket.OPEN}async connect(){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;this.intentionallyDisconnected=false;let e=await b$1(this.credentials);this.ws=new WebSocket(this.url+(e?`?${stringify(e)}`:"")),this.ws.addEventListener("open",this.handleOpen.bind(this)),this.ws.addEventListener("close",this.handleClose.bind(this)),this.ws.addEventListener("error",this.handleError.bind(this)),this.ws.addEventListener("message",this.handleMessage.bind(this));}disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.intentionallyDisconnected=true,this.ws&&(this.ws.close(),this.ws=null);}addEventListener(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t);}removeEventListener(e,t){this.eventListeners.has(e)&&this.eventListeners.get(e).delete(t);}send(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e);else throw new Error("WebSocket is not open")}handleOpen(e){this.reconnectAttempts=0,this.dispatchEvent("open",e),this.dispatchEvent("connectionChange",{open:true});}handleClose(e){this.dispatchEvent("close",e),this.dispatchEvent("connectionChange",{open:false}),this.autoReconnect&&!this.intentionallyDisconnected&&this.scheduleReconnect();}handleError(e){this.dispatchEvent("error",e);}handleMessage(e){this.dispatchEvent("message",e);}scheduleReconnect(){this.reconnectLimit&&this.reconnectAttempts>=this.reconnectLimit||(this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.connect();},this.reconnectTimeout));}dispatchEvent(e,t){this.eventListeners.has(e)&&this.eventListeners.get(e).forEach(i=>{i(t);});}};var re=(l,e)=>{let[t,i]=useState(()=>l.get());return useEffect(()=>{if(e!=null&&e.subscribeToRemote)return l.subscribeToRemote()},[e==null?void 0:e.subscribeToRemote]),useEffect(()=>l.subscribe(()=>{let r=l.get();i(r);}),[]),t},se=({children:l,client:e})=>(useEffect(()=>{e.subscribeToRemote();},[]),jsx(Fragment,{children:l}));var j=class{url;ws;schema;rawObjPool={};optimisticMutationStack={};optimisticObjGraph=new S;optimisticRawObjPool={};resourceTypeSubscriptions={};routeSubscriptions={};replyHandlers={};constructor(e){this.url=e.url,this.schema=e.schema,this.ws=new M({url:e.url,autoConnect:true,autoReconnect:true,reconnectTimeout:5e3,credentials:e.credentials}),this.ws.addEventListener("message",t=>{this.handleServerMessage(t.data);}),this.ws.addEventListener("connectionChange",t=>{t.open&&(this.sendWsMessage({id:a(),type:"SYNC"}),Object.entries(this.routeSubscriptions).forEach(([i,r])=>{r>0&&this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:i});}),Object.values(this.optimisticMutationStack).forEach(i=>{i.forEach(r=>this.sendWsMessage(r));}));});}get(e){if(e.length===0)throw new Error("Path must not be empty");if(e.length===1)return Object.fromEntries(Object.entries(this.optimisticRawObjPool[e[0]]??{}).map(([i,r])=>[i,c(r)]));let t=this.getFullObject(e[0],e[1]);if(!t)throw new Error("Object of type "+e[0]+" not found with id "+e[1]);return c(t)}handleServerMessage(e){try{console.log("Message received from the server:",e);let t=P.parse(JSON.parse(e));if(console.log("Parsed message:",t),t.type==="MUTATE"){let{resource:i}=t;try{this.addMutation(i,t);}catch(r){console.error("Error parsing mutation from the server:",r);}}else if(t.type==="SYNC"){let{resource:i,data:r}=t;console.log("Syncing resource:",r,t),Object.entries(r).forEach(([s,n])=>{this.addMutation(i,{id:s,type:"MUTATE",resource:i,resourceId:s,payload:n});});}else if(t.type!=="REJECT"){if(t.type==="REPLY"){let{id:i,data:r}=t;if(!this.replyHandlers[i])return;clearTimeout(this.replyHandlers[i].timeoutHandle),this.replyHandlers[i].handler(r);}}}catch(t){console.error("Error parsing message from the server:",t);}}subscribeToRemote(e){return this.routeSubscriptions[e]=(this.routeSubscriptions[e]??0)+1,this.sendWsMessage({id:a(),type:"SUBSCRIBE",resource:e}),()=>{this.routeSubscriptions[e]-=1,this.routeSubscriptions[e];}}subscribeToSlice(e,t){if(e.length===1)return this.resourceTypeSubscriptions[e[0]]||(this.resourceTypeSubscriptions[e[0]]=new Set),this.resourceTypeSubscriptions[e[0]].add(t),()=>{this.resourceTypeSubscriptions[e[0]].delete(t);};if(e.length===2){if(!this.optimisticObjGraph.getNode(e[1]))throw new Error("Node not found");return this.optimisticObjGraph.subscribe(e[1],t)}throw new Error("Not implemented")}mutate(e,t,i){let r={id:a(),type:"MUTATE",resource:e,payload:this.schema[e].encodeMutation("set",i,new Date().toISOString()),resourceId:t};this.addMutation(e,r,true),this.sendWsMessage(r);}genericMutate(e,t,i){if(!this.ws||!this.ws.connected())throw new Error("WebSocket not connected");let r={id:a(),type:"MUTATE",resource:e,procedure:t,payload:i};return this.sendWsMessage(r),new Promise((s,n)=>{this.replyHandlers[r.id]={timeoutHandle:setTimeout(()=>{delete this.replyHandlers[r.id],n(new Error("Reply timeout"));},5e3),handler:d=>{delete this.replyHandlers[r.id],s(d);}};})}sendWsMessage(e){this.ws&&this.ws.connected()&&this.ws.send(JSON.stringify(e));}addMutation(e,t,i=false){var d,p,g,v;let r=this.schema[e];if(console.log("Adding mutation",t),!r)throw new Error("Schema not found");i?(this.optimisticMutationStack[e]||(this.optimisticMutationStack[e]=[]),this.optimisticMutationStack[e].push(t)):this.optimisticMutationStack[e]&&(this.optimisticMutationStack[e]=this.optimisticMutationStack[e].filter(a=>a.id!==t.id)),this.optimisticObjGraph.getNode(t.resourceId)||this.optimisticObjGraph.createNode(t.resourceId,e,Object.values(r.relations).flatMap(a=>a.type==="many"?[a.foreignColumn]:[]));let s=((d=this.optimisticRawObjPool[e])==null?void 0:d[t.resourceId])??((p=this.rawObjPool[e])==null?void 0:p[t.resourceId]);i||(this.rawObjPool[e]??={},this.rawObjPool[e][t.resourceId]={value:{...this.schema[e].mergeMutation("set",t.payload,this.rawObjPool[e][t.resourceId])[0].value,id:{value:t.resourceId}}}),this.optimisticRawObjPool[e]??={};let n=(this.optimisticMutationStack[e]??[]).reduce((a,u)=>u.resourceId!==u.resourceId?a:this.schema[e].mergeMutation("set",u.payload,a)[0],(g=this.rawObjPool[e])==null?void 0:g[t.resourceId]);if(n&&(this.optimisticRawObjPool[e][t.resourceId]={value:{...n.value,id:{value:t.resourceId}}}),Object.keys(r.relations).length>0){let a=Object.fromEntries(Object.entries(r.relations).flatMap(([u,f])=>f.type==="one"?[[f.relationalColumn,u]]:[]));Object.entries(t.payload).forEach(([u,f])=>{if(!a[u])return;let[,h]=r.relations[a[u]].mergeMutation("set",f,s==null?void 0:s.value[u]);h&&this.optimisticObjGraph.createLink(t.resourceId,h.value,u);});}(v=this.resourceTypeSubscriptions[e])==null||v.forEach(a=>a()),this.optimisticObjGraph.notifySubscribers(t.resourceId);}getFullObject(e,t){var s;let i=this.optimisticObjGraph.getNode(t);if(!i)return;let r=(s=this.optimisticRawObjPool[e])==null?void 0:s[t];if(r)return {value:{...r.value,...Object.fromEntries(Array.from(i.referencedBy.entries()).map(([n,d])=>{var f;let p=d instanceof Set,g=p?Array.from(d.values()).flatMap(h=>{let m=this.optimisticObjGraph.getNode(h);return m?[m]:[]}):this.optimisticObjGraph.getNode(d);if(!g)return [n,void 0];let[v,a]=Object.entries(this.schema[e].relations).find(h=>h[1].relationalColumn===n||h[1].foreignColumn===n)??[],u=a==null?void 0:a.entity.name;return !u||!a?[n,p?[]:void 0]:[v,{value:p?g.map(h=>{var m;return (m=this.optimisticRawObjPool[u])==null?void 0:m[h.id]}):(f=this.optimisticRawObjPool[u])==null?void 0:f[g.id]}]}))}}}},Ce=l=>{let e=new j(l);return {client:{ws:e.ws,subscribeToRemote:t=>{let i=[];for(let r of t??Object.keys(e.schema))i.push(e.subscribeToRemote(r));return ()=>{i.forEach(r=>r());}}},store:d(()=>{},{apply:(t,i,r)=>{let s=i.slice(0,-1),n=i[i.length-1];if(n==="get")return e.get(s);if(n==="subscribe")return e.subscribeToSlice(s,r[0]);if(n==="subscribeToRemote")return e.subscribeToRemote(s[0]);if(n==="insert"){let{id:d,...p}=r[0];return e.mutate(s[0],d,p)}if(n==="update"){let[d,p]=r;return e.mutate(s[0],d,p)}return e.genericMutate(s[0],n,r[0])}})}};export{se as SubscriptionProvider,Ce as createClient,re as useLiveQuery};
@@ -0,0 +1,17 @@
1
+ import { A as AnyRouter, C as ClientOptions, L as LiveObjectAny, W as WhereClause, S as Simplify, I as InferLiveObject, a as LiveObjectMutationInput } from './index-NDRWVwih.js';
2
+ import 'zod';
3
+ import 'react/jsx-runtime';
4
+
5
+ type GetOptions<T extends LiveObjectAny> = {
6
+ headers?: Record<string, string>;
7
+ where?: WhereClause<T>;
8
+ };
9
+ type FetchClient<TRouter extends AnyRouter> = {
10
+ [K in keyof TRouter["routes"]]: {
11
+ get: (opts?: GetOptions<TRouter["routes"][K]["_resourceSchema"]>) => Promise<Simplify<InferLiveObject<TRouter["routes"][K]["_resourceSchema"]>>>;
12
+ upsert: (input: Simplify<LiveObjectMutationInput<TRouter["routes"][K]["_resourceSchema"]>>) => Promise<void>;
13
+ };
14
+ };
15
+ declare const createClient: <TRouter extends AnyRouter>(opts: ClientOptions) => FetchClient<TRouter>;
16
+
17
+ export { createClient };
@@ -0,0 +1 @@
1
+ import {d,b,c}from'./chunk-NIWX45UD.js';import {stringify}from'qs';var S=t=>d(()=>{},{apply:async(h,c$1,o)=>{if(c$1.length>2)throw new Error("Trying to access invalid property");let[n,i]=c$1,s=await b(t.credentials)??{};if(i==="get"){let e=o[0],r={};return e!=null&&e.where&&(r.where=e.where),fetch(`${t.url}/${n}${Object.keys(r).length>0?`?${stringify(r)}`:""}`,{headers:s}).then(async y=>Object.fromEntries(Object.entries(await y.json()??{}).map(([m,l])=>[m,c(l)])))}if(i==="upsert"){let{id:e,...r}=o[0];return fetch(`${t.url}/${n}/set`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({resourceId:e,payload:t.schema[n].encodeMutation("set",r,new Date().toISOString())})})}return fetch(`${t.url}/${n}/${i}`,{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify(o[0])})}});export{S as createClient};