@live-state/sync 0.0.1-alpha.1

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,458 @@
1
+ import { z, ZodUnion } from 'zod';
2
+
3
+ declare const mutationsMsgSchema: z.ZodObject<{
4
+ _id: z.ZodString;
5
+ type: z.ZodLiteral<"MUTATE">;
6
+ resource: z.ZodString;
7
+ resourceId: z.ZodString;
8
+ payload: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
9
+ value: ZodUnion<[ZodUnion<[ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>;
10
+ _meta: z.ZodOptional<z.ZodObject<{
11
+ timestamp: z.ZodOptional<z.ZodString>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ timestamp?: string | undefined;
14
+ }, {
15
+ timestamp?: string | undefined;
16
+ }>>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ value: string | number | boolean | Date;
19
+ _meta?: {
20
+ timestamp?: string | undefined;
21
+ } | undefined;
22
+ }, {
23
+ value: string | number | boolean | Date;
24
+ _meta?: {
25
+ timestamp?: string | undefined;
26
+ } | undefined;
27
+ }>>, Record<string, {
28
+ value: string | number | boolean | Date;
29
+ _meta?: {
30
+ timestamp?: string | undefined;
31
+ } | undefined;
32
+ }>, Record<string, {
33
+ value: string | number | boolean | Date;
34
+ _meta?: {
35
+ timestamp?: string | undefined;
36
+ } | undefined;
37
+ }>>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ _id: string;
40
+ type: "MUTATE";
41
+ resource: string;
42
+ resourceId: string;
43
+ payload: Record<string, {
44
+ value: string | number | boolean | Date;
45
+ _meta?: {
46
+ timestamp?: string | undefined;
47
+ } | undefined;
48
+ }>;
49
+ }, {
50
+ _id: string;
51
+ type: "MUTATE";
52
+ resource: string;
53
+ resourceId: string;
54
+ payload: Record<string, {
55
+ value: string | number | boolean | Date;
56
+ _meta?: {
57
+ timestamp?: string | undefined;
58
+ } | undefined;
59
+ }>;
60
+ }>;
61
+ type MutationMessage = z.infer<typeof mutationsMsgSchema>;
62
+ declare const clientMessageSchema: ZodUnion<[z.ZodObject<{
63
+ _id: z.ZodString;
64
+ type: z.ZodLiteral<"SUBSCRIBE">;
65
+ resource: z.ZodString;
66
+ }, "strip", z.ZodTypeAny, {
67
+ _id: string;
68
+ type: "SUBSCRIBE";
69
+ resource: string;
70
+ }, {
71
+ _id: string;
72
+ type: "SUBSCRIBE";
73
+ resource: string;
74
+ }>, z.ZodObject<{
75
+ _id: z.ZodString;
76
+ type: z.ZodLiteral<"MUTATE">;
77
+ resource: z.ZodString;
78
+ resourceId: z.ZodString;
79
+ payload: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
80
+ value: ZodUnion<[ZodUnion<[ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>;
81
+ _meta: z.ZodOptional<z.ZodObject<{
82
+ timestamp: z.ZodOptional<z.ZodString>;
83
+ }, "strip", z.ZodTypeAny, {
84
+ timestamp?: string | undefined;
85
+ }, {
86
+ timestamp?: string | undefined;
87
+ }>>;
88
+ }, "strip", z.ZodTypeAny, {
89
+ value: string | number | boolean | Date;
90
+ _meta?: {
91
+ timestamp?: string | undefined;
92
+ } | undefined;
93
+ }, {
94
+ value: string | number | boolean | Date;
95
+ _meta?: {
96
+ timestamp?: string | undefined;
97
+ } | undefined;
98
+ }>>, Record<string, {
99
+ value: string | number | boolean | Date;
100
+ _meta?: {
101
+ timestamp?: string | undefined;
102
+ } | undefined;
103
+ }>, Record<string, {
104
+ value: string | number | boolean | Date;
105
+ _meta?: {
106
+ timestamp?: string | undefined;
107
+ } | undefined;
108
+ }>>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ _id: string;
111
+ type: "MUTATE";
112
+ resource: string;
113
+ resourceId: string;
114
+ payload: Record<string, {
115
+ value: string | number | boolean | Date;
116
+ _meta?: {
117
+ timestamp?: string | undefined;
118
+ } | undefined;
119
+ }>;
120
+ }, {
121
+ _id: string;
122
+ type: "MUTATE";
123
+ resource: string;
124
+ resourceId: string;
125
+ payload: Record<string, {
126
+ value: string | number | boolean | Date;
127
+ _meta?: {
128
+ timestamp?: string | undefined;
129
+ } | undefined;
130
+ }>;
131
+ }>, z.ZodObject<{
132
+ _id: z.ZodString;
133
+ type: z.ZodLiteral<"SYNC">;
134
+ lastSyncedAt: z.ZodOptional<z.ZodString>;
135
+ resources: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
136
+ }, "strip", z.ZodTypeAny, {
137
+ _id: string;
138
+ type: "SYNC";
139
+ lastSyncedAt?: string | undefined;
140
+ resources?: string[] | undefined;
141
+ }, {
142
+ _id: string;
143
+ type: "SYNC";
144
+ lastSyncedAt?: string | undefined;
145
+ resources?: string[] | undefined;
146
+ }>]>;
147
+ type ClientMessage = z.infer<typeof clientMessageSchema>;
148
+ declare const serverMessageSchema: ZodUnion<[z.ZodObject<{
149
+ _id: z.ZodString;
150
+ type: z.ZodLiteral<"MUTATE">;
151
+ resource: z.ZodString;
152
+ resourceId: z.ZodString;
153
+ payload: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
154
+ value: ZodUnion<[ZodUnion<[ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>;
155
+ _meta: z.ZodOptional<z.ZodObject<{
156
+ timestamp: z.ZodOptional<z.ZodString>;
157
+ }, "strip", z.ZodTypeAny, {
158
+ timestamp?: string | undefined;
159
+ }, {
160
+ timestamp?: string | undefined;
161
+ }>>;
162
+ }, "strip", z.ZodTypeAny, {
163
+ value: string | number | boolean | Date;
164
+ _meta?: {
165
+ timestamp?: string | undefined;
166
+ } | undefined;
167
+ }, {
168
+ value: string | number | boolean | Date;
169
+ _meta?: {
170
+ timestamp?: string | undefined;
171
+ } | undefined;
172
+ }>>, Record<string, {
173
+ value: string | number | boolean | Date;
174
+ _meta?: {
175
+ timestamp?: string | undefined;
176
+ } | undefined;
177
+ }>, Record<string, {
178
+ value: string | number | boolean | Date;
179
+ _meta?: {
180
+ timestamp?: string | undefined;
181
+ } | undefined;
182
+ }>>;
183
+ }, "strip", z.ZodTypeAny, {
184
+ _id: string;
185
+ type: "MUTATE";
186
+ resource: string;
187
+ resourceId: string;
188
+ payload: Record<string, {
189
+ value: string | number | boolean | Date;
190
+ _meta?: {
191
+ timestamp?: string | undefined;
192
+ } | undefined;
193
+ }>;
194
+ }, {
195
+ _id: string;
196
+ type: "MUTATE";
197
+ resource: string;
198
+ resourceId: string;
199
+ payload: Record<string, {
200
+ value: string | number | boolean | Date;
201
+ _meta?: {
202
+ timestamp?: string | undefined;
203
+ } | undefined;
204
+ }>;
205
+ }>, z.ZodObject<{
206
+ _id: z.ZodString;
207
+ type: z.ZodLiteral<"SYNC">;
208
+ resource: z.ZodString;
209
+ data: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
210
+ value: ZodUnion<[ZodUnion<[ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodBoolean]>, z.ZodDate]>;
211
+ _meta: z.ZodOptional<z.ZodObject<{
212
+ timestamp: z.ZodOptional<z.ZodString>;
213
+ }, "strip", z.ZodTypeAny, {
214
+ timestamp?: string | undefined;
215
+ }, {
216
+ timestamp?: string | undefined;
217
+ }>>;
218
+ }, "strip", z.ZodTypeAny, {
219
+ value: string | number | boolean | Date;
220
+ _meta?: {
221
+ timestamp?: string | undefined;
222
+ } | undefined;
223
+ }, {
224
+ value: string | number | boolean | Date;
225
+ _meta?: {
226
+ timestamp?: string | undefined;
227
+ } | undefined;
228
+ }>>, Record<string, {
229
+ value: string | number | boolean | Date;
230
+ _meta?: {
231
+ timestamp?: string | undefined;
232
+ } | undefined;
233
+ }>, Record<string, {
234
+ value: string | number | boolean | Date;
235
+ _meta?: {
236
+ timestamp?: string | undefined;
237
+ } | undefined;
238
+ }>>>;
239
+ }, "strip", z.ZodTypeAny, {
240
+ _id: string;
241
+ type: "SYNC";
242
+ resource: string;
243
+ data: Record<string, Record<string, {
244
+ value: string | number | boolean | Date;
245
+ _meta?: {
246
+ timestamp?: string | undefined;
247
+ } | undefined;
248
+ }>>;
249
+ }, {
250
+ _id: string;
251
+ type: "SYNC";
252
+ resource: string;
253
+ data: Record<string, Record<string, {
254
+ value: string | number | boolean | Date;
255
+ _meta?: {
256
+ timestamp?: string | undefined;
257
+ } | undefined;
258
+ }>>;
259
+ }>, z.ZodObject<{
260
+ _id: z.ZodString;
261
+ type: z.ZodLiteral<"REJECT">;
262
+ resource: z.ZodString;
263
+ }, "strip", z.ZodTypeAny, {
264
+ _id: string;
265
+ type: "REJECT";
266
+ resource: string;
267
+ }, {
268
+ _id: string;
269
+ type: "REJECT";
270
+ resource: string;
271
+ }>]>;
272
+ type ServerMessage = z.infer<typeof serverMessageSchema>;
273
+
274
+ type LiveTypeMeta = {};
275
+ type MutationType = "set";
276
+ declare abstract class LiveType<Value = any, Meta extends LiveTypeMeta = LiveTypeMeta, EncodeInput = Partial<Value> | Value, DecodeInput = {
277
+ value: Value;
278
+ _meta: keyof Meta extends never ? never : Meta;
279
+ }> {
280
+ readonly _value: Value;
281
+ readonly _meta: Meta;
282
+ readonly _encodeInput: EncodeInput;
283
+ readonly _decodeInput: DecodeInput;
284
+ abstract encodeMutation(mutationType: MutationType, input: EncodeInput, timestamp: string): DecodeInput;
285
+ /**
286
+ * Merges the materialized shape with the encoded mutation
287
+ * @param mutationType The type of mutation
288
+ * @param encodedMutation The encoded mutation
289
+ * @param materializedShape The materialized shape
290
+ * @returns A tuple of the new materialized shape and the accepted diff
291
+ */
292
+ abstract mergeMutation(mutationType: MutationType, encodedMutation: DecodeInput, materializedShape?: MaterializedLiveType<LiveType<Value, Meta>>): [MaterializedLiveType<LiveType<Value, Meta>>, DecodeInput | null];
293
+ }
294
+ type LiveTypeAny = LiveType<any, LiveTypeMeta, any, any>;
295
+ type InferLiveType<T extends LiveTypeAny> = T["_value"] extends Record<string, LiveTypeAny> ? {
296
+ [K in keyof T["_value"]]: InferLiveType<T["_value"][K]>;
297
+ } : T["_value"];
298
+ type InferIndex<T extends LiveTypeAny> = string;
299
+
300
+ declare class OptionalLiveType<T extends LiveTypeAny> extends LiveType<T["_value"] | undefined, T["_meta"], T["_encodeInput"], T["_decodeInput"]> {
301
+ encodeMutation(mutationType: MutationType, input: T["_value"] | undefined, timestamp: string): string;
302
+ mergeMutation(mutationType: MutationType, encodedMutation: T["_decodeInput"], materializedShape?: MaterializedLiveType<LiveType<T["_value"] | undefined, T["_meta"], T["_value"] | Partial<T["_value"] | undefined>, T["_decodeInput"]>> | undefined): [
303
+ MaterializedLiveType<LiveType<T["_value"] | undefined, T["_meta"], T["_value"] | Partial<T["_value"] | undefined>, T["_decodeInput"]>>,
304
+ T["_decodeInput"] | null
305
+ ];
306
+ }
307
+ type LiveAtomicTypeMeta = {
308
+ timestamp: string;
309
+ } & LiveTypeMeta;
310
+ declare abstract class LiveAtomicType<Value = any, Meta extends LiveAtomicTypeMeta = LiveAtomicTypeMeta, EncodeInput = Partial<Value> | Value> extends LiveType<Value, Meta, EncodeInput> {
311
+ constructor();
312
+ optional(): OptionalLiveType<this>;
313
+ }
314
+ declare class LiveNumber extends LiveAtomicType<number> {
315
+ encodeMutation(mutationType: MutationType, input: Partial<number>, timestamp: string): {
316
+ value: number;
317
+ _meta: {
318
+ timestamp: string;
319
+ };
320
+ };
321
+ mergeMutation(mutationType: MutationType, encodedMutation: {
322
+ value: number;
323
+ _meta: {
324
+ timestamp: string;
325
+ };
326
+ }, materializedShape?: MaterializedLiveType<LiveNumber>): [
327
+ MaterializedLiveType<LiveNumber>,
328
+ {
329
+ value: number;
330
+ _meta: {
331
+ timestamp: string;
332
+ };
333
+ } | null
334
+ ];
335
+ static create(): LiveNumber;
336
+ }
337
+ declare const number: typeof LiveNumber.create;
338
+ declare class LiveString extends LiveAtomicType<string> {
339
+ encodeMutation(mutationType: MutationType, input: Partial<string>, timestamp: string): {
340
+ value: string;
341
+ _meta: {
342
+ timestamp: string;
343
+ };
344
+ };
345
+ mergeMutation(mutationType: MutationType, encodedMutation: {
346
+ value: string;
347
+ _meta: {
348
+ timestamp: string;
349
+ };
350
+ }, materializedShape?: MaterializedLiveType<LiveString>): [
351
+ MaterializedLiveType<LiveString>,
352
+ {
353
+ value: string;
354
+ _meta: {
355
+ timestamp: string;
356
+ };
357
+ } | null
358
+ ];
359
+ static create(): LiveString;
360
+ }
361
+ declare const string: typeof LiveString.create;
362
+
363
+ type InferLiveObjectWithoutRelations<T extends LiveObjectAny> = {
364
+ [K in keyof T["fields"]]: InferLiveType<T["fields"][K]>;
365
+ };
366
+ type InferLiveObject<T extends LiveObjectAny> = InferLiveObjectWithoutRelations<T> & {
367
+ [K in keyof T["relations"]]: T["relations"][K]["type"] extends "one" ? InferLiveObject<T["relations"][K]["entity"]> : InferLiveObject<T["relations"][K]["entity"]>[];
368
+ };
369
+ type InferRelationalColumns<T extends Record<string, RelationAny>> = {
370
+ [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;
371
+ };
372
+ type InferLiveObjectWithRelationalIds<T extends LiveObjectAny> = keyof T["relations"] extends string ? InferLiveObjectWithoutRelations<T> & InferRelationalColumns<T["relations"]> : InferLiveObjectWithoutRelations<T>;
373
+ type LiveObjectMutationInput<TSchema extends LiveObjectAny> = InferLiveObjectWithRelationalIds<TSchema>;
374
+ 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>>> {
375
+ readonly name: TName;
376
+ readonly fields: TSchema;
377
+ readonly relations: TRelations;
378
+ constructor(name: TName, fields: TSchema, relations?: TRelations);
379
+ encodeMutation(_mutationType: MutationType, input: LiveObjectMutationInput<this>, timestamp: string): Record<string, any>;
380
+ mergeMutation(mutationType: MutationType, encodedMutations: Record<string, MaterializedLiveType<LiveTypeAny>>, materializedShape?: MaterializedLiveType<this> | undefined): [MaterializedLiveType<this>, Record<string, any> | null];
381
+ setRelations<TRelations extends Record<string, RelationAny>>(relations: TRelations): LiveObject<this["name"], this["fields"], TRelations>;
382
+ static create<TName extends string, TSchema extends Record<string, LiveTypeAny>>(name: TName, schema: TSchema): LiveObject<TName, TSchema, never>;
383
+ }
384
+ declare const object: typeof LiveObject.create;
385
+ type LiveObjectAny = LiveObject<string, Record<string, LiveTypeAny>, any>;
386
+ 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>, {
387
+ timestamp: string;
388
+ } & LiveTypeMeta> {
389
+ readonly entity: TEntity;
390
+ readonly type: TType;
391
+ readonly required: TRequired;
392
+ readonly relationalColumn?: TRelationalColumn;
393
+ readonly foreignColumn?: TForeignColumn;
394
+ readonly sourceEntity: TSourceEntity;
395
+ private constructor();
396
+ encodeMutation(mutationType: MutationType, input: string, timestamp: string): {
397
+ value: string;
398
+ _meta: {
399
+ timestamp: string;
400
+ };
401
+ };
402
+ mergeMutation(mutationType: MutationType, encodedMutation: {
403
+ value: string;
404
+ _meta: {
405
+ timestamp: string;
406
+ };
407
+ }, materializedShape?: MaterializedLiveType<LiveString> | undefined): [
408
+ MaterializedLiveType<LiveString>,
409
+ {
410
+ value: string;
411
+ _meta: {
412
+ timestamp: string;
413
+ };
414
+ } | null
415
+ ];
416
+ 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>;
417
+ 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>;
418
+ }
419
+ type RelationAny = Relation<LiveObjectAny, LiveObjectAny, any, any, any, any>;
420
+ declare const createRelations: <TSourceObject extends LiveObjectAny, TRelations extends Record<string, RelationAny>>(liveObject: TSourceObject, factory: (connectors: {
421
+ one: ReturnType<typeof Relation.createOneFactory<TSourceObject>>;
422
+ many: ReturnType<typeof Relation.createManyFactory<TSourceObject>>;
423
+ }) => TRelations) => RelationsDecl<TSourceObject["name"], TRelations>;
424
+ type MaterializedLiveType<T extends LiveTypeAny> = keyof T["_meta"] extends never ? {
425
+ value: T["_value"] extends Record<string, LiveTypeAny> ? {
426
+ [K in keyof T["_value"]]: MaterializedLiveType<T["_value"][K]>;
427
+ } : T["_value"];
428
+ } : {
429
+ value: T["_value"] extends Record<string, LiveTypeAny> ? {
430
+ [K in keyof T["_value"]]: MaterializedLiveType<T["_value"][K]>;
431
+ } : T["_value"];
432
+ _meta: T["_meta"];
433
+ };
434
+ type MaterializedLiveObject<T extends LiveObjectAny> = MaterializedLiveType<T> & {
435
+ [K in keyof T["relations"]]: InferIndex<T["relations"][K]["entity"]>;
436
+ };
437
+ declare const inferValue: <T extends LiveTypeAny>(type: MaterializedLiveType<T>) => InferLiveType<T>;
438
+ type ExtractObjectValues<T> = T[keyof T];
439
+ type RelationsDecl<TObjectName extends string = string, TRelations extends Record<string, RelationAny> = Record<string, RelationAny>> = {
440
+ $type: "relations";
441
+ objectName: TObjectName;
442
+ relations: TRelations;
443
+ };
444
+ type ParseRelationsFromSchema<TRawSchema extends RawSchema, TObjectName extends string> = ExtractObjectValues<{
445
+ [K in keyof TRawSchema]: TRawSchema[K] extends RelationsDecl<infer TObjectName_, any> ? TObjectName_ extends TObjectName ? {
446
+ [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"]>;
447
+ } : never : never;
448
+ }>;
449
+ type ParseObjectFromSchema<TRawSchema extends RawSchema, TObjectName extends string> = ExtractObjectValues<{
450
+ [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;
451
+ }>;
452
+ type RawSchema = Record<string, LiveObjectAny | RelationsDecl>;
453
+ type Schema<TRawSchema extends RawSchema> = {
454
+ [K in keyof TRawSchema as TRawSchema[K] extends LiveObjectAny ? TRawSchema[K]["name"] : never]: TRawSchema[K] extends LiveObjectAny ? ParseObjectFromSchema<TRawSchema, TRawSchema[K]["name"]> : never;
455
+ };
456
+ declare const createSchema: <TRawSchema extends RawSchema>(schema: TRawSchema) => Schema<TRawSchema>;
457
+
458
+ export { type ClientMessage as C, type InferLiveObject as I, type LiveObjectAny as L, type MaterializedLiveType as M, Relation as R, type Schema as S, type MutationMessage as a, type ServerMessage as b, type InferLiveObjectWithRelationalIds as c, type LiveObjectMutationInput as d, LiveObject as e, createRelations as f, type MaterializedLiveObject as g, createSchema as h, inferValue as i, LiveNumber as j, LiveString as k, type LiveTypeMeta as l, type MutationType as m, number as n, object as o, LiveType as p, type LiveTypeAny as q, type InferLiveType as r, string as s, type InferIndex as t };
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ 'use strict';var o=class{_value;_meta;_encodeInput;_decodeInput};var T=class extends o{encodeMutation(n,t,e){throw new Error("Method not implemented.")}mergeMutation(n,t,e){throw new Error("Method not implemented.")}},s=class extends o{constructor(){super(),this.optional=this.optional.bind(this);}optional(){return new T}},y=class a extends s{encodeMutation(n,t,e){return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[{value:Number(t.value),_meta:t._meta},t]}static create(){return new a}},M=y.create,c=class a extends s{encodeMutation(n,t,e){return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[t,t]}static create(){return new a}},h=c.create;var u=class a extends o{name;fields;relations;constructor(n,t,e){super(),this.name=n,this.fields=t,this.relations=e??{};}encodeMutation(n,t,e){return Object.fromEntries(Object.entries(t).map(([r,i])=>[r,(this.fields[r]??this.relations[r]).encodeMutation("set",i,e)]))}mergeMutation(n,t,e){let r={};return [{value:{...(e==null?void 0:e.value)??{},...Object.fromEntries(Object.entries(t).map(([i,d])=>{let[v,m]=(this.fields[i]??this.relations[i]).mergeMutation(n,d,e==null?void 0:e.value[i]);return m&&(r[i]=m),[i,v]}))}},r]}setRelations(n){return new a(this.name,this.fields,n)}static create(n,t){return new a(n,t)}},A=u.create,l=class a extends o{entity;type;required;relationalColumn;foreignColumn;sourceEntity;constructor(n,t,e,r,i){super(),this.entity=n,this.type=t,this.required=i??false,this.relationalColumn=e,this.foreignColumn=r;}encodeMutation(n,t,e){if(n!=="set")throw new Error("Mutation type not implemented.");if(this.type==="many")throw new Error("Many not implemented.");return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){if(this.type==="many")throw new Error("Many not implemented.");return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[t,t]}static createOneFactory(){return (n,t,e)=>new a(n,"one",t,void 0,e??false)}static createManyFactory(){return (n,t,e)=>new a(n,"many",void 0,t,e??false)}},K=(a,n)=>({$type:"relations",objectName:a.name,relations:n({one:l.createOneFactory(),many:l.createManyFactory()})}),p=a=>Array.isArray(a.value)?a.value.map(n=>p(n)):typeof a.value!="object"?a.value:Object.fromEntries(Object.entries(a.value).map(([n,t])=>[n,p(t)])),E=a=>Object.fromEntries(Object.entries(a).flatMap(([n,t])=>{if(t.$type==="relations")return [];let e=t,r=Object.values(a).find(i=>i.$type==="relations"&&i.objectName===t.name);return r&&(e=e.setRelations(r.relations)),[[e.name,e]]}));exports.LiveNumber=y;exports.LiveObject=u;exports.LiveString=c;exports.LiveType=o;exports.Relation=l;exports.createRelations=K;exports.createSchema=E;exports.inferValue=p;exports.number=M;exports.object=A;exports.string=h;
@@ -0,0 +1,2 @@
1
+ export { C as ClientMessage, t as InferIndex, I as InferLiveObject, c as InferLiveObjectWithRelationalIds, r as InferLiveType, j as LiveNumber, e as LiveObject, L as LiveObjectAny, d as LiveObjectMutationInput, k as LiveString, p as LiveType, q as LiveTypeAny, l as LiveTypeMeta, g as MaterializedLiveObject, M as MaterializedLiveType, m as MutationType, R as Relation, S as Schema, b as ServerMessage, f as createRelations, h as createSchema, i as inferValue, n as number, o as object, s as string } from './index-sSVirsfN.cjs';
2
+ import 'zod';
@@ -0,0 +1,2 @@
1
+ export { C as ClientMessage, t as InferIndex, I as InferLiveObject, c as InferLiveObjectWithRelationalIds, r as InferLiveType, j as LiveNumber, e as LiveObject, L as LiveObjectAny, d as LiveObjectMutationInput, k as LiveString, p as LiveType, q as LiveTypeAny, l as LiveTypeMeta, g as MaterializedLiveObject, M as MaterializedLiveType, m as MutationType, R as Relation, S as Schema, b as ServerMessage, f as createRelations, h as createSchema, i as inferValue, n as number, o as object, s as string } from './index-sSVirsfN.js';
2
+ import 'zod';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ var o=class{_value;_meta;_encodeInput;_decodeInput};var T=class extends o{encodeMutation(n,t,e){throw new Error("Method not implemented.")}mergeMutation(n,t,e){throw new Error("Method not implemented.")}},s=class extends o{constructor(){super(),this.optional=this.optional.bind(this);}optional(){return new T}},y=class a extends s{encodeMutation(n,t,e){return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[{value:Number(t.value),_meta:t._meta},t]}static create(){return new a}},M=y.create,c=class a extends s{encodeMutation(n,t,e){return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[t,t]}static create(){return new a}},h=c.create;var u=class a extends o{name;fields;relations;constructor(n,t,e){super(),this.name=n,this.fields=t,this.relations=e??{};}encodeMutation(n,t,e){return Object.fromEntries(Object.entries(t).map(([r,i])=>[r,(this.fields[r]??this.relations[r]).encodeMutation("set",i,e)]))}mergeMutation(n,t,e){let r={};return [{value:{...(e==null?void 0:e.value)??{},...Object.fromEntries(Object.entries(t).map(([i,d])=>{let[v,m]=(this.fields[i]??this.relations[i]).mergeMutation(n,d,e==null?void 0:e.value[i]);return m&&(r[i]=m),[i,v]}))}},r]}setRelations(n){return new a(this.name,this.fields,n)}static create(n,t){return new a(n,t)}},A=u.create,l=class a extends o{entity;type;required;relationalColumn;foreignColumn;sourceEntity;constructor(n,t,e,r,i){super(),this.entity=n,this.type=t,this.required=i??false,this.relationalColumn=e,this.foreignColumn=r;}encodeMutation(n,t,e){if(n!=="set")throw new Error("Mutation type not implemented.");if(this.type==="many")throw new Error("Many not implemented.");return {value:t,_meta:{timestamp:e}}}mergeMutation(n,t,e){if(this.type==="many")throw new Error("Many not implemented.");return e&&e._meta.timestamp.localeCompare(t._meta.timestamp)>=0?[e,null]:[t,t]}static createOneFactory(){return (n,t,e)=>new a(n,"one",t,void 0,e??false)}static createManyFactory(){return (n,t,e)=>new a(n,"many",void 0,t,e??false)}},K=(a,n)=>({$type:"relations",objectName:a.name,relations:n({one:l.createOneFactory(),many:l.createManyFactory()})}),p=a=>Array.isArray(a.value)?a.value.map(n=>p(n)):typeof a.value!="object"?a.value:Object.fromEntries(Object.entries(a.value).map(([n,t])=>[n,p(t)])),E=a=>Object.fromEntries(Object.entries(a).flatMap(([n,t])=>{if(t.$type==="relations")return [];let e=t,r=Object.values(a).find(i=>i.$type==="relations"&&i.objectName===t.name);return r&&(e=e.setRelations(r.relations)),[[e.name,e]]}));export{y as LiveNumber,u as LiveObject,c as LiveString,o as LiveType,l as Relation,K as createRelations,E as createSchema,p as inferValue,M as number,A as object,h as string};
@@ -0,0 +1 @@
1
+ 'use strict';var nanoid=require('nanoid'),zod=require('zod');var y=class{},S=class extends y{storage={};async updateSchema(e){console.log("Updating schema",e),this.storage=Object.entries(e).reduce((r,[s,i])=>(r[i.name]={},r),{});}async findById(e,r){var s;return (s=this.storage[e])==null?void 0:s[r]}async find(e,r){return this.storage[e]??{}}async upsert(e,r,s){return this.storage[e]??={},this.storage[e][r]=s,s}};var d=zod.z.string().nanoid(),v=zod.z.object({_id:d,type:zod.z.literal("SUBSCRIBE"),resource:zod.z.string()}),q=zod.z.object({_id:d,type:zod.z.literal("SYNC"),lastSyncedAt:zod.z.string().optional(),resources:zod.z.string().array().optional()}),R=zod.z.record(zod.z.object({value:zod.z.string().or(zod.z.number()).or(zod.z.boolean()).or(zod.z.date()),_meta:zod.z.object({timestamp:zod.z.string().optional()}).optional()})).superRefine((a,e)=>{a.id&&e.addIssue({code:zod.z.ZodIssueCode.custom,message:"Payload cannot have an id"});}),T=zod.z.object({_id:d,type:zod.z.literal("MUTATE"),resource:zod.z.string(),resourceId:zod.z.string(),payload:R}),b=zod.z.union([v,T,q]),x=zod.z.object({_id:d,type:zod.z.literal("SYNC"),resource:zod.z.string(),data:zod.z.record(R)}),j=zod.z.object({_id:d,type:zod.z.literal("REJECT"),resource:zod.z.string()});zod.z.union([T,x,j]);var _=a=>{let e={},r={};return a.subscribeToMutations(s=>{console.log("Mutation propagated:",s),Object.entries(r[s.resource]??{}).forEach(([i,p])=>{var o;(o=e[i])==null||o.send(JSON.stringify(s));});}),s=>{let i=nanoid.nanoid();e[i]=s,console.log("Client connected:",i),s.on("message",async p=>{try{console.log("Message received from the client:",p);let o=b.parse(JSON.parse(p.toString()));if(o.type==="SUBSCRIBE"){let{resource:n}=o;r[n]||(r[n]={}),r[n][i]={};}else if(o.type==="SYNC"){let{resources:n}=o,c=n??Object.keys(a.schema);console.log("Syncing resources:",c),await Promise.all(c.map(async u=>{let l=await a.handleRequest({req:{type:"FIND",resourceName:u,context:{}}});if(!l||!l.data)throw new Error("Invalid resource");s.send(JSON.stringify({_id:o._id,type:"SYNC",resource:u,data:Object.fromEntries(Object.entries(l.data??{}).map(([f,M])=>[f,M.value]))}));}));}else if(o.type==="MUTATE"){let{resource:n}=o;console.log("Received mutation from client:",o);try{let c=await a.handleRequest({req:{type:"SET",resourceName:n,payload:o.payload,context:{messageId:o._id},resourceId:o.resourceId}}).catch(u=>(console.error("Error handling mutation from the client:",u),null));(!c||!c.acceptedValues||Object.keys(c.acceptedValues).length===0)&&s.send(JSON.stringify({_id:o._id,type:"REJECT",resource:n}));}catch(c){s.send(JSON.stringify({_id:o._id,type:"REJECT",resource:n})),console.error("Error parsing mutation from the client:",c);}}}catch(o){console.error("Error handling message from the client:",o);}}),s.on("close",()=>{console.log("Connection closed",i),delete e[i];});}};var g=class a{routes;constructor(e){this.routes=e.routes;}static create(e){return new a(e)}},V=a=>g.create({...a}),h=class{shape;constructor(e){this.shape=e;}async handleFind(e){return {data:await e.db.find(e.req.resourceName,e.req.where),acceptedValues:null}}async handleSet(e){if(!e.req.payload)throw new Error("Payload is required");if(!e.req.resourceId)throw new Error("ResourceId is required");let r=await e.db.findById(e.req.resourceName,e.req.resourceId),[s,i]=this.shape.mergeMutation("set",e.req.payload,r);if(!i){if(!r)throw new Error("Mutation rejected");return {data:r,acceptedValues:null}}return {data:await e.db.upsert(e.req.resourceName,e.req.resourceId,s),acceptedValues:i}}async handleRequest(e){switch(e.req.type){case "FIND":return this.handleFind(e);case "SET":return this.handleSet(e);default:throw new Error("Invalid request type")}}},Z=()=>a=>new h(a),m=class a{router;storage;schema;mutationSubscriptions=new Set;constructor(e){this.router=e.router,this.storage=e.storage,this.schema=e.schema,this.storage.updateSchema(this.schema);}static create(e){return new a(e)}subscribeToMutations(e){return this.mutationSubscriptions.add(e),()=>{this.mutationSubscriptions.delete(e);}}async handleRequest(e){var s;let r=await((s=this.router.routes[e.req.resourceName])==null?void 0:s.handleRequest({req:e.req,db:this.storage}));return r&&e.req.type==="SET"&&r.acceptedValues&&Object.keys(r.acceptedValues).length>0&&this.mutationSubscriptions.forEach(i=>{i({_id:e.req.context.messageId??nanoid.nanoid(),type:"MUTATE",resource:e.req.resourceName,payload:r.acceptedValues??{},resourceId:e.req.resourceId});}),r}},k=m.create;exports.InMemoryStorage=S;exports.Route=h;exports.Router=g;exports.Server=m;exports.Storage=y;exports.routeFactory=Z;exports.router=V;exports.server=k;exports.webSocketAdapter=_;
@@ -0,0 +1,88 @@
1
+ import { S as Schema, L as LiveObjectAny, M as MaterializedLiveType, a as MutationMessage } from './index-sSVirsfN.cjs';
2
+ import WebSocket from 'ws';
3
+ import 'zod';
4
+
5
+ declare abstract class Storage {
6
+ abstract updateSchema(opts: Schema<any>): Promise<void>;
7
+ abstract findById<T extends LiveObjectAny>(resourceName: string, id: string): Promise<MaterializedLiveType<T> | undefined>;
8
+ abstract find<T extends LiveObjectAny>(resourceName: string, where?: Record<string, any>): Promise<Record<string, MaterializedLiveType<T>>>;
9
+ abstract upsert<T extends LiveObjectAny>(resourceName: string, resourceId: string, value: MaterializedLiveType<T>): Promise<MaterializedLiveType<T>>;
10
+ }
11
+ declare class InMemoryStorage extends Storage {
12
+ private storage;
13
+ updateSchema(opts: Schema<any>): Promise<void>;
14
+ findById<T extends LiveObjectAny>(resourceName: string, id: string): Promise<MaterializedLiveType<T> | undefined>;
15
+ find<T extends LiveObjectAny>(resourceName: string, where?: Record<string, any>): Promise<Record<string, MaterializedLiveType<T>>>;
16
+ upsert<T extends LiveObjectAny>(resourceName: string, resourceId: string, value: MaterializedLiveType<T>): Promise<MaterializedLiveType<T>>;
17
+ }
18
+
19
+ type Subscription = {
20
+ filters?: Record<string, any>;
21
+ };
22
+ declare const webSocketAdapter: (server: Server<AnyRouter>) => (ws: WebSocket) => void;
23
+
24
+ type RequestBase = {
25
+ resourceName: string;
26
+ context: Record<string, any>;
27
+ where?: Record<string, any>;
28
+ };
29
+ type FindRequest = RequestBase & {
30
+ type: "FIND";
31
+ };
32
+ type SetRequest = RequestBase & {
33
+ type: "SET";
34
+ resourceId: string;
35
+ payload: Record<string, any>;
36
+ };
37
+ type Request = FindRequest | SetRequest;
38
+ type RequestType = Request["type"];
39
+ type RouteRecord = Record<string, Route<LiveObjectAny>>;
40
+ declare class Router<TSchema extends Schema<any>, TRoutes extends RouteRecord> {
41
+ readonly routes: TRoutes;
42
+ private constructor();
43
+ static create<TSchema extends Schema<any>, TRoutes extends RouteRecord>(opts: {
44
+ routes: TRoutes;
45
+ }): Router<TSchema, TRoutes>;
46
+ }
47
+ declare const router: <TSchema extends Schema<any>, TRoutes extends Record<keyof TSchema, Route<LiveObjectAny>>>(opts: {
48
+ schema: TSchema;
49
+ routes: TRoutes;
50
+ }) => Router<Schema<any>, TRoutes>;
51
+ type AnyRouter = Router<Schema<any>, RouteRecord>;
52
+ type RouteResult<TShape extends LiveObjectAny> = {
53
+ data: MaterializedLiveType<TShape> | Record<string, MaterializedLiveType<TShape>>;
54
+ acceptedValues: Record<string, any> | null;
55
+ };
56
+ declare class Route<TShape extends LiveObjectAny> {
57
+ readonly shape: TShape;
58
+ constructor(shape: TShape);
59
+ private handleFind;
60
+ private handleSet;
61
+ handleRequest(opts: {
62
+ req: Request;
63
+ db: Storage;
64
+ }): Promise<RouteResult<TShape>>;
65
+ }
66
+ declare const routeFactory: () => <T extends LiveObjectAny>(shape: T) => Route<T>;
67
+ type AnyRoute = Route<LiveObjectAny>;
68
+ type ClientId = string;
69
+ type MutationHandler = (mutation: MutationMessage) => void;
70
+ declare class Server<TRouter extends AnyRouter> {
71
+ readonly router: TRouter;
72
+ readonly storage: Storage;
73
+ readonly schema: Schema<any>;
74
+ private mutationSubscriptions;
75
+ private constructor();
76
+ static create<TRouter extends AnyRouter>(opts: {
77
+ router: TRouter;
78
+ storage: Storage;
79
+ schema: Schema<any>;
80
+ }): Server<TRouter>;
81
+ subscribeToMutations(handler: MutationHandler): () => void;
82
+ handleRequest(opts: {
83
+ req: Request;
84
+ }): Promise<RouteResult<LiveObjectAny>>;
85
+ }
86
+ declare const server: typeof Server.create;
87
+
88
+ export { type AnyRoute, type AnyRouter, type ClientId, type FindRequest, InMemoryStorage, type MutationHandler, type Request, type RequestType, Route, type RouteRecord, Router, Server, type SetRequest, Storage, type Subscription, routeFactory, router, server, webSocketAdapter };
@@ -0,0 +1,88 @@
1
+ import { S as Schema, L as LiveObjectAny, M as MaterializedLiveType, a as MutationMessage } from './index-sSVirsfN.js';
2
+ import WebSocket from 'ws';
3
+ import 'zod';
4
+
5
+ declare abstract class Storage {
6
+ abstract updateSchema(opts: Schema<any>): Promise<void>;
7
+ abstract findById<T extends LiveObjectAny>(resourceName: string, id: string): Promise<MaterializedLiveType<T> | undefined>;
8
+ abstract find<T extends LiveObjectAny>(resourceName: string, where?: Record<string, any>): Promise<Record<string, MaterializedLiveType<T>>>;
9
+ abstract upsert<T extends LiveObjectAny>(resourceName: string, resourceId: string, value: MaterializedLiveType<T>): Promise<MaterializedLiveType<T>>;
10
+ }
11
+ declare class InMemoryStorage extends Storage {
12
+ private storage;
13
+ updateSchema(opts: Schema<any>): Promise<void>;
14
+ findById<T extends LiveObjectAny>(resourceName: string, id: string): Promise<MaterializedLiveType<T> | undefined>;
15
+ find<T extends LiveObjectAny>(resourceName: string, where?: Record<string, any>): Promise<Record<string, MaterializedLiveType<T>>>;
16
+ upsert<T extends LiveObjectAny>(resourceName: string, resourceId: string, value: MaterializedLiveType<T>): Promise<MaterializedLiveType<T>>;
17
+ }
18
+
19
+ type Subscription = {
20
+ filters?: Record<string, any>;
21
+ };
22
+ declare const webSocketAdapter: (server: Server<AnyRouter>) => (ws: WebSocket) => void;
23
+
24
+ type RequestBase = {
25
+ resourceName: string;
26
+ context: Record<string, any>;
27
+ where?: Record<string, any>;
28
+ };
29
+ type FindRequest = RequestBase & {
30
+ type: "FIND";
31
+ };
32
+ type SetRequest = RequestBase & {
33
+ type: "SET";
34
+ resourceId: string;
35
+ payload: Record<string, any>;
36
+ };
37
+ type Request = FindRequest | SetRequest;
38
+ type RequestType = Request["type"];
39
+ type RouteRecord = Record<string, Route<LiveObjectAny>>;
40
+ declare class Router<TSchema extends Schema<any>, TRoutes extends RouteRecord> {
41
+ readonly routes: TRoutes;
42
+ private constructor();
43
+ static create<TSchema extends Schema<any>, TRoutes extends RouteRecord>(opts: {
44
+ routes: TRoutes;
45
+ }): Router<TSchema, TRoutes>;
46
+ }
47
+ declare const router: <TSchema extends Schema<any>, TRoutes extends Record<keyof TSchema, Route<LiveObjectAny>>>(opts: {
48
+ schema: TSchema;
49
+ routes: TRoutes;
50
+ }) => Router<Schema<any>, TRoutes>;
51
+ type AnyRouter = Router<Schema<any>, RouteRecord>;
52
+ type RouteResult<TShape extends LiveObjectAny> = {
53
+ data: MaterializedLiveType<TShape> | Record<string, MaterializedLiveType<TShape>>;
54
+ acceptedValues: Record<string, any> | null;
55
+ };
56
+ declare class Route<TShape extends LiveObjectAny> {
57
+ readonly shape: TShape;
58
+ constructor(shape: TShape);
59
+ private handleFind;
60
+ private handleSet;
61
+ handleRequest(opts: {
62
+ req: Request;
63
+ db: Storage;
64
+ }): Promise<RouteResult<TShape>>;
65
+ }
66
+ declare const routeFactory: () => <T extends LiveObjectAny>(shape: T) => Route<T>;
67
+ type AnyRoute = Route<LiveObjectAny>;
68
+ type ClientId = string;
69
+ type MutationHandler = (mutation: MutationMessage) => void;
70
+ declare class Server<TRouter extends AnyRouter> {
71
+ readonly router: TRouter;
72
+ readonly storage: Storage;
73
+ readonly schema: Schema<any>;
74
+ private mutationSubscriptions;
75
+ private constructor();
76
+ static create<TRouter extends AnyRouter>(opts: {
77
+ router: TRouter;
78
+ storage: Storage;
79
+ schema: Schema<any>;
80
+ }): Server<TRouter>;
81
+ subscribeToMutations(handler: MutationHandler): () => void;
82
+ handleRequest(opts: {
83
+ req: Request;
84
+ }): Promise<RouteResult<LiveObjectAny>>;
85
+ }
86
+ declare const server: typeof Server.create;
87
+
88
+ export { type AnyRoute, type AnyRouter, type ClientId, type FindRequest, InMemoryStorage, type MutationHandler, type Request, type RequestType, Route, type RouteRecord, Router, Server, type SetRequest, Storage, type Subscription, routeFactory, router, server, webSocketAdapter };