@live-state/sync 0.0.7-pr-4 → 1.0.0-canary-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.
package/dist/server.d.ts CHANGED
@@ -1,14 +1,20 @@
1
1
  import { z } from 'zod';
2
- import { L as LiveObjectAny, I as IncludeClause, a as InferLiveObject, W as WhereClause, S as Simplify, b as InferInsert, c as InferUpdate, M as MaterializedLiveType, d as Schema, e as LiveCollectionAny, f as InferLiveCollection, g as InferLiveObjectWithRelationalIds, h as Logger, i as LogLevel } from './index-hO1iQ-VU.js';
2
+ import { L as LiveObjectAny, I as IncludeClause, W as WhereClause, S as Simplify, a as InferLiveObject, b as InferInsert, c as InferUpdate, d as Schema, e as LiveCollectionAny, f as InferLiveCollection, g as InferLiveObjectWithRelationalIds, M as MaterializedLiveType, h as Logger, i as LogLevel } from './index-hO1iQ-VU.js';
3
3
  import { StandardSchemaV1 } from '@standard-schema/spec';
4
4
  import { PostgresPool, Kysely } from 'kysely';
5
5
  import { Application } from 'express-ws';
6
6
 
7
+ /**
8
+ * Internal Tracked Query representation. A Custom Query handler returns an
9
+ * unresolved query builder; the server mints a `RawQueryRequest` from it via
10
+ * `buildQueryRequest()`, which the query engine subscribes and resolves against
11
+ * storage. This is **not** an inbound client→server message — clients can only
12
+ * invoke named Custom Query procedures (see ADR-0002).
13
+ */
7
14
  declare const querySchema: z.ZodObject<{
8
15
  resource: z.ZodString;
9
16
  where: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
10
17
  include: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
11
- lastSyncedAt: z.ZodOptional<z.ZodString>;
12
18
  limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
13
19
  sort: z.ZodOptional<z.ZodArray<z.ZodObject<{
14
20
  key: z.ZodString;
@@ -19,14 +25,15 @@ declare const querySchema: z.ZodObject<{
19
25
  }, z.core.$strip>>>;
20
26
  }, z.core.$strip>;
21
27
  type RawQueryRequest = z.infer<typeof querySchema>;
22
- declare const defaultMutationSchema: z.ZodObject<{
28
+ declare const syncDeltaSchema: z.ZodObject<{
23
29
  id: z.ZodOptional<z.ZodString>;
24
- type: z.ZodLiteral<"MUTATE">;
30
+ type: z.ZodLiteral<"SYNC">;
25
31
  resource: z.ZodString;
26
- resourceId: z.ZodOptional<z.ZodString>;
27
- procedure: z.ZodEnum<{
32
+ resourceId: z.ZodString;
33
+ op: z.ZodEnum<{
28
34
  INSERT: "INSERT";
29
35
  UPDATE: "UPDATE";
36
+ DELETE: "DELETE";
30
37
  }>;
31
38
  payload: z.ZodRecord<z.ZodString, z.ZodObject<{
32
39
  value: z.ZodNullable<z.ZodAny>;
@@ -39,81 +46,22 @@ declare const defaultMutationSchema: z.ZodObject<{
39
46
  originMutationId: z.ZodOptional<z.ZodString>;
40
47
  }, z.core.$strip>>;
41
48
  }, z.core.$strip>;
42
- type DefaultMutation = Omit<z.infer<typeof defaultMutationSchema>, "resourceId"> & {
43
- resourceId: string;
44
- };
49
+ type SyncDelta = z.infer<typeof syncDeltaSchema>;
45
50
 
46
51
  type ConditionalPromise<T, P extends boolean> = P extends true ? Promise<T> : T;
47
52
  type PromiseOrSync<T> = T | Promise<T>;
48
53
 
49
- /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
50
-
51
- declare abstract class Storage implements DataSource {
52
- /**
53
- * @deprecated Use db.[collection].one(id).get() instead
54
- */
55
- abstract findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
56
- include?: TInclude;
57
- }): Promise<InferLiveObject<T, TInclude> | undefined>;
58
- /**
59
- * @deprecated Use db.[collection].where({...}).get() instead
60
- */
61
- abstract find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
62
- where?: WhereClause<T>;
63
- include?: TInclude;
64
- limit?: number;
65
- sort?: {
66
- key: string;
67
- direction: "asc" | "desc";
68
- }[];
69
- }): Promise<InferLiveObject<T, TInclude>[]>;
70
- /**
71
- * @deprecated Use db.[collection].insert({...}) instead
72
- */
73
- insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
74
- /**
75
- * @deprecated Use db.[collection].update(id, {...}) instead
76
- */
77
- update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
78
- abstract transaction<T>(fn: (opts: {
79
- trx: Storage;
80
- commit: () => Promise<void>;
81
- rollback: () => Promise<void>;
82
- }) => Promise<T>): Promise<T>;
83
- }
84
-
85
- /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
86
-
87
- declare class Batcher {
88
- private storage;
89
- private queue;
90
- private scheduled;
91
- constructor(storage: Storage);
92
- rawFind<T extends LiveObjectAny>({ resource, commonWhere, uniqueWhere, ...rest }: {
93
- resource: string;
94
- commonWhere?: Record<string, any>;
95
- uniqueWhere?: Record<string, any>;
96
- include?: Record<string, any>;
97
- limit?: number;
98
- sort?: {
99
- key: string;
100
- direction: "asc" | "desc";
101
- }[];
102
- }): Promise<MaterializedLiveType<T>[]>;
103
- private getBatchKey;
104
- private processBatch;
105
- private executeBatchedRequests;
106
- }
107
-
108
54
  interface DataSource {
109
55
  get(query: RawQueryRequest, extra?: {
110
56
  context?: any;
111
- batcher?: Batcher;
112
57
  }): PromiseOrSync<any[]>;
113
58
  }
114
59
 
115
60
  /** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */
116
61
 
62
+ interface QueryExecutor extends DataSource {
63
+ subscribe(query: RawQueryRequest, callback: (value: any[]) => void): () => void;
64
+ }
117
65
  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>>[];
118
66
  declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false, TShouldAwait extends boolean = false> {
119
67
  private _collection;
@@ -148,6 +96,42 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
148
96
 
149
97
  /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
150
98
 
99
+ declare abstract class Storage implements DataSource {
100
+ /**
101
+ * @deprecated Use db.[collection].one(id).get() instead
102
+ */
103
+ abstract findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
104
+ include?: TInclude;
105
+ }): Promise<InferLiveObject<T, TInclude> | undefined>;
106
+ /**
107
+ * @deprecated Use db.[collection].where({...}).get() instead
108
+ */
109
+ abstract find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
110
+ where?: WhereClause<T>;
111
+ include?: TInclude;
112
+ limit?: number;
113
+ sort?: {
114
+ key: string;
115
+ direction: "asc" | "desc";
116
+ }[];
117
+ }): Promise<InferLiveObject<T, TInclude>[]>;
118
+ /**
119
+ * @deprecated Use db.[collection].insert({...}) instead
120
+ */
121
+ insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
122
+ /**
123
+ * @deprecated Use db.[collection].update(id, {...}) instead
124
+ */
125
+ update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
126
+ abstract transaction<T>(fn: (opts: {
127
+ trx: Storage;
128
+ commit: () => Promise<void>;
129
+ rollback: () => Promise<void>;
130
+ }) => Promise<T>): Promise<T>;
131
+ }
132
+
133
+ /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
134
+
151
135
  /**
152
136
  * A QueryBuilder with added insert() and update() mutation methods for server-side use.
153
137
  */
@@ -214,100 +198,20 @@ type ServerDB<TSchema extends Schema<any>> = {
214
198
  */
215
199
  declare function createServerDB<TSchema extends Schema<any>>(storage: Storage, schema: TSchema, context?: Record<string, any>): ServerDB<TSchema>;
216
200
 
217
- /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
218
- /** biome-ignore-all lint/style/noNonNullAssertion: false positive */
201
+ /** biome-ignore-all lint/suspicious/noExplicitAny: hooks operate generically over any entity shape */
219
202
 
220
- type AnyProcedureRoute = ProcedureRoute<Middleware<any>, Record<string, any>, Record<string, any>, any, any>;
221
- type AnyRouteOrProcedure = AnyRoute | AnyProcedureRoute;
222
- type RouteRecord = Record<string, AnyRouteOrProcedure>;
223
- declare class Router<TRoutes extends RouteRecord> {
224
- readonly routes: TRoutes;
225
- readonly hooksRegistry: Map<string, Hooks<any, any, any>>;
226
- private constructor();
227
- static create<TRoutes extends RouteRecord>(opts: {
228
- routes: TRoutes;
229
- }): Router<TRoutes>;
230
- getHooks(resourceName: string): Hooks<any, any, any> | undefined;
231
- }
232
- declare const router: <TSchema extends Schema<any>, TRoutes extends Record<keyof TSchema, Route<any, any, any, any, any, any>> & Record<string, Route<any, any, any, any, any, any> | ProcedureRoute<any, any, any, any, any>>>(opts: {
233
- schema: TSchema;
234
- routes: TRoutes;
235
- }) => Router<TRoutes>;
236
- type AnyRouter = Router<any>;
237
- type QueryResult<TShape extends LiveObjectAny> = {
238
- data: MaterializedLiveType<TShape>[];
239
- unsubscribe?: () => void;
240
- };
241
- type MutationResult<TShape extends LiveObjectAny> = {
242
- data: MaterializedLiveType<TShape>;
243
- acceptedValues: Record<string, any> | null;
244
- };
245
- type Mutation<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
246
- _type: "mutation";
247
- inputValidator: TInputValidator;
248
- handler: (opts: {
249
- req: MutationRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
250
- db: ServerDB<any>;
251
- }) => TOutput;
252
- };
253
- interface QueryProcedureRequest<TInput = any, TContext = Record<string, any>> extends BaseRequest<TContext> {
254
- type: "CUSTOM_QUERY";
255
- input: TInput;
256
- resource: string;
257
- procedure: string;
258
- }
259
- type Query<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
260
- _type: "query";
261
- inputValidator: TInputValidator;
262
- handler: (opts: {
263
- req: QueryProcedureRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
264
- db: ServerDB<any>;
265
- }) => TOutput;
266
- };
267
- type Procedure<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = Mutation<TInputValidator, TOutput, TContext> | Query<TInputValidator, TOutput, TContext>;
268
- type QueryCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
269
- (): {
270
- handler: <TOutput>(handler: (opts: {
271
- req: QueryProcedureRequest<undefined, TContext>;
272
- db: ServerDB<TSchema>;
273
- }) => TOutput) => Query<StandardSchemaV1<any, undefined>, TOutput, TContext>;
274
- };
275
- <TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
276
- handler: <THandler extends (opts: {
277
- req: QueryProcedureRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
278
- db: ServerDB<TSchema>;
279
- }) => any>(handler: THandler) => Query<TInputValidator, ReturnType<THandler>, TContext>;
280
- };
281
- };
282
- type MutationCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
283
- (): {
284
- handler: <TOutput>(handler: (opts: {
285
- req: MutationRequest<undefined, TContext>;
286
- db: ServerDB<TSchema>;
287
- }) => TOutput) => Mutation<StandardSchemaV1<any, undefined>, TOutput, TContext>;
288
- };
289
- <TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
290
- handler: <THandler extends (opts: {
291
- req: MutationRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
292
- db: ServerDB<TSchema>;
293
- }) => any>(handler: THandler) => Mutation<TInputValidator, ReturnType<THandler>, TContext>;
294
- };
295
- };
296
- type ReadAuthorizationHandler<TShape extends LiveObjectAny, TContext = Record<string, any>> = (opts: {
297
- ctx: TContext;
298
- }) => WhereClause<TShape> | boolean;
299
- type MutationAuthorizationHandler<TShape extends LiveObjectAny, TContext = Record<string, any>> = (opts: {
300
- ctx: TContext;
301
- value: Simplify<InferLiveObjectWithRelationalIds<TShape>>;
302
- }) => WhereClause<TShape> | boolean;
303
- type Authorization<TShape extends LiveObjectAny, TContext = Record<string, any>> = {
304
- read?: ReadAuthorizationHandler<TShape, TContext>;
305
- insert?: MutationAuthorizationHandler<TShape, TContext>;
306
- update?: {
307
- preMutation?: MutationAuthorizationHandler<TShape, TContext>;
308
- postMutation?: MutationAuthorizationHandler<TShape, TContext>;
309
- };
310
- };
203
+ /**
204
+ * Database lifecycle hooks.
205
+ *
206
+ * These fire from the storage layer around every committed write (insert /
207
+ * update), regardless of how the write was produced — a custom mutation
208
+ * handler calling `db.x.insert(...)`, a transaction, etc. They are *not* tied
209
+ * to a particular mutation procedure.
210
+ *
211
+ * `before*` handlers may return a transformed raw value to replace what gets
212
+ * persisted; returning `void` leaves the value unchanged. `after*` handlers run
213
+ * once the write is committed.
214
+ */
311
215
  type BeforeInsertHook<TShape extends LiveObjectAny, TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = (opts: {
312
216
  ctx?: TContext;
313
217
  value: Simplify<InferLiveObjectWithRelationalIds<TShape>> & {
@@ -354,73 +258,8 @@ type Hooks<TShape extends LiveObjectAny, TSchema extends Schema<any> = Schema<an
354
258
  beforeUpdate?: BeforeUpdateHook<TShape, TSchema, TContext>;
355
259
  afterUpdate?: AfterUpdateHook<TShape, TSchema, TContext>;
356
260
  };
357
- declare class Route<TResourceSchema extends LiveObjectAny, TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, any>>, TCustomQueries extends Record<string, Query<any, any>>, TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
358
- readonly resourceSchema: TResourceSchema;
359
- readonly middlewares: Set<TMiddleware>;
360
- readonly customMutations: TCustomMutations;
361
- readonly customQueries: TCustomQueries;
362
- readonly authorization?: Authorization<TResourceSchema, TContext>;
363
- readonly hooks?: Hooks<TResourceSchema, TSchema, TContext>;
364
- constructor(resourceSchema: TResourceSchema, customMutations?: TCustomMutations, customQueries?: TCustomQueries, authorization?: Authorization<TResourceSchema, TContext>, hooks?: Hooks<TResourceSchema, TSchema, TContext>);
365
- use(...middlewares: TMiddleware[]): this;
366
- withProcedures<T extends Record<string, Procedure<any, any, any>>>(procedureFactory: (opts: {
367
- mutation: MutationCreator<TSchema, TContext>;
368
- query: QueryCreator<TSchema, TContext>;
369
- }) => T): Route<TResourceSchema, TMiddleware, { [K in keyof T as T[K] extends Mutation<any, any, Record<string, any>> ? K : never]: Extract<T[K], Mutation<any, any, Record<string, any>>>; }, { [K_1 in keyof T as T[K_1] extends Query<any, any, Record<string, any>> ? K_1 : never]: Extract<T[K_1], Query<any, any, Record<string, any>>>; }, TSchema, TContext>;
370
- /**
371
- * @deprecated Use `withProcedures` instead
372
- */
373
- withMutations<T extends Record<string, Mutation<any, any>>>(mutationFactory: (opts: {
374
- mutation: MutationCreator<TSchema, TContext>;
375
- }) => T): Route<TResourceSchema, TMiddleware, { [K in keyof T as T[K] extends Mutation<any, any, Record<string, any>> ? K : never]: Extract<T[K], Mutation<any, any, Record<string, any>>>; }, { [K_1 in keyof T as T[K_1] extends Query<any, any, Record<string, any>> ? K_1 : never]: Extract<T[K_1], Query<any, any, Record<string, any>>>; }, TSchema, TContext>;
376
- /**
377
- * @deprecated Declare hooks with `defineHooks` and pass them to `server({ hooks })` instead.
378
- */
379
- withHooks(hooks: Hooks<TResourceSchema, TSchema, TContext>): Route<TResourceSchema, TMiddleware, TCustomMutations, TCustomQueries, TSchema, TContext>;
380
- getAuthorizationClause(req: QueryRequest): WhereClause<TResourceSchema> | undefined | boolean;
381
- private handleSet;
382
- private wrapInMiddlewares;
383
- }
384
- declare class ProcedureRoute<TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, any>>, TCustomQueries extends Record<string, Query<any, any>>, TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
385
- readonly resourceSchema: undefined;
386
- readonly middlewares: Set<TMiddleware>;
387
- readonly customMutations: TCustomMutations;
388
- readonly customQueries: TCustomQueries;
389
- constructor(customMutations?: TCustomMutations, customQueries?: TCustomQueries);
390
- use(...middlewares: TMiddleware[]): this;
391
- getAuthorizationClause(): undefined;
392
- private wrapInMiddlewares;
393
- }
394
- type TypedMiddleware<TContextIn, TContextOut> = {
395
- _brand: "TypedMiddleware";
396
- _rawMiddleware: Middleware<any>;
397
- _contextIn?: TContextIn;
398
- _contextOut?: TContextOut;
399
- };
400
- declare function createMiddleware<TContextIn, TContextOut = TContextIn>(fn: (opts: {
401
- ctx: TContextIn;
402
- req: Request<TContextIn>;
403
- next: (ctx: TContextOut) => any;
404
- }) => any): TypedMiddleware<TContextIn, TContextOut>;
405
- declare class RouteFactory<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
406
- private middlewares;
407
- private constructor();
408
- collectionRoute<T extends LiveObjectAny>(shape: T, authorization?: Authorization<T, TContext>): Route<T, Middleware<any>, Record<string, never>, Record<string, never>, TSchema, TContext>;
409
- withProcedures<T extends Record<string, Procedure<any, any, any>>>(procedureFactory: (opts: {
410
- mutation: MutationCreator<TSchema, TContext>;
411
- query: QueryCreator<TSchema, TContext>;
412
- }) => T): ProcedureRoute<Middleware<any>, { [K in keyof T as T[K] extends Mutation<any, any, Record<string, any>> ? K : never]: T[K]; } & Record<string, Mutation<any, any, Record<string, any>>>, { [K_1 in keyof T as T[K_1] extends Query<any, any, Record<string, any>> ? K_1 : never]: T[K_1]; } & Record<string, Query<any, any, Record<string, any>>>, TSchema, TContext>;
413
- use<TNewContext>(mw: TypedMiddleware<TContext, TNewContext>): RouteFactory<TSchema, TNewContext>;
414
- use(...middlewares: Middleware<any>[]): RouteFactory<TSchema, TContext>;
415
- static create<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>>(): RouteFactory<TSchema, TContext>;
416
- }
417
- declare const routeFactory: typeof RouteFactory.create;
418
- type AnyRoute = Route<LiveObjectAny, Middleware<any>, Record<string, any>, Record<string, any>, any, any>;
419
-
420
- /** biome-ignore-all lint/suspicious/noExplicitAny: hooks operate generically over any entity shape */
421
-
422
261
  /**
423
- * Schema-keyed registry of lifecycle hooks.
262
+ * Schema-keyed registry of database lifecycle hooks.
424
263
  *
425
264
  * Top-level keys are constrained to entity names on `TSchema`. Per-entity
426
265
  * payloads (`value`, `rawValue`, `previousValue`, …) are inferred from the
@@ -430,11 +269,11 @@ type HooksRegistry<TSchema extends Schema<any>, TContext = Record<string, any>>
430
269
  [K in keyof TSchema]?: TSchema[K] extends LiveObjectAny ? Hooks<TSchema[K], TSchema, TContext> : never;
431
270
  };
432
271
  /**
433
- * Declares lifecycle hooks for a schema.
272
+ * Declares database lifecycle hooks for a schema.
434
273
  *
435
274
  * Identity function whose generic parameters constrain the returned object's
436
275
  * top-level keys to schema entity names and thread `TContext` through to
437
- * handler payloads.
276
+ * handler payloads. Pass the result to `server({ hooks })`.
438
277
  *
439
278
  * @example
440
279
  * ```ts
@@ -466,6 +305,114 @@ declare const mergeEntityHooks: (slices: Array<AnyHooks | undefined>) => AnyHook
466
305
  */
467
306
  declare const mergeHooks: <TSchema extends Schema<any>, TContext = Record<string, any>>(...definitions: HooksRegistry<TSchema, TContext>[]) => HooksRegistry<TSchema, TContext>;
468
307
 
308
+ /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
309
+ /** biome-ignore-all lint/style/noNonNullAssertion: false positive */
310
+
311
+ type AnyRoute = Route<Middleware<any>, Record<string, any>, Record<string, any>, any, any>;
312
+ type RouteRecord = Record<string, AnyRoute>;
313
+ declare class Router<TRoutes extends RouteRecord, TSchema extends Schema<any> = Schema<any>> {
314
+ readonly routes: TRoutes;
315
+ readonly schema: TSchema;
316
+ private constructor();
317
+ static create<TRoutes extends RouteRecord, TSchema extends Schema<any>>(opts: {
318
+ routes: TRoutes;
319
+ schema: TSchema;
320
+ }): Router<TRoutes, TSchema>;
321
+ }
322
+ declare const router: <TSchema extends Schema<any>, TRoutes extends RouteRecord>(opts: {
323
+ schema: TSchema;
324
+ routes: TRoutes;
325
+ }) => Router<TRoutes, TSchema>;
326
+ type AnyRouter = Router<any, any>;
327
+ type Mutation<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
328
+ _type: 'mutation';
329
+ inputValidator: TInputValidator;
330
+ handler: (opts: {
331
+ req: MutationRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
332
+ db: ServerDB<any>;
333
+ }) => TOutput;
334
+ };
335
+ interface QueryProcedureRequest<TInput = any, TContext = Record<string, any>> extends BaseRequest<TContext> {
336
+ type: 'CUSTOM_QUERY';
337
+ input: TInput;
338
+ resource: string;
339
+ procedure: string;
340
+ }
341
+ type Query<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
342
+ _type: 'query';
343
+ inputValidator: TInputValidator;
344
+ handler: (opts: {
345
+ req: QueryProcedureRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
346
+ db: ServerDB<any>;
347
+ }) => TOutput;
348
+ };
349
+ type Procedure<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = Mutation<TInputValidator, TOutput, TContext> | Query<TInputValidator, TOutput, TContext>;
350
+ type QueryCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
351
+ (): {
352
+ handler: <TOutput>(handler: (opts: {
353
+ req: QueryProcedureRequest<undefined, TContext>;
354
+ db: ServerDB<TSchema>;
355
+ }) => TOutput) => Query<StandardSchemaV1<any, undefined>, TOutput, TContext>;
356
+ };
357
+ <TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
358
+ handler: <THandler extends (opts: {
359
+ req: QueryProcedureRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
360
+ db: ServerDB<TSchema>;
361
+ }) => any>(handler: THandler) => Query<TInputValidator, ReturnType<THandler>, TContext>;
362
+ };
363
+ };
364
+ type MutationCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
365
+ (): {
366
+ handler: <TOutput>(handler: (opts: {
367
+ req: MutationRequest<undefined, TContext>;
368
+ db: ServerDB<TSchema>;
369
+ }) => TOutput) => Mutation<StandardSchemaV1<any, undefined>, TOutput, TContext>;
370
+ };
371
+ <TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
372
+ handler: <THandler extends (opts: {
373
+ req: MutationRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
374
+ db: ServerDB<TSchema>;
375
+ }) => any>(handler: THandler) => Mutation<TInputValidator, ReturnType<THandler>, TContext>;
376
+ };
377
+ };
378
+ declare class Route<TMiddleware extends Middleware<any>, TCustomMutations extends Record<string, Mutation<any, any>>, TCustomQueries extends Record<string, Query<any, any>>, TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
379
+ readonly middlewares: Set<TMiddleware>;
380
+ readonly customMutations: TCustomMutations;
381
+ readonly customQueries: TCustomQueries;
382
+ constructor(customMutations?: TCustomMutations, customQueries?: TCustomQueries);
383
+ use(...middlewares: TMiddleware[]): this;
384
+ private wrapInMiddlewares;
385
+ }
386
+ type TypedMiddleware<TContextIn, TContextOut> = {
387
+ _brand: 'TypedMiddleware';
388
+ _rawMiddleware: Middleware<any>;
389
+ _contextIn?: TContextIn;
390
+ _contextOut?: TContextOut;
391
+ };
392
+ declare function createMiddleware<TContextIn, TContextOut = TContextIn>(fn: (opts: {
393
+ ctx: TContextIn;
394
+ req: Request<TContextIn>;
395
+ next: (ctx: TContextOut) => any;
396
+ }) => any): TypedMiddleware<TContextIn, TContextOut>;
397
+ declare class RouteFactory<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
398
+ private middlewares;
399
+ private constructor();
400
+ withProcedures<T extends Record<string, Procedure<any, any, any>>>(procedureFactory: (opts: {
401
+ mutation: MutationCreator<TSchema, TContext>;
402
+ query: QueryCreator<TSchema, TContext>;
403
+ }) => T): Route<Middleware<any>, { [K in keyof T as T[K] extends Mutation<any, any, Record<string, any>> ? K : never]: Extract<T[K], Mutation<any, any, Record<string, any>>>; }, { [K_1 in keyof T as T[K_1] extends Query<any, any, Record<string, any>> ? K_1 : never]: Extract<T[K_1], Query<any, any, Record<string, any>>>; }, TSchema, TContext>;
404
+ /**
405
+ * @deprecated Use `withProcedures` instead
406
+ */
407
+ withMutations<T extends Record<string, Mutation<any, any>>>(mutationFactory: (opts: {
408
+ mutation: MutationCreator<TSchema, TContext>;
409
+ }) => T): Route<Middleware<any>, { [K in keyof T as T[K] extends Mutation<any, any, Record<string, any>> ? K : never]: Extract<T[K], Mutation<any, any, Record<string, any>>>; }, { [K_1 in keyof T as T[K_1] extends Query<any, any, Record<string, any>> ? K_1 : never]: Extract<T[K_1], Query<any, any, Record<string, any>>>; }, TSchema, TContext>;
410
+ use<TNewContext>(mw: TypedMiddleware<TContext, TNewContext>): RouteFactory<TSchema, TNewContext>;
411
+ use(...middlewares: Middleware<any>[]): RouteFactory<TSchema, TContext>;
412
+ static create<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>>(): RouteFactory<TSchema, TContext>;
413
+ }
414
+ declare const routeFactory: typeof RouteFactory.create;
415
+
469
416
  /** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
470
417
 
471
418
  declare class SQLStorage extends Storage {
@@ -528,18 +475,18 @@ interface BaseRequest<TContext = Record<string, any>> {
528
475
  context: TContext;
529
476
  }
530
477
  interface QueryRequest<TContext = Record<string, any>> extends BaseRequest<TContext>, RawQueryRequest {
531
- type: "QUERY";
478
+ type: 'QUERY';
532
479
  }
533
480
  interface MutationRequest<TInput = any, TContext = Record<string, any>> extends BaseRequest<TContext> {
534
- type: "MUTATE";
481
+ type: 'MUTATE';
535
482
  input: TInput;
536
483
  resource: string;
537
484
  resourceId?: string;
538
485
  procedure: string;
539
486
  }
540
487
  type Request<TContext = Record<string, any>> = QueryRequest<TContext> | MutationRequest<any, TContext> | QueryProcedureRequest<any, TContext>;
541
- type ContextProvider<TContext = Record<string, any>> = (req: Omit<BaseRequest, "context"> & {
542
- transport: "HTTP" | "WEBSOCKET";
488
+ type ContextProvider<TContext = Record<string, any>> = (req: Omit<BaseRequest, 'context'> & {
489
+ transport: 'HTTP' | 'WEBSOCKET';
543
490
  }) => TContext | Promise<TContext>;
544
491
  type NextFunction<O, R = Request> = (req: R) => PromiseOrSync<O>;
545
492
  type Middleware<T = any> = (opts: {
@@ -575,16 +522,12 @@ declare class Server<TRouter extends AnyRouter, TContext = Record<string, any>>
575
522
  logLevel?: LogLevel;
576
523
  }): Server<TRouter, Record<string, any>>;
577
524
  getHooks(resourceName: string): Hooks<any, any, any> | undefined;
578
- handleQuery(opts: {
579
- req: QueryRequest;
580
- subscription?: (mutation: DefaultMutation) => void;
581
- }): Promise<QueryResult<any>>;
582
525
  handleMutation(opts: {
583
526
  req: MutationRequest;
584
527
  }): Promise<any>;
585
528
  handleCustomQuery(opts: {
586
529
  req: QueryProcedureRequest;
587
- subscription?: (mutation: DefaultMutation) => void;
530
+ subscription?: (mutation: SyncDelta) => void;
588
531
  }): Promise<any>;
589
532
  use(middleware: Middleware<any>): this;
590
533
  context(contextProvider: ContextProvider<TContext>): this;
@@ -593,4 +536,4 @@ declare class Server<TRouter extends AnyRouter, TContext = Record<string, any>>
593
536
  }
594
537
  declare const server: typeof Server.create;
595
538
 
596
- export { type AfterInsertHook, type AfterUpdateHook, type AnyProcedureRoute, type AnyRoute, type AnyRouteOrProcedure, type AnyRouter, type Authorization, type BaseRequest, type BeforeInsertHook, type BeforeUpdateHook, type ContextProvider, type Hooks, type HooksRegistry, type Middleware, type Mutation, type MutationAuthorizationHandler, type MutationRequest, type MutationResult, type NextFunction, type Procedure, ProcedureRoute, type Query, type QueryProcedureRequest, type QueryRequest, type QueryResult, type ReadAuthorizationHandler, type Request, Route, RouteFactory, type RouteRecord, Router, SQLStorage, Server, type ServerCollection, type ServerDB, Storage, type TypedMiddleware, createMiddleware, createServerDB, defineHooks, expressAdapter, mergeEntityHooks, mergeHooks, routeFactory, router, server };
539
+ export { type AfterInsertHook, type AfterUpdateHook, type AnyRoute, type AnyRouter, type BaseRequest, type BeforeInsertHook, type BeforeUpdateHook, type ContextProvider, type Hooks, type HooksRegistry, type Middleware, type Mutation, type MutationRequest, type NextFunction, type Procedure, type Query, QueryBuilder, type QueryExecutor, type QueryProcedureRequest, type QueryRequest, type Request, Route, RouteFactory, type RouteRecord, Router, SQLStorage, Server, type ServerCollection, type ServerDB, Storage, type TypedMiddleware, createMiddleware, createServerDB, defineHooks, expressAdapter, mergeEntityHooks, mergeHooks, routeFactory, router, server };