@live-state/sync 0.0.7 → 1.0.0-canary-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-YPTDCIAN.js +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/fetch-client.d.ts +1 -1
- package/dist/fetch-client.js +1 -1
- package/dist/{index-C0Qm5yHg.d.ts → index-DOU7wys1.d.ts} +113 -76
- package/dist/optimistic-client.d.ts +1 -1
- package/dist/server.cjs +5 -5
- package/dist/server.d.cts +202 -240
- package/dist/server.d.ts +202 -240
- package/dist/server.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-LSAVBBUS.js +0 -1
package/dist/server.d.cts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { L as LiveObjectAny, I as IncludeClause,
|
|
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.cjs';
|
|
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
|
|
28
|
+
declare const syncDeltaSchema: z.ZodObject<{
|
|
23
29
|
id: z.ZodOptional<z.ZodString>;
|
|
24
|
-
type: z.ZodLiteral<"
|
|
30
|
+
type: z.ZodLiteral<"SYNC">;
|
|
25
31
|
resource: z.ZodString;
|
|
26
|
-
resourceId: z.
|
|
27
|
-
|
|
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,83 +46,43 @@ declare const defaultMutationSchema: z.ZodObject<{
|
|
|
39
46
|
originMutationId: z.ZodOptional<z.ZodString>;
|
|
40
47
|
}, z.core.$strip>>;
|
|
41
48
|
}, z.core.$strip>;
|
|
42
|
-
type
|
|
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>>[];
|
|
66
|
+
/**
|
|
67
|
+
* Type-only brand recording a {@link QueryBuilder}'s inferable parameters.
|
|
68
|
+
*
|
|
69
|
+
* `CustomQueryResult` (client entry point) has to recognise a query-builder
|
|
70
|
+
* value returned from a route handler whose type flows through the *server*
|
|
71
|
+
* entry point. The two entry points are emitted as separate `.d.ts` graphs, so
|
|
72
|
+
* each gets its own `declare class QueryBuilder`; because the class has
|
|
73
|
+
* `private` members, TypeScript compares those declarations *nominally* and any
|
|
74
|
+
* `extends QueryBuilder<...>` check across the boundary fails. Narrowing on this
|
|
75
|
+
* structural brand instead makes the check independent of class identity — and
|
|
76
|
+
* therefore also of duplicate installed package versions.
|
|
77
|
+
*/
|
|
78
|
+
interface QueryBuilderBrand<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection>, TSingle extends boolean> {
|
|
79
|
+
collection: TCollection;
|
|
80
|
+
include: TInclude;
|
|
81
|
+
single: TSingle;
|
|
82
|
+
}
|
|
118
83
|
declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends IncludeClause<TCollection> = {}, TSingle extends boolean = false, TShouldAwait extends boolean = false> {
|
|
84
|
+
/** Never assigned at runtime; exists only to carry {@link QueryBuilderBrand}. */
|
|
85
|
+
readonly __queryBuilderBrand: QueryBuilderBrand<TCollection, TInclude, TSingle>;
|
|
119
86
|
private _collection;
|
|
120
87
|
private _client;
|
|
121
88
|
private _where;
|
|
@@ -148,6 +115,42 @@ declare class QueryBuilder<TCollection extends LiveObjectAny, TInclude extends I
|
|
|
148
115
|
|
|
149
116
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
150
117
|
|
|
118
|
+
declare abstract class Storage implements DataSource {
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Use db.[collection].one(id).get() instead
|
|
121
|
+
*/
|
|
122
|
+
abstract findOne<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, id: string, options?: {
|
|
123
|
+
include?: TInclude;
|
|
124
|
+
}): Promise<InferLiveObject<T, TInclude> | undefined>;
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated Use db.[collection].where({...}).get() instead
|
|
127
|
+
*/
|
|
128
|
+
abstract find<T extends LiveObjectAny, TInclude extends IncludeClause<T> | undefined = undefined>(resource: T, options?: {
|
|
129
|
+
where?: WhereClause<T>;
|
|
130
|
+
include?: TInclude;
|
|
131
|
+
limit?: number;
|
|
132
|
+
sort?: {
|
|
133
|
+
key: string;
|
|
134
|
+
direction: "asc" | "desc";
|
|
135
|
+
}[];
|
|
136
|
+
}): Promise<InferLiveObject<T, TInclude>[]>;
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated Use db.[collection].insert({...}) instead
|
|
139
|
+
*/
|
|
140
|
+
insert<T extends LiveObjectAny>(resource: T, value: Simplify<InferInsert<T>>): Promise<InferLiveObject<T>>;
|
|
141
|
+
/**
|
|
142
|
+
* @deprecated Use db.[collection].update(id, {...}) instead
|
|
143
|
+
*/
|
|
144
|
+
update<T extends LiveObjectAny>(resource: T, resourceId: string, value: InferUpdate<T>): Promise<Partial<InferLiveObject<T>>>;
|
|
145
|
+
abstract transaction<T>(fn: (opts: {
|
|
146
|
+
trx: Storage;
|
|
147
|
+
commit: () => Promise<void>;
|
|
148
|
+
rollback: () => Promise<void>;
|
|
149
|
+
}) => Promise<T>): Promise<T>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
153
|
+
|
|
151
154
|
/**
|
|
152
155
|
* A QueryBuilder with added insert() and update() mutation methods for server-side use.
|
|
153
156
|
*/
|
|
@@ -214,100 +217,20 @@ type ServerDB<TSchema extends Schema<any>> = {
|
|
|
214
217
|
*/
|
|
215
218
|
declare function createServerDB<TSchema extends Schema<any>>(storage: Storage, schema: TSchema, context?: Record<string, any>): ServerDB<TSchema>;
|
|
216
219
|
|
|
217
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny:
|
|
218
|
-
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
|
220
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: hooks operate generically over any entity shape */
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
};
|
|
222
|
+
/**
|
|
223
|
+
* Database lifecycle hooks.
|
|
224
|
+
*
|
|
225
|
+
* These fire from the storage layer around every committed write (insert /
|
|
226
|
+
* update), regardless of how the write was produced — a custom mutation
|
|
227
|
+
* handler calling `db.x.insert(...)`, a transaction, etc. They are *not* tied
|
|
228
|
+
* to a particular mutation procedure.
|
|
229
|
+
*
|
|
230
|
+
* `before*` handlers may return a transformed raw value to replace what gets
|
|
231
|
+
* persisted; returning `void` leaves the value unchanged. `after*` handlers run
|
|
232
|
+
* once the write is committed.
|
|
233
|
+
*/
|
|
311
234
|
type BeforeInsertHook<TShape extends LiveObjectAny, TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = (opts: {
|
|
312
235
|
ctx?: TContext;
|
|
313
236
|
value: Simplify<InferLiveObjectWithRelationalIds<TShape>> & {
|
|
@@ -354,73 +277,8 @@ type Hooks<TShape extends LiveObjectAny, TSchema extends Schema<any> = Schema<an
|
|
|
354
277
|
beforeUpdate?: BeforeUpdateHook<TShape, TSchema, TContext>;
|
|
355
278
|
afterUpdate?: AfterUpdateHook<TShape, TSchema, TContext>;
|
|
356
279
|
};
|
|
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
280
|
/**
|
|
423
|
-
* Schema-keyed registry of lifecycle hooks.
|
|
281
|
+
* Schema-keyed registry of database lifecycle hooks.
|
|
424
282
|
*
|
|
425
283
|
* Top-level keys are constrained to entity names on `TSchema`. Per-entity
|
|
426
284
|
* payloads (`value`, `rawValue`, `previousValue`, …) are inferred from the
|
|
@@ -430,11 +288,11 @@ type HooksRegistry<TSchema extends Schema<any>, TContext = Record<string, any>>
|
|
|
430
288
|
[K in keyof TSchema]?: TSchema[K] extends LiveObjectAny ? Hooks<TSchema[K], TSchema, TContext> : never;
|
|
431
289
|
};
|
|
432
290
|
/**
|
|
433
|
-
* Declares lifecycle hooks for a schema.
|
|
291
|
+
* Declares database lifecycle hooks for a schema.
|
|
434
292
|
*
|
|
435
293
|
* Identity function whose generic parameters constrain the returned object's
|
|
436
294
|
* top-level keys to schema entity names and thread `TContext` through to
|
|
437
|
-
* handler payloads.
|
|
295
|
+
* handler payloads. Pass the result to `server({ hooks })`.
|
|
438
296
|
*
|
|
439
297
|
* @example
|
|
440
298
|
* ```ts
|
|
@@ -466,6 +324,114 @@ declare const mergeEntityHooks: (slices: Array<AnyHooks | undefined>) => AnyHook
|
|
|
466
324
|
*/
|
|
467
325
|
declare const mergeHooks: <TSchema extends Schema<any>, TContext = Record<string, any>>(...definitions: HooksRegistry<TSchema, TContext>[]) => HooksRegistry<TSchema, TContext>;
|
|
468
326
|
|
|
327
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
328
|
+
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
|
329
|
+
|
|
330
|
+
type AnyRoute = Route<Middleware<any>, Record<string, any>, Record<string, any>, any, any>;
|
|
331
|
+
type RouteRecord = Record<string, AnyRoute>;
|
|
332
|
+
declare class Router<TRoutes extends RouteRecord, TSchema extends Schema<any> = Schema<any>> {
|
|
333
|
+
readonly routes: TRoutes;
|
|
334
|
+
readonly schema: TSchema;
|
|
335
|
+
private constructor();
|
|
336
|
+
static create<TRoutes extends RouteRecord, TSchema extends Schema<any>>(opts: {
|
|
337
|
+
routes: TRoutes;
|
|
338
|
+
schema: TSchema;
|
|
339
|
+
}): Router<TRoutes, TSchema>;
|
|
340
|
+
}
|
|
341
|
+
declare const router: <TSchema extends Schema<any>, TRoutes extends RouteRecord>(opts: {
|
|
342
|
+
schema: TSchema;
|
|
343
|
+
routes: TRoutes;
|
|
344
|
+
}) => Router<TRoutes, TSchema>;
|
|
345
|
+
type AnyRouter = Router<any, any>;
|
|
346
|
+
type Mutation<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
|
|
347
|
+
_type: 'mutation';
|
|
348
|
+
inputValidator: TInputValidator;
|
|
349
|
+
handler: (opts: {
|
|
350
|
+
req: MutationRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
|
|
351
|
+
db: ServerDB<any>;
|
|
352
|
+
}) => TOutput;
|
|
353
|
+
};
|
|
354
|
+
interface QueryProcedureRequest<TInput = any, TContext = Record<string, any>> extends BaseRequest<TContext> {
|
|
355
|
+
type: 'CUSTOM_QUERY';
|
|
356
|
+
input: TInput;
|
|
357
|
+
resource: string;
|
|
358
|
+
procedure: string;
|
|
359
|
+
}
|
|
360
|
+
type Query<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = {
|
|
361
|
+
_type: 'query';
|
|
362
|
+
inputValidator: TInputValidator;
|
|
363
|
+
handler: (opts: {
|
|
364
|
+
req: QueryProcedureRequest<TInputValidator extends StandardSchemaV1<any, any> ? StandardSchemaV1.InferOutput<TInputValidator> : undefined, TContext>;
|
|
365
|
+
db: ServerDB<any>;
|
|
366
|
+
}) => TOutput;
|
|
367
|
+
};
|
|
368
|
+
type Procedure<TInputValidator extends StandardSchemaV1<any, any> | never, TOutput, TContext = Record<string, any>> = Mutation<TInputValidator, TOutput, TContext> | Query<TInputValidator, TOutput, TContext>;
|
|
369
|
+
type QueryCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
|
|
370
|
+
(): {
|
|
371
|
+
handler: <TOutput>(handler: (opts: {
|
|
372
|
+
req: QueryProcedureRequest<undefined, TContext>;
|
|
373
|
+
db: ServerDB<TSchema>;
|
|
374
|
+
}) => TOutput) => Query<StandardSchemaV1<any, undefined>, TOutput, TContext>;
|
|
375
|
+
};
|
|
376
|
+
<TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
|
|
377
|
+
handler: <THandler extends (opts: {
|
|
378
|
+
req: QueryProcedureRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
|
|
379
|
+
db: ServerDB<TSchema>;
|
|
380
|
+
}) => any>(handler: THandler) => Query<TInputValidator, ReturnType<THandler>, TContext>;
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
type MutationCreator<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> = {
|
|
384
|
+
(): {
|
|
385
|
+
handler: <TOutput>(handler: (opts: {
|
|
386
|
+
req: MutationRequest<undefined, TContext>;
|
|
387
|
+
db: ServerDB<TSchema>;
|
|
388
|
+
}) => TOutput) => Mutation<StandardSchemaV1<any, undefined>, TOutput, TContext>;
|
|
389
|
+
};
|
|
390
|
+
<TInputValidator extends StandardSchemaV1<any, any>>(validator: TInputValidator): {
|
|
391
|
+
handler: <THandler extends (opts: {
|
|
392
|
+
req: MutationRequest<StandardSchemaV1.InferOutput<TInputValidator>, TContext>;
|
|
393
|
+
db: ServerDB<TSchema>;
|
|
394
|
+
}) => any>(handler: THandler) => Mutation<TInputValidator, ReturnType<THandler>, TContext>;
|
|
395
|
+
};
|
|
396
|
+
};
|
|
397
|
+
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>> {
|
|
398
|
+
readonly middlewares: Set<TMiddleware>;
|
|
399
|
+
readonly customMutations: TCustomMutations;
|
|
400
|
+
readonly customQueries: TCustomQueries;
|
|
401
|
+
constructor(customMutations?: TCustomMutations, customQueries?: TCustomQueries);
|
|
402
|
+
use(...middlewares: TMiddleware[]): this;
|
|
403
|
+
private wrapInMiddlewares;
|
|
404
|
+
}
|
|
405
|
+
type TypedMiddleware<TContextIn, TContextOut> = {
|
|
406
|
+
_brand: 'TypedMiddleware';
|
|
407
|
+
_rawMiddleware: Middleware<any>;
|
|
408
|
+
_contextIn?: TContextIn;
|
|
409
|
+
_contextOut?: TContextOut;
|
|
410
|
+
};
|
|
411
|
+
declare function createMiddleware<TContextIn, TContextOut = TContextIn>(fn: (opts: {
|
|
412
|
+
ctx: TContextIn;
|
|
413
|
+
req: Request<TContextIn>;
|
|
414
|
+
next: (ctx: TContextOut) => any;
|
|
415
|
+
}) => any): TypedMiddleware<TContextIn, TContextOut>;
|
|
416
|
+
declare class RouteFactory<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>> {
|
|
417
|
+
private middlewares;
|
|
418
|
+
private constructor();
|
|
419
|
+
withProcedures<T extends Record<string, Procedure<any, any, any>>>(procedureFactory: (opts: {
|
|
420
|
+
mutation: MutationCreator<TSchema, TContext>;
|
|
421
|
+
query: QueryCreator<TSchema, TContext>;
|
|
422
|
+
}) => 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>;
|
|
423
|
+
/**
|
|
424
|
+
* @deprecated Use `withProcedures` instead
|
|
425
|
+
*/
|
|
426
|
+
withMutations<T extends Record<string, Mutation<any, any>>>(mutationFactory: (opts: {
|
|
427
|
+
mutation: MutationCreator<TSchema, TContext>;
|
|
428
|
+
}) => 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>;
|
|
429
|
+
use<TNewContext>(mw: TypedMiddleware<TContext, TNewContext>): RouteFactory<TSchema, TNewContext>;
|
|
430
|
+
use(...middlewares: Middleware<any>[]): RouteFactory<TSchema, TContext>;
|
|
431
|
+
static create<TSchema extends Schema<any> = Schema<any>, TContext = Record<string, any>>(): RouteFactory<TSchema, TContext>;
|
|
432
|
+
}
|
|
433
|
+
declare const routeFactory: typeof RouteFactory.create;
|
|
434
|
+
|
|
469
435
|
/** biome-ignore-all lint/suspicious/noExplicitAny: false positive */
|
|
470
436
|
|
|
471
437
|
declare class SQLStorage extends Storage {
|
|
@@ -528,18 +494,18 @@ interface BaseRequest<TContext = Record<string, any>> {
|
|
|
528
494
|
context: TContext;
|
|
529
495
|
}
|
|
530
496
|
interface QueryRequest<TContext = Record<string, any>> extends BaseRequest<TContext>, RawQueryRequest {
|
|
531
|
-
type:
|
|
497
|
+
type: 'QUERY';
|
|
532
498
|
}
|
|
533
499
|
interface MutationRequest<TInput = any, TContext = Record<string, any>> extends BaseRequest<TContext> {
|
|
534
|
-
type:
|
|
500
|
+
type: 'MUTATE';
|
|
535
501
|
input: TInput;
|
|
536
502
|
resource: string;
|
|
537
503
|
resourceId?: string;
|
|
538
504
|
procedure: string;
|
|
539
505
|
}
|
|
540
506
|
type Request<TContext = Record<string, any>> = QueryRequest<TContext> | MutationRequest<any, TContext> | QueryProcedureRequest<any, TContext>;
|
|
541
|
-
type ContextProvider<TContext = Record<string, any>> = (req: Omit<BaseRequest,
|
|
542
|
-
transport:
|
|
507
|
+
type ContextProvider<TContext = Record<string, any>> = (req: Omit<BaseRequest, 'context'> & {
|
|
508
|
+
transport: 'HTTP' | 'WEBSOCKET';
|
|
543
509
|
}) => TContext | Promise<TContext>;
|
|
544
510
|
type NextFunction<O, R = Request> = (req: R) => PromiseOrSync<O>;
|
|
545
511
|
type Middleware<T = any> = (opts: {
|
|
@@ -575,16 +541,12 @@ declare class Server<TRouter extends AnyRouter, TContext = Record<string, any>>
|
|
|
575
541
|
logLevel?: LogLevel;
|
|
576
542
|
}): Server<TRouter, Record<string, any>>;
|
|
577
543
|
getHooks(resourceName: string): Hooks<any, any, any> | undefined;
|
|
578
|
-
handleQuery(opts: {
|
|
579
|
-
req: QueryRequest;
|
|
580
|
-
subscription?: (mutation: DefaultMutation) => void;
|
|
581
|
-
}): Promise<QueryResult<any>>;
|
|
582
544
|
handleMutation(opts: {
|
|
583
545
|
req: MutationRequest;
|
|
584
546
|
}): Promise<any>;
|
|
585
547
|
handleCustomQuery(opts: {
|
|
586
548
|
req: QueryProcedureRequest;
|
|
587
|
-
subscription?: (mutation:
|
|
549
|
+
subscription?: (mutation: SyncDelta) => void;
|
|
588
550
|
}): Promise<any>;
|
|
589
551
|
use(middleware: Middleware<any>): this;
|
|
590
552
|
context(contextProvider: ContextProvider<TContext>): this;
|
|
@@ -593,4 +555,4 @@ declare class Server<TRouter extends AnyRouter, TContext = Record<string, any>>
|
|
|
593
555
|
}
|
|
594
556
|
declare const server: typeof Server.create;
|
|
595
557
|
|
|
596
|
-
export { type AfterInsertHook, type AfterUpdateHook, type
|
|
558
|
+
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 };
|