foldkit-remote 0.2.0 → 0.4.0
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/README.md +877 -446
- package/dist/index.d.mts +445 -172
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1537 -1276
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,64 @@
|
|
|
1
1
|
import { Context, Duration, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
2
|
-
import
|
|
2
|
+
import * as Domain from "foldkit-entity";
|
|
3
|
+
import { EntryWithoutKeepAlive } from "foldkit/subscription";
|
|
4
|
+
import { ActiveSurface, Contract, Invalid, Metadata, ModelRef, Projection, Surface, Wiring } from "foldkit-surface";
|
|
3
5
|
import { Rpc, RpcGroup } from "effect/unstable/rpc";
|
|
4
6
|
import { KeyValueStore } from "effect/unstable/persistence";
|
|
5
7
|
import { Command } from "foldkit/command";
|
|
6
|
-
|
|
8
|
+
//#region ../metadata/dist/index.d.mts
|
|
9
|
+
//#region src/index.d.ts
|
|
10
|
+
/** Marks a `Metadata` value. Its entries are private to this module. */
|
|
11
|
+
declare const MetadataTypeId: unique symbol;
|
|
12
|
+
type MetadataTypeId = typeof MetadataTypeId;
|
|
13
|
+
/**
|
|
14
|
+
* Declarative facts an interpreter attaches to a node it does not own, such as
|
|
15
|
+
* the server data a Remote selection needs. The carrier holds and combines
|
|
16
|
+
* them without knowing what they mean; a package reads only the key it owns.
|
|
17
|
+
*
|
|
18
|
+
* Opaque: only a key's `of` and `Metadata.combine` make one, so entries cannot
|
|
19
|
+
* be forged past a key's type or `merge`, and they are frozen.
|
|
20
|
+
*/
|
|
21
|
+
interface Metadata$1 {
|
|
22
|
+
readonly [MetadataTypeId]: MetadataTypeId;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* An interpreter's typed slot in `Metadata`. Lookup is by the key object, never
|
|
26
|
+
* its `name`, so two packages cannot collide by choosing the same string.
|
|
27
|
+
*/
|
|
28
|
+
interface MetadataKey<A> {
|
|
29
|
+
/** For tooling output only. */
|
|
30
|
+
readonly name: string;
|
|
31
|
+
/** Normalizes the entries gathered from combined values, e.g. unioning duplicates. */
|
|
32
|
+
readonly merge: (values: ReadonlyArray<A>) => ReadonlyArray<A>;
|
|
33
|
+
/** One line per entry for tooling output. */
|
|
34
|
+
readonly summarize: (value: A) => string;
|
|
35
|
+
readonly of: (...values: ReadonlyArray<A>) => Metadata$1;
|
|
36
|
+
readonly get: (metadata: Metadata$1) => ReadonlyArray<A>;
|
|
37
|
+
}
|
|
38
|
+
/** One key's entries as serializable text, named by the key. */
|
|
39
|
+
interface MetadataSummary {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly entries: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
declare const Metadata$1: {
|
|
44
|
+
/**
|
|
45
|
+
* Declares an interpreter's slot. Call once per package, at module level:
|
|
46
|
+
* entries are found by the key object, so two copies of a package (a
|
|
47
|
+
* duplicated install, a reloaded module) do not see each other's entries.
|
|
48
|
+
*/
|
|
49
|
+
key: <A>(name: string, options: {
|
|
50
|
+
readonly merge: (values: ReadonlyArray<A>) => ReadonlyArray<A>;
|
|
51
|
+
readonly summarize: (value: A) => string;
|
|
52
|
+
}) => MetadataKey<A>;
|
|
53
|
+
empty: Metadata$1;
|
|
54
|
+
/** True only for a value this module made; a copy or a hand-built brand is not one. */
|
|
55
|
+
is: (value: unknown) => value is Metadata$1;
|
|
56
|
+
/** Gathers every part's entries and runs each key's `merge` over its group. */
|
|
57
|
+
combine: (parts: ReadonlyArray<Metadata$1>) => Metadata$1;
|
|
58
|
+
summarize: (metadata: Metadata$1) => readonly MetadataSummary[];
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#endregion
|
|
7
62
|
//#region src/connection.d.ts
|
|
8
63
|
export interface EdgeRef {
|
|
9
64
|
readonly entity: string;
|
|
@@ -49,6 +104,51 @@ export declare const hasNext: (connection: Connection) => boolean;
|
|
|
49
104
|
/** A connection with more than one segment has an explicit unknown gap. */
|
|
50
105
|
export declare const isGapped: (connection: Connection) => boolean;
|
|
51
106
|
//#endregion
|
|
107
|
+
//#region src/remoteData.d.ts
|
|
108
|
+
export interface RemoteError {
|
|
109
|
+
readonly _tag: string;
|
|
110
|
+
readonly message: string;
|
|
111
|
+
}
|
|
112
|
+
export type RemoteData<A> = {
|
|
113
|
+
readonly _tag: 'Initial';
|
|
114
|
+
} | {
|
|
115
|
+
readonly _tag: 'Loading';
|
|
116
|
+
} | {
|
|
117
|
+
readonly _tag: 'Ready';
|
|
118
|
+
readonly value: A;
|
|
119
|
+
} | {
|
|
120
|
+
readonly _tag: 'Refreshing';
|
|
121
|
+
readonly value: A;
|
|
122
|
+
} | {
|
|
123
|
+
readonly _tag: 'Failed';
|
|
124
|
+
readonly error: RemoteError;
|
|
125
|
+
readonly previous?: A;
|
|
126
|
+
} | {
|
|
127
|
+
readonly _tag: 'NotFound';
|
|
128
|
+
};
|
|
129
|
+
export declare const remoteErrorSchema: Schema.Struct<{
|
|
130
|
+
readonly _tag: Schema.String;
|
|
131
|
+
readonly message: Schema.String;
|
|
132
|
+
}>;
|
|
133
|
+
export declare const remoteDataSchema: <A>(value: Schema.Schema<A>) => Schema.Codec<RemoteData<A>, unknown>;
|
|
134
|
+
export declare const RemoteData: {
|
|
135
|
+
/**
|
|
136
|
+
* The `RemoteData` schema for a value schema. Exposed so a `RemoteData` can
|
|
137
|
+
* be embedded in a hand-written Model schema, not only through `Remote.select`.
|
|
138
|
+
*/
|
|
139
|
+
schema: <A>(value: Schema.Schema<A>) => Schema.Schema<RemoteData<A>>;
|
|
140
|
+
/** Exhaustive: omitting a state is a compile error. */
|
|
141
|
+
match: <A, R>(data: RemoteData<A>, cases: {
|
|
142
|
+
readonly Initial: () => R;
|
|
143
|
+
readonly Loading: () => R;
|
|
144
|
+
readonly Ready: (value: A) => R;
|
|
145
|
+
readonly Refreshing: (value: A) => R;
|
|
146
|
+
readonly Failed: (error: RemoteError, previous: Option.Option<A>) => R;
|
|
147
|
+
readonly NotFound: () => R;
|
|
148
|
+
}) => R;
|
|
149
|
+
map: <A, B>(data: RemoteData<A>, f: (value: A) => B) => RemoteData<B>;
|
|
150
|
+
};
|
|
151
|
+
//#endregion
|
|
52
152
|
//#region src/store.d.ts
|
|
53
153
|
export type EntityKey = string;
|
|
54
154
|
export interface EntityEntry {
|
|
@@ -128,6 +228,8 @@ export interface MutationState {
|
|
|
128
228
|
readonly pending: ReadonlySet<string>;
|
|
129
229
|
readonly applied: ReadonlySet<string>;
|
|
130
230
|
readonly failed: ReadonlySet<string>;
|
|
231
|
+
/** Why each request in `failed` failed, kept exactly as long as `failed` keeps its id. */
|
|
232
|
+
readonly errors: ReadonlyMap<string, RemoteError>;
|
|
131
233
|
/**
|
|
132
234
|
* How many mutations this model has started. A bound domain takes its next
|
|
133
235
|
* request id from here, so `update` stays pure and the id exists before the
|
|
@@ -137,7 +239,21 @@ export interface MutationState {
|
|
|
137
239
|
}
|
|
138
240
|
export declare const emptyMutationState: MutationState;
|
|
139
241
|
export declare const beginMutation: (state: MutationState, requestId: string) => MutationState;
|
|
140
|
-
export declare const failMutation: (state: MutationState, requestId: string) => MutationState;
|
|
242
|
+
export declare const failMutation: (state: MutationState, requestId: string, error: RemoteError) => MutationState;
|
|
243
|
+
/** What Remote knows of one mutation request, by the id `mutate` returned. */
|
|
244
|
+
export type MutationStatus =
|
|
245
|
+
/** Never started here, or settled so long ago its id has left the window. */
|
|
246
|
+
{
|
|
247
|
+
readonly _tag: 'Unknown';
|
|
248
|
+
} | {
|
|
249
|
+
readonly _tag: 'Pending';
|
|
250
|
+
} | {
|
|
251
|
+
readonly _tag: 'Applied';
|
|
252
|
+
} | {
|
|
253
|
+
readonly _tag: 'Failed';
|
|
254
|
+
readonly error: RemoteError;
|
|
255
|
+
};
|
|
256
|
+
export declare const mutationStatus: (state: MutationState, requestId: string) => MutationStatus;
|
|
141
257
|
export interface Reconciled {
|
|
142
258
|
readonly store: EntityStore;
|
|
143
259
|
readonly state: MutationState;
|
|
@@ -147,7 +263,10 @@ export interface Reconciled {
|
|
|
147
263
|
* with the same `requestId` (a retry, or a live event describing the same change)
|
|
148
264
|
* does not re-apply the entities, but still clears `pending`.
|
|
149
265
|
*/
|
|
150
|
-
export declare const reconcileMutation: (store: EntityStore, state: MutationState, requestId: string, entities: ReadonlyArray<NormalizedPatch
|
|
266
|
+
export declare const reconcileMutation: (store: EntityStore, state: MutationState, requestId: string, entities: ReadonlyArray<NormalizedPatch>, deleted?: ReadonlyArray<{
|
|
267
|
+
readonly entity: string;
|
|
268
|
+
readonly id: string;
|
|
269
|
+
}>) => Reconciled;
|
|
151
270
|
/** A mutation an application declares: its name and input/output codecs. */
|
|
152
271
|
export interface MutationDescriptor<Name extends string, Input, Output> {
|
|
153
272
|
readonly name: Name;
|
|
@@ -171,6 +290,130 @@ export declare const Mutation: {
|
|
|
171
290
|
}) => MutationDescriptor<Name, TypeOf<Input>, TypeOf<Output>>;
|
|
172
291
|
};
|
|
173
292
|
//#endregion
|
|
293
|
+
//#region src/query.d.ts
|
|
294
|
+
export type LiveInsertion = 'visible' | 'boundary' | 'invalidate' | 'ignore';
|
|
295
|
+
export interface LivePolicy {
|
|
296
|
+
readonly prepend?: LiveInsertion;
|
|
297
|
+
readonly append?: LiveInsertion;
|
|
298
|
+
}
|
|
299
|
+
export interface ConnectionSpec<Entity extends string = string> {
|
|
300
|
+
readonly entity: Entity;
|
|
301
|
+
readonly edgeKey?: Schema.Schema<unknown>;
|
|
302
|
+
readonly live?: LivePolicy;
|
|
303
|
+
}
|
|
304
|
+
export interface QueryWindow {
|
|
305
|
+
readonly first?: number | undefined;
|
|
306
|
+
readonly last?: number | undefined;
|
|
307
|
+
readonly after?: Cursor | undefined;
|
|
308
|
+
readonly before?: Cursor | undefined;
|
|
309
|
+
}
|
|
310
|
+
export interface QueryRef<Name extends string, Input> {
|
|
311
|
+
readonly query: Name;
|
|
312
|
+
readonly input: Input;
|
|
313
|
+
/** The input codec, so a `QueryRef` can encode itself without its descriptor. */
|
|
314
|
+
readonly Input: Schema.Codec<Input>;
|
|
315
|
+
readonly window: QueryWindow;
|
|
316
|
+
/** Connection identity: descriptor + canonical input, excluding the window. */
|
|
317
|
+
readonly identity: string;
|
|
318
|
+
}
|
|
319
|
+
export interface QueryDescriptor<Name extends string, Input, Result> {
|
|
320
|
+
readonly name: Name;
|
|
321
|
+
readonly Input: Schema.Codec<Input>;
|
|
322
|
+
readonly Result: Result;
|
|
323
|
+
readonly ref: (input: Input) => QueryRef<Name, Input>;
|
|
324
|
+
}
|
|
325
|
+
/** Stable stringify: object keys sorted, undefined-valued keys dropped, so equal inputs encode equally. */
|
|
326
|
+
export declare const stableStringify: (value: unknown) => string;
|
|
327
|
+
/**
|
|
328
|
+
* `Result: Project` (or anything with the entity's `name`, as `Query.connection`
|
|
329
|
+
* takes) means a connection over it; a `ConnectionSpec` names its `entity`
|
|
330
|
+
* instead and is the result as given.
|
|
331
|
+
*/
|
|
332
|
+
export type ResultOf<Result> = Result extends {
|
|
333
|
+
readonly name: infer Entity extends string;
|
|
334
|
+
} ? ConnectionSpec<Entity> : Result;
|
|
335
|
+
export declare const Query: {
|
|
336
|
+
/** Declares the entity and options a query's result is a connection over. */
|
|
337
|
+
connection: <Entity extends string>(entity: {
|
|
338
|
+
readonly name: Entity;
|
|
339
|
+
}, options?: {
|
|
340
|
+
readonly edgeKey?: Schema.Schema<unknown>;
|
|
341
|
+
readonly live?: LivePolicy;
|
|
342
|
+
}) => ConnectionSpec<Entity>;
|
|
343
|
+
/**
|
|
344
|
+
* Declares a query. `Input` is a codec or the fields of the `Schema.Struct` it
|
|
345
|
+
* would be; `Result` is a `Query.connection(...)`, or the entity the result is
|
|
346
|
+
* a connection over.
|
|
347
|
+
*/
|
|
348
|
+
make: <const Name extends string, Input extends SchemaOrFields, Result>(name: Name, config: {
|
|
349
|
+
readonly Input: Input;
|
|
350
|
+
readonly Result: Result;
|
|
351
|
+
}) => QueryDescriptor<Name, TypeOf<Input>, ResultOf<Result>>;
|
|
352
|
+
first: (count: number) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
353
|
+
last: (count: number) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
354
|
+
after: (cursor: Cursor) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
355
|
+
before: (cursor: Cursor) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
356
|
+
};
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/requirement.d.ts
|
|
359
|
+
/**
|
|
360
|
+
* The slice required of an entity. `windows` carries a pagination window per
|
|
361
|
+
* relation field, and `relations` the slice required of each relation's
|
|
362
|
+
* target, so one requirement describes a whole selection graph.
|
|
363
|
+
*/
|
|
364
|
+
export interface RelationRequirement {
|
|
365
|
+
readonly entity: string;
|
|
366
|
+
readonly fields: readonly string[];
|
|
367
|
+
readonly windows?: Readonly<Record<string, QueryWindow>> | undefined;
|
|
368
|
+
readonly relations?: Readonly<Record<string, RelationRequirement>> | undefined;
|
|
369
|
+
}
|
|
370
|
+
export interface Requirement extends RelationRequirement {
|
|
371
|
+
readonly id: string;
|
|
372
|
+
/** The projection also subscribes to changes of this entity (`Data.live`). */
|
|
373
|
+
readonly live?: boolean | undefined;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* A query connection a projection reads: the page it first asks for and the
|
|
377
|
+
* slice it selects of each item. `identity` is the connection's (query plus
|
|
378
|
+
* canonical input, excluding the window).
|
|
379
|
+
*/
|
|
380
|
+
export interface ConnectionRequirement {
|
|
381
|
+
readonly identity: string;
|
|
382
|
+
readonly window: QueryWindow;
|
|
383
|
+
readonly select: RelationRequirement;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Merges connection requirements for the same connection and window into one,
|
|
387
|
+
* unioning what they select of each item; the first keeps its other properties.
|
|
388
|
+
*/
|
|
389
|
+
declare function mergeConnections(connections: readonly ConnectionRequirement[]): readonly ConnectionRequirement[];
|
|
390
|
+
/** Unions two relation slices for the same target: fields, windows, and nested relations. */
|
|
391
|
+
declare function mergeRelation(current: RelationRequirement, next: RelationRequirement): RelationRequirement;
|
|
392
|
+
/** Unions requirements for the same entity + id, dropping duplicate fields. */
|
|
393
|
+
declare function mergeRequirements(requirements: readonly Requirement[]): readonly Requirement[];
|
|
394
|
+
/**
|
|
395
|
+
* Requirement helpers, for the packages that plan and serve requirements.
|
|
396
|
+
* `merge` unions same-entity+id requirements; `mergeRelation` unions two
|
|
397
|
+
* slices of one target (fields, windows, nested relations).
|
|
398
|
+
*/
|
|
399
|
+
export declare const Requirement: {
|
|
400
|
+
merge: typeof mergeRequirements;
|
|
401
|
+
mergeRelation: typeof mergeRelation;
|
|
402
|
+
mergeConnections: typeof mergeConnections;
|
|
403
|
+
};
|
|
404
|
+
/** Remote's entity requirements on a Projection, unioned per entity and id as nodes compose. */
|
|
405
|
+
export declare const RemoteRequirements: MetadataKey<Requirement>;
|
|
406
|
+
/** Remote's query connections on a Projection, unioned per connection and window. */
|
|
407
|
+
export declare const RemoteConnections: MetadataKey<ConnectionRequirement>;
|
|
408
|
+
/** The entity requirements a Projection carries. */
|
|
409
|
+
export declare const requirementsOf: (projection: {
|
|
410
|
+
readonly metadata: Metadata;
|
|
411
|
+
}) => ReadonlyArray<Requirement>;
|
|
412
|
+
/** The query connections a Projection carries. */
|
|
413
|
+
export declare const connectionsOf: (projection: {
|
|
414
|
+
readonly metadata: Metadata;
|
|
415
|
+
}) => ReadonlyArray<ConnectionRequirement>;
|
|
416
|
+
//#endregion
|
|
174
417
|
//#region src/optimistic.d.ts
|
|
175
418
|
export interface EntityLayer {
|
|
176
419
|
readonly id: string;
|
|
@@ -257,7 +500,10 @@ export declare const pruneOverlays: (optimistic: OptimisticState, connection: st
|
|
|
257
500
|
* a later layer re-wins on rebase. Confirmed connection changes are recorded
|
|
258
501
|
* once per request, as overlays the request no longer owns.
|
|
259
502
|
*/
|
|
260
|
-
export declare const settleSuccess: (base: EntityStore, optimistic: OptimisticState, state: MutationState, requestId: string, entities: ReadonlyArray<NormalizedPatch>, connections?: ReadonlyArray<ConnectionChange
|
|
503
|
+
export declare const settleSuccess: (base: EntityStore, optimistic: OptimisticState, state: MutationState, requestId: string, entities: ReadonlyArray<NormalizedPatch>, connections?: ReadonlyArray<ConnectionChange>, deleted?: ReadonlyArray<{
|
|
504
|
+
readonly entity: string;
|
|
505
|
+
readonly id: string;
|
|
506
|
+
}>) => {
|
|
261
507
|
readonly store: EntityStore;
|
|
262
508
|
readonly state: MutationState;
|
|
263
509
|
readonly optimistic: OptimisticState;
|
|
@@ -275,71 +521,6 @@ export declare const settleFailure: (optimistic: OptimisticState, requestId: str
|
|
|
275
521
|
*/
|
|
276
522
|
export declare const visibleItems: (connection: Connection, connectionId: string, overlays: ReadonlyArray<ConnectionOverlay>, store?: EntityStore) => ReadonlyArray<Edge>;
|
|
277
523
|
//#endregion
|
|
278
|
-
//#region src/query.d.ts
|
|
279
|
-
export type LiveInsertion = 'visible' | 'boundary' | 'invalidate' | 'ignore';
|
|
280
|
-
export interface LivePolicy {
|
|
281
|
-
readonly prepend?: LiveInsertion;
|
|
282
|
-
readonly append?: LiveInsertion;
|
|
283
|
-
}
|
|
284
|
-
export interface ConnectionSpec<Entity extends string = string> {
|
|
285
|
-
readonly entity: Entity;
|
|
286
|
-
readonly edgeKey?: Schema.Schema<unknown>;
|
|
287
|
-
readonly live?: LivePolicy;
|
|
288
|
-
}
|
|
289
|
-
export interface QueryWindow {
|
|
290
|
-
readonly first?: number | undefined;
|
|
291
|
-
readonly last?: number | undefined;
|
|
292
|
-
readonly after?: Cursor | undefined;
|
|
293
|
-
readonly before?: Cursor | undefined;
|
|
294
|
-
}
|
|
295
|
-
export interface QueryRef<Name extends string, Input> {
|
|
296
|
-
readonly query: Name;
|
|
297
|
-
readonly input: Input;
|
|
298
|
-
/** The input codec, so a `QueryRef` can encode itself without its descriptor. */
|
|
299
|
-
readonly Input: Schema.Codec<Input>;
|
|
300
|
-
readonly window: QueryWindow;
|
|
301
|
-
/** Connection identity: descriptor + canonical input, excluding the window. */
|
|
302
|
-
readonly identity: string;
|
|
303
|
-
}
|
|
304
|
-
export interface QueryDescriptor<Name extends string, Input, Result> {
|
|
305
|
-
readonly name: Name;
|
|
306
|
-
readonly Input: Schema.Codec<Input>;
|
|
307
|
-
readonly Result: Result;
|
|
308
|
-
readonly ref: (input: Input) => QueryRef<Name, Input>;
|
|
309
|
-
}
|
|
310
|
-
/** Stable stringify: object keys sorted, undefined-valued keys dropped, so equal inputs encode equally. */
|
|
311
|
-
export declare const stableStringify: (value: unknown) => string;
|
|
312
|
-
/**
|
|
313
|
-
* `Result: Project` (or anything with the entity's `name`, as `Query.connection`
|
|
314
|
-
* takes) means a connection over it; a `ConnectionSpec` names its `entity`
|
|
315
|
-
* instead and is the result as given.
|
|
316
|
-
*/
|
|
317
|
-
export type ResultOf<Result> = Result extends {
|
|
318
|
-
readonly name: infer Entity extends string;
|
|
319
|
-
} ? ConnectionSpec<Entity> : Result;
|
|
320
|
-
export declare const Query: {
|
|
321
|
-
/** Declares the entity and options a query's result is a connection over. */
|
|
322
|
-
connection: <Entity extends string>(entity: {
|
|
323
|
-
readonly name: Entity;
|
|
324
|
-
}, options?: {
|
|
325
|
-
readonly edgeKey?: Schema.Schema<unknown>;
|
|
326
|
-
readonly live?: LivePolicy;
|
|
327
|
-
}) => ConnectionSpec<Entity>;
|
|
328
|
-
/**
|
|
329
|
-
* Declares a query. `Input` is a codec or the fields of the `Schema.Struct` it
|
|
330
|
-
* would be; `Result` is a `Query.connection(...)`, or the entity the result is
|
|
331
|
-
* a connection over.
|
|
332
|
-
*/
|
|
333
|
-
make: <const Name extends string, Input extends SchemaOrFields, Result>(name: Name, config: {
|
|
334
|
-
readonly Input: Input;
|
|
335
|
-
readonly Result: Result;
|
|
336
|
-
}) => QueryDescriptor<Name, TypeOf<Input>, ResultOf<Result>>;
|
|
337
|
-
first: (count: number) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
338
|
-
last: (count: number) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
339
|
-
after: (cursor: Cursor) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
340
|
-
before: (cursor: Cursor) => <R extends QueryRef<string, unknown>>(ref: R) => R;
|
|
341
|
-
};
|
|
342
|
-
//#endregion
|
|
343
524
|
//#region src/live.d.ts
|
|
344
525
|
export type LiveCursor = number;
|
|
345
526
|
export type LiveEvent = {
|
|
@@ -427,10 +608,10 @@ export declare const liveHasNext: (connection: Connection, state: LiveState, con
|
|
|
427
608
|
/** A connection to keep: its identity, and what a page of it selects of each item, if a projection reads it. */
|
|
428
609
|
export interface ConnectionRoot {
|
|
429
610
|
readonly identity: string;
|
|
430
|
-
readonly select?: RelationRequirement
|
|
611
|
+
readonly select?: RelationRequirement | undefined;
|
|
431
612
|
}
|
|
432
613
|
export interface RetentionRoots {
|
|
433
|
-
readonly requirements: ReadonlyArray<Requirement
|
|
614
|
+
readonly requirements: ReadonlyArray<Requirement>;
|
|
434
615
|
/** Connections (`QueryRef.identity`) to keep, with their edges' targets and what `select` reaches through them. */
|
|
435
616
|
readonly connections: ReadonlyArray<ConnectionRoot>;
|
|
436
617
|
}
|
|
@@ -468,9 +649,17 @@ export interface SnapshotOptions {
|
|
|
468
649
|
}
|
|
469
650
|
/** How a snapshot meets a store that already has entries. */
|
|
470
651
|
export type MergePolicy = 'replace' | 'preserve-existing';
|
|
652
|
+
/**
|
|
653
|
+
* The snapshot text, or `undefined` when it would exceed `maxBytes`. Only the
|
|
654
|
+
* entity store goes in; pass `model.entities`, never the whole `RemoteModel`.
|
|
655
|
+
*/
|
|
656
|
+
declare function dehydrate(store: EntityStore, options?: SnapshotOptions & {
|
|
657
|
+
readonly maxBytes?: undefined;
|
|
658
|
+
}): string;
|
|
659
|
+
declare function dehydrate(store: EntityStore, options?: SnapshotOptions): string | undefined;
|
|
471
660
|
export declare const RemotePersistence: {
|
|
472
661
|
/** The snapshot text, or `undefined` when it would exceed `maxBytes`. */
|
|
473
|
-
dehydrate:
|
|
662
|
+
dehydrate: typeof dehydrate;
|
|
474
663
|
/** The store a snapshot text holds, or `undefined` when it is refused. */
|
|
475
664
|
hydrate: (raw: string | undefined | null, options?: SnapshotOptions) => EntityStore | undefined;
|
|
476
665
|
/** A snapshot brought into a store by policy. */
|
|
@@ -531,11 +720,11 @@ export declare const WindowSchema: Schema.Struct<{
|
|
|
531
720
|
export declare const MAX_FIELDS_PER_REQUEST = 256;
|
|
532
721
|
/** A selection may not nest relations deeper than this; the wire refuses more. */
|
|
533
722
|
export declare const MAX_RELATION_DEPTH = 8;
|
|
534
|
-
export declare const RelationRequest: Schema.Codec<RelationRequirement
|
|
535
|
-
export declare const ReadRequest: Schema.Codec<Requirement
|
|
723
|
+
export declare const RelationRequest: Schema.Codec<RelationRequirement, RelationRequirement, never, never>;
|
|
724
|
+
export declare const ReadRequest: Schema.Codec<Requirement, Requirement>;
|
|
536
725
|
export declare const ReadBatch: Schema.Struct<{
|
|
537
726
|
readonly version: Schema.Number;
|
|
538
|
-
readonly requests: Schema.$Array<Schema.Codec<Requirement
|
|
727
|
+
readonly requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
539
728
|
}>;
|
|
540
729
|
export declare const NormalizedEntity: Schema.Struct<{
|
|
541
730
|
readonly entity: Schema.String;
|
|
@@ -605,10 +794,15 @@ export declare const MutationResult: Schema.Struct<{
|
|
|
605
794
|
readonly key: Schema.String;
|
|
606
795
|
}>;
|
|
607
796
|
}>]>>>;
|
|
797
|
+
/** Entities the mutation deleted; the client knows them absent from then on. */
|
|
798
|
+
readonly deleted: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
799
|
+
readonly entity: Schema.String;
|
|
800
|
+
readonly id: Schema.String;
|
|
801
|
+
}>>>;
|
|
608
802
|
}>;
|
|
609
803
|
export declare const LiveRequirement: Schema.Struct<{
|
|
610
804
|
readonly version: Schema.Number;
|
|
611
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
805
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
612
806
|
/** Resume cursor; events at or before it are duplicates. */
|
|
613
807
|
readonly after: Schema.Number;
|
|
614
808
|
}>;
|
|
@@ -654,7 +848,7 @@ export declare const LiveChange: Schema.Union<readonly [Schema.Struct<{
|
|
|
654
848
|
}>]>;
|
|
655
849
|
export declare const Read: Rpc.Rpc<"FoldkitRemoteRead", Schema.Struct<{
|
|
656
850
|
readonly version: Schema.Number;
|
|
657
|
-
readonly requests: Schema.$Array<Schema.Codec<Requirement
|
|
851
|
+
readonly requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
658
852
|
}>, Schema.Struct<{
|
|
659
853
|
readonly entities: Schema.$Array<Schema.Struct<{
|
|
660
854
|
readonly entity: Schema.String;
|
|
@@ -693,10 +887,15 @@ export declare const Mutate: Rpc.Rpc<"FoldkitRemoteMutate", Schema.Struct<{
|
|
|
693
887
|
readonly key: Schema.String;
|
|
694
888
|
}>;
|
|
695
889
|
}>]>>>;
|
|
890
|
+
/** Entities the mutation deleted; the client knows them absent from then on. */
|
|
891
|
+
readonly deleted: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
892
|
+
readonly entity: Schema.String;
|
|
893
|
+
readonly id: Schema.String;
|
|
894
|
+
}>>>;
|
|
696
895
|
}>, typeof RemoteMutationError, never, never>;
|
|
697
896
|
export declare const Live: Rpc.Rpc<"FoldkitRemoteLive", Schema.Struct<{
|
|
698
897
|
readonly version: Schema.Number;
|
|
699
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
898
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
700
899
|
/** Resume cursor; events at or before it are duplicates. */
|
|
701
900
|
readonly after: Schema.Number;
|
|
702
901
|
}>, import("effect/unstable/rpc/RpcSchema").Stream<Schema.Union<readonly [Schema.Struct<{
|
|
@@ -819,7 +1018,7 @@ export declare const QueryRpc: Rpc.Rpc<"FoldkitRemoteQuery", Schema.Struct<{
|
|
|
819
1018
|
}>, typeof RemoteQueryError, never, never>;
|
|
820
1019
|
export declare const RemoteRpc: RpcGroup.RpcGroup<Rpc.Rpc<"FoldkitRemoteRead", Schema.Struct<{
|
|
821
1020
|
readonly version: Schema.Number;
|
|
822
|
-
readonly requests: Schema.$Array<Schema.Codec<Requirement
|
|
1021
|
+
readonly requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
823
1022
|
}>, Schema.Struct<{
|
|
824
1023
|
readonly entities: Schema.$Array<Schema.Struct<{
|
|
825
1024
|
readonly entity: Schema.String;
|
|
@@ -857,9 +1056,14 @@ export declare const RemoteRpc: RpcGroup.RpcGroup<Rpc.Rpc<"FoldkitRemoteRead", S
|
|
|
857
1056
|
readonly key: Schema.String;
|
|
858
1057
|
}>;
|
|
859
1058
|
}>]>>>;
|
|
1059
|
+
/** Entities the mutation deleted; the client knows them absent from then on. */
|
|
1060
|
+
readonly deleted: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
1061
|
+
readonly entity: Schema.String;
|
|
1062
|
+
readonly id: Schema.String;
|
|
1063
|
+
}>>>;
|
|
860
1064
|
}>, typeof RemoteMutationError, never, never> | Rpc.Rpc<"FoldkitRemoteLive", Schema.Struct<{
|
|
861
1065
|
readonly version: Schema.Number;
|
|
862
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
1066
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
863
1067
|
/** Resume cursor; events at or before it are duplicates. */
|
|
864
1068
|
readonly after: Schema.Number;
|
|
865
1069
|
}>, import("effect/unstable/rpc/RpcSchema").Stream<Schema.Union<readonly [Schema.Struct<{
|
|
@@ -930,51 +1134,6 @@ export declare const RemoteRpc: RpcGroup.RpcGroup<Rpc.Rpc<"FoldkitRemoteRead", S
|
|
|
930
1134
|
}>]>;
|
|
931
1135
|
}>, typeof RemoteQueryError, never, never>>;
|
|
932
1136
|
//#endregion
|
|
933
|
-
//#region src/remoteData.d.ts
|
|
934
|
-
export interface RemoteError {
|
|
935
|
-
readonly _tag: string;
|
|
936
|
-
readonly message: string;
|
|
937
|
-
}
|
|
938
|
-
export type RemoteData<A> = {
|
|
939
|
-
readonly _tag: 'Initial';
|
|
940
|
-
} | {
|
|
941
|
-
readonly _tag: 'Loading';
|
|
942
|
-
} | {
|
|
943
|
-
readonly _tag: 'Ready';
|
|
944
|
-
readonly value: A;
|
|
945
|
-
} | {
|
|
946
|
-
readonly _tag: 'Refreshing';
|
|
947
|
-
readonly value: A;
|
|
948
|
-
} | {
|
|
949
|
-
readonly _tag: 'Failed';
|
|
950
|
-
readonly error: RemoteError;
|
|
951
|
-
readonly previous?: A;
|
|
952
|
-
} | {
|
|
953
|
-
readonly _tag: 'NotFound';
|
|
954
|
-
};
|
|
955
|
-
export declare const remoteErrorSchema: Schema.Struct<{
|
|
956
|
-
readonly _tag: Schema.String;
|
|
957
|
-
readonly message: Schema.String;
|
|
958
|
-
}>;
|
|
959
|
-
export declare const remoteDataSchema: <A>(value: Schema.Schema<A>) => Schema.Schema<RemoteData<A>>;
|
|
960
|
-
export declare const RemoteData: {
|
|
961
|
-
/**
|
|
962
|
-
* The `RemoteData` schema for a value schema. Exposed so a `RemoteData` can
|
|
963
|
-
* be embedded in a hand-written Model schema, not only through `Remote.select`.
|
|
964
|
-
*/
|
|
965
|
-
schema: <A>(value: Schema.Schema<A>) => Schema.Schema<RemoteData<A>>;
|
|
966
|
-
/** Exhaustive: omitting a state is a compile error. */
|
|
967
|
-
match: <A, R>(data: RemoteData<A>, cases: {
|
|
968
|
-
readonly Initial: () => R;
|
|
969
|
-
readonly Loading: () => R;
|
|
970
|
-
readonly Ready: (value: A) => R;
|
|
971
|
-
readonly Refreshing: (value: A) => R;
|
|
972
|
-
readonly Failed: (error: RemoteError, previous: Option.Option<A>) => R;
|
|
973
|
-
readonly NotFound: () => R;
|
|
974
|
-
}) => R;
|
|
975
|
-
map: <A, B>(data: RemoteData<A>, f: (value: A) => B) => RemoteData<B>;
|
|
976
|
-
};
|
|
977
|
-
//#endregion
|
|
978
1137
|
//#region src/model.d.ts
|
|
979
1138
|
/**
|
|
980
1139
|
* The normalized cache as a Foldkit Submodel. `Remote.define` returns a schema
|
|
@@ -1000,29 +1159,40 @@ export interface RemoteModel {
|
|
|
1000
1159
|
* fetching this".
|
|
1001
1160
|
*/
|
|
1002
1161
|
readonly loading: ReadonlySet<string>;
|
|
1162
|
+
/**
|
|
1163
|
+
* `Remote.refresh` generations. The read entries restart when `requested`
|
|
1164
|
+
* moves, so a read sent before a refresh cannot land after it; `started` is
|
|
1165
|
+
* the latest generation a read began under.
|
|
1166
|
+
*/
|
|
1167
|
+
readonly refresh: {
|
|
1168
|
+
readonly requested: number;
|
|
1169
|
+
readonly started: number;
|
|
1170
|
+
};
|
|
1003
1171
|
}
|
|
1004
1172
|
export declare const initialRemoteModel: RemoteModel;
|
|
1005
|
-
export declare const remoteModelSchema: () => Schema.
|
|
1173
|
+
export declare const remoteModelSchema: () => Schema.Codec<RemoteModel, unknown>;
|
|
1006
1174
|
/** The submodel's Messages; each reduces to `RemoteModel` through `updateRemote`. */
|
|
1007
1175
|
export type RemoteMessage = {
|
|
1008
1176
|
readonly _tag: 'ReadReceived';
|
|
1009
|
-
readonly requests: readonly Requirement
|
|
1177
|
+
readonly requests: readonly Requirement[];
|
|
1010
1178
|
readonly result: Schema.Schema.Type<typeof ReadBatchResult>;
|
|
1011
1179
|
readonly now: number;
|
|
1012
1180
|
} | {
|
|
1013
1181
|
readonly _tag: 'ReadFailed';
|
|
1014
|
-
readonly requests: readonly Requirement
|
|
1182
|
+
readonly requests: readonly Requirement[];
|
|
1015
1183
|
readonly error: RemoteError;
|
|
1016
1184
|
} |
|
|
1017
1185
|
/** A refetch of present fields began; they read as `Refreshing` until it lands. */
|
|
1018
1186
|
{
|
|
1019
1187
|
readonly _tag: 'RefreshStarted';
|
|
1020
|
-
readonly requests: readonly Requirement
|
|
1188
|
+
readonly requests: readonly Requirement[];
|
|
1021
1189
|
} |
|
|
1022
1190
|
/** A read began; the fields it asks for that the store lacks read as `Loading`. */
|
|
1023
1191
|
{
|
|
1024
1192
|
readonly _tag: 'ReadStarted';
|
|
1025
|
-
readonly requests: readonly Requirement
|
|
1193
|
+
readonly requests: readonly Requirement[];
|
|
1194
|
+
/** The refresh generation the read was planned under. */
|
|
1195
|
+
readonly refresh?: number | undefined;
|
|
1026
1196
|
} |
|
|
1027
1197
|
/** The active Surfaces' roots changed; everything they do not reach is collected. */
|
|
1028
1198
|
{
|
|
@@ -1046,6 +1216,11 @@ export type RemoteMessage = {
|
|
|
1046
1216
|
readonly entities: readonly NormalizedPatch[];
|
|
1047
1217
|
/** Connection changes the server confirmed; they replace the request's own. */
|
|
1048
1218
|
readonly connections?: ReadonlyArray<ConnectionChange> | undefined;
|
|
1219
|
+
/** Entities the mutation deleted: tombstoned, which hides them from every connection. */
|
|
1220
|
+
readonly deleted?: ReadonlyArray<{
|
|
1221
|
+
readonly entity: string;
|
|
1222
|
+
readonly id: string;
|
|
1223
|
+
}> | undefined;
|
|
1049
1224
|
} | {
|
|
1050
1225
|
readonly _tag: 'MutationFailed';
|
|
1051
1226
|
readonly requestId: string;
|
|
@@ -1079,10 +1254,10 @@ export type RemoteMessage = {
|
|
|
1079
1254
|
readonly error: RemoteError;
|
|
1080
1255
|
};
|
|
1081
1256
|
export declare const retentionRootsSchema: Schema.Struct<{
|
|
1082
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
1257
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1083
1258
|
readonly connections: Schema.$Array<Schema.Struct<{
|
|
1084
1259
|
readonly identity: Schema.String;
|
|
1085
|
-
readonly select: Schema.optional<Schema.Codec<
|
|
1260
|
+
readonly select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
|
|
1086
1261
|
}>>;
|
|
1087
1262
|
}>;
|
|
1088
1263
|
/**
|
|
@@ -1091,7 +1266,7 @@ export declare const retentionRootsSchema: Schema.Struct<{
|
|
|
1091
1266
|
*/
|
|
1092
1267
|
export declare const remoteMessageCases: {
|
|
1093
1268
|
ReadReceived: {
|
|
1094
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
1269
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1095
1270
|
result: Schema.Struct<{
|
|
1096
1271
|
readonly entities: Schema.$Array<Schema.Struct<{
|
|
1097
1272
|
readonly entity: Schema.String;
|
|
@@ -1102,24 +1277,25 @@ export declare const remoteMessageCases: {
|
|
|
1102
1277
|
now: Schema.Number;
|
|
1103
1278
|
};
|
|
1104
1279
|
ReadFailed: {
|
|
1105
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
1280
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1106
1281
|
error: Schema.Struct<{
|
|
1107
1282
|
readonly _tag: Schema.String;
|
|
1108
1283
|
readonly message: Schema.String;
|
|
1109
1284
|
}>;
|
|
1110
1285
|
};
|
|
1111
1286
|
RefreshStarted: {
|
|
1112
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
1287
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1113
1288
|
};
|
|
1114
1289
|
ReadStarted: {
|
|
1115
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
1290
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1291
|
+
refresh: Schema.optional<Schema.Number>;
|
|
1116
1292
|
};
|
|
1117
1293
|
RetentionChanged: {
|
|
1118
1294
|
roots: Schema.Struct<{
|
|
1119
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
1295
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1120
1296
|
readonly connections: Schema.$Array<Schema.Struct<{
|
|
1121
1297
|
readonly identity: Schema.String;
|
|
1122
|
-
readonly select: Schema.optional<Schema.Codec<
|
|
1298
|
+
readonly select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
|
|
1123
1299
|
}>>;
|
|
1124
1300
|
}>;
|
|
1125
1301
|
};
|
|
@@ -1139,6 +1315,10 @@ export declare const remoteMessageCases: {
|
|
|
1139
1315
|
readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
|
|
1140
1316
|
}>>;
|
|
1141
1317
|
connections: Schema.optional<Schema.$Array<Schema.Unknown>>;
|
|
1318
|
+
deleted: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
1319
|
+
readonly entity: Schema.String;
|
|
1320
|
+
readonly id: Schema.String;
|
|
1321
|
+
}>>>;
|
|
1142
1322
|
};
|
|
1143
1323
|
MutationFailed: {
|
|
1144
1324
|
requestId: Schema.String;
|
|
@@ -1213,7 +1393,7 @@ export declare const updateRemote: (model: RemoteModel, message: RemoteMessage)
|
|
|
1213
1393
|
* accumulates rather than replaces. Every read path should use this rather than
|
|
1214
1394
|
* reducing `writeEntity` by hand.
|
|
1215
1395
|
*/
|
|
1216
|
-
export declare const writeRead: (store: EntityStore, requests: ReadonlyArray<Requirement
|
|
1396
|
+
export declare const writeRead: (store: EntityStore, requests: ReadonlyArray<Requirement>, result: Schema.Schema.Type<typeof ReadBatchResult>, now?: number) => EntityStore;
|
|
1217
1397
|
//#endregion
|
|
1218
1398
|
//#region src/coalesce.d.ts
|
|
1219
1399
|
type Batch = Schema.Schema.Type<typeof ReadBatch>;
|
|
@@ -1231,7 +1411,7 @@ export interface CoalesceOptions {
|
|
|
1231
1411
|
readonly window?: Duration.Input | undefined;
|
|
1232
1412
|
}
|
|
1233
1413
|
/** A stable key for a requirement, so an equal requirement in flight is joined. */
|
|
1234
|
-
export declare const requirementKey: (requirement: Requirement
|
|
1414
|
+
export declare const requirementKey: (requirement: Requirement) => string;
|
|
1235
1415
|
/**
|
|
1236
1416
|
* Wraps a raw query so that an identical query in flight (same query, input,
|
|
1237
1417
|
* and window) is joined rather than run again; distinct queries run
|
|
@@ -1251,7 +1431,7 @@ declare const RemoteClient_base: Context.ServiceClass<RemoteClient, "foldkit-rem
|
|
|
1251
1431
|
readonly query: (request: Schema.Schema.Type<typeof QueryRequest>) => Effect.Effect<Schema.Schema.Type<typeof QueryResult>, RemoteQueryError>;
|
|
1252
1432
|
readonly mutate: (request: Schema.Schema.Type<typeof MutationRequest>) => Effect.Effect<Schema.Schema.Type<typeof MutationResult>, RemoteMutationError>;
|
|
1253
1433
|
readonly live: (request: {
|
|
1254
|
-
readonly requirements: ReadonlyArray<Requirement
|
|
1434
|
+
readonly requirements: ReadonlyArray<Requirement>;
|
|
1255
1435
|
readonly after: LiveCursor;
|
|
1256
1436
|
}) => Stream.Stream<LiveEvent, RemoteLiveError | RemoteProtocolError>;
|
|
1257
1437
|
}>;
|
|
@@ -1295,6 +1475,10 @@ export declare const mutateRemote: <Name extends string, Input, Output>(mutation
|
|
|
1295
1475
|
};
|
|
1296
1476
|
}[];
|
|
1297
1477
|
connections: ConnectionChange[];
|
|
1478
|
+
deleted: readonly {
|
|
1479
|
+
readonly entity: string;
|
|
1480
|
+
readonly id: string;
|
|
1481
|
+
}[];
|
|
1298
1482
|
}, RemoteMutationError, RemoteClient>;
|
|
1299
1483
|
//#endregion
|
|
1300
1484
|
//#region src/relation.d.ts
|
|
@@ -1326,7 +1510,7 @@ export declare const refParts: (encoded: string) => RefParts;
|
|
|
1326
1510
|
*/
|
|
1327
1511
|
export declare const refsIn: (value: unknown) => ReadonlyArray<RefParts>;
|
|
1328
1512
|
/** The refs in a relation value that name the relation's target entity, and no other. */
|
|
1329
|
-
export declare const targetsOf: (value: unknown, relation: RelationRequirement
|
|
1513
|
+
export declare const targetsOf: (value: unknown, relation: RelationRequirement) => ReadonlyArray<RefParts>;
|
|
1330
1514
|
export declare const isRefPage: (value: unknown) => value is RefPageValue;
|
|
1331
1515
|
/**
|
|
1332
1516
|
* The relation shape an entity field schema declares: a ref (`one`), a nullable
|
|
@@ -1355,7 +1539,7 @@ export interface Selection<Value, Name extends string = string, Shape extends 'e
|
|
|
1355
1539
|
/** Pagination windows for nested relation fields, keyed by field name. */
|
|
1356
1540
|
readonly connections?: Readonly<Record<string, QueryWindow>> | undefined;
|
|
1357
1541
|
/** The slice required of each nested relation's target, keyed by field name. */
|
|
1358
|
-
readonly relations?: Readonly<Record<string, RelationRequirement
|
|
1542
|
+
readonly relations?: Readonly<Record<string, RelationRequirement>> | undefined;
|
|
1359
1543
|
/** Present when this selection is itself a paginated relation. */
|
|
1360
1544
|
readonly window?: QueryWindow | undefined;
|
|
1361
1545
|
/** Phantom: see `Shape`. */
|
|
@@ -1377,8 +1561,13 @@ type NestedValue<Field, Sel> = Sel extends Selection<infer V, string, 'connectio
|
|
|
1377
1561
|
export type SelectionValue<F extends Schema.Struct.Fields, Sel> = Simplify<{ readonly [K in keyof Sel & keyof F]: Sel[K] extends true ? Schema.Schema.Type<F[K]> : NestedValue<Schema.Schema.Type<F[K]>, Sel[K]>; }>;
|
|
1378
1562
|
export declare const pageSchema: (item: AnySchema) => AnySchema;
|
|
1379
1563
|
/** The requirement a nested selection contributes for its relation's target. */
|
|
1380
|
-
export declare const relationOf: (selection: Selection<unknown>) => RelationRequirement
|
|
1564
|
+
export declare const relationOf: (selection: Selection<unknown>) => RelationRequirement;
|
|
1381
1565
|
export declare const Selection: {
|
|
1566
|
+
/**
|
|
1567
|
+
* The Remote Selection of a `foldkit-entity` Selection: the same members, read
|
|
1568
|
+
* from Remote's store. `true` on a relation reads its refs, as it does here.
|
|
1569
|
+
*/
|
|
1570
|
+
from: <Name extends string, S extends Schema.Constraint>(selection: Domain.Selection<Name, unknown, S>) => Selection<S["Type"], Name, "entity">;
|
|
1382
1571
|
/**
|
|
1383
1572
|
* The fields to read of `entity`. A nested `Selection` on a relation field
|
|
1384
1573
|
* reads through the ref (or refs, or page of refs) the field holds into the
|
|
@@ -1404,7 +1593,7 @@ interface Assembled {
|
|
|
1404
1593
|
* not present yet. A tombstoned target reads as `null` (or is dropped from a
|
|
1405
1594
|
* list), so the Selection's codec decides whether that is a failure.
|
|
1406
1595
|
*/
|
|
1407
|
-
export declare const assemble: (store: EntityStore, key: string, requirement: RelationRequirement
|
|
1596
|
+
export declare const assemble: (store: EntityStore, key: string, requirement: RelationRequirement) => Assembled | undefined;
|
|
1408
1597
|
//#endregion
|
|
1409
1598
|
//#region src/entity.d.ts
|
|
1410
1599
|
export type AnySchema = Schema.Schema<unknown>;
|
|
@@ -1447,7 +1636,25 @@ export interface RefPage<Name extends string, F extends Schema.Struct.Fields = S
|
|
|
1447
1636
|
readonly hasNext: boolean;
|
|
1448
1637
|
readonly hasPrevious: boolean;
|
|
1449
1638
|
}
|
|
1639
|
+
/** The ref codec a `foldkit-entity` relation becomes: one ref, a nullable ref, or an array of refs. */
|
|
1640
|
+
type RelationField<Spec> = Spec extends Domain.RelationSpec<infer Target, infer Cardinality, infer Optional> ? Cardinality extends 'many' ? Schema.$Array<Schema.Codec<EntityRef<Target['name']>, string>> : Optional extends true ? Schema.NullOr<Schema.Codec<EntityRef<Target['name']>, string>> : Schema.Codec<EntityRef<Target['name']>, string> : never;
|
|
1641
|
+
/**
|
|
1642
|
+
* The fields Remote stores for a `foldkit-entity` Entity: its own fields, its
|
|
1643
|
+
* derived members (the server supplies them like any field), and each relation
|
|
1644
|
+
* as refs.
|
|
1645
|
+
*/
|
|
1646
|
+
export type FieldsFrom<E> = E extends Domain.Entity<any, infer Fields, infer Relations, infer Derived> ? Fields & { readonly [K in keyof Derived]: Derived[K]['schema']; } & { readonly [K in keyof Relations]: RelationField<Relations[K]>; } : never;
|
|
1450
1647
|
declare const Entity$1: {
|
|
1648
|
+
/**
|
|
1649
|
+
* The Remote descriptor of a `foldkit-entity` Entity. Relations declared with
|
|
1650
|
+
* `Entity.relate` become ref fields, so the store, the planner, and the server
|
|
1651
|
+
* treat it as they treat an `Entity.make` descriptor.
|
|
1652
|
+
*/
|
|
1653
|
+
from: <E extends Domain.AnyEntity>(entity: E & {
|
|
1654
|
+
readonly fields: {
|
|
1655
|
+
readonly id: unknown;
|
|
1656
|
+
};
|
|
1657
|
+
}) => EntityDescriptor<E["name"], FieldsFrom<E>>;
|
|
1451
1658
|
make: <const Name extends string, const F extends Schema.Struct.Fields & {
|
|
1452
1659
|
readonly id: Schema.Schema<unknown>;
|
|
1453
1660
|
}>(name: Name, schema: Schema.Struct<F>) => EntityDescriptor<Name, F>;
|
|
@@ -1504,7 +1711,7 @@ export declare const inspectRemote: (model: RemoteModel) => RemoteInspection;
|
|
|
1504
1711
|
export declare const inspectEntity: (model: RemoteModel, key: string) => RemoteInspection["entities"][number] | undefined;
|
|
1505
1712
|
//#endregion
|
|
1506
1713
|
//#region src/plan.d.ts
|
|
1507
|
-
type Window = NonNullable<Requirement
|
|
1714
|
+
type Window = NonNullable<Requirement['windows']>[string];
|
|
1508
1715
|
/** A stable key for a window, so two equal windows compare equal. */
|
|
1509
1716
|
export declare const windowKey: (window: Window) => string;
|
|
1510
1717
|
export interface PlanFreshness {
|
|
@@ -1517,7 +1724,7 @@ export interface PlanOptions {
|
|
|
1517
1724
|
/** Plan every requested field, present or not, tombstoned or not. */
|
|
1518
1725
|
readonly force?: boolean | undefined;
|
|
1519
1726
|
}
|
|
1520
|
-
export declare const plan: (store: EntityStore, requirements: readonly Requirement
|
|
1727
|
+
export declare const plan: (store: EntityStore, requirements: readonly Requirement[], options?: PlanOptions) => ReadonlyArray<Requirement>;
|
|
1521
1728
|
//#endregion
|
|
1522
1729
|
//#region src/policy.d.ts
|
|
1523
1730
|
export type RemotePolicy =
|
|
@@ -1561,7 +1768,18 @@ export declare const RemotePolicy: {
|
|
|
1561
1768
|
};
|
|
1562
1769
|
//#endregion
|
|
1563
1770
|
//#region src/index.d.ts
|
|
1564
|
-
|
|
1771
|
+
/** What a domain registers: a Remote descriptor, or a `foldkit-entity` Entity (read through `Entity.from`). */
|
|
1772
|
+
export type EntityLike = EntityDescriptor<any, any> | Domain.AnyEntity;
|
|
1773
|
+
/**
|
|
1774
|
+
* What a read selects: a Remote Selection, or a `foldkit-entity` Selection
|
|
1775
|
+
* (read through `Selection.from`).
|
|
1776
|
+
*/
|
|
1777
|
+
export type EntitySelection<Value, Name extends string> = Selection<Value, Name, 'entity'> | Domain.Selection<Name, unknown, Schema.Constraint & {
|
|
1778
|
+
readonly Type: Value;
|
|
1779
|
+
}>;
|
|
1780
|
+
type EntityName<D> = D extends {
|
|
1781
|
+
readonly name: infer Name extends string;
|
|
1782
|
+
} ? Name : never;
|
|
1565
1783
|
type QueryName<D> = D extends QueryDescriptor<infer Name, any, any> ? Name : never;
|
|
1566
1784
|
type MutationName<D> = D extends MutationDescriptor<infer Name, any, any> ? Name : never;
|
|
1567
1785
|
/**
|
|
@@ -1572,11 +1790,11 @@ type MutationName<D> = D extends MutationDescriptor<infer Name, any, any> ? Name
|
|
|
1572
1790
|
export type Registered<Name extends string, Names extends string, Kind extends string> = [Name] extends [Names] ? unknown : Invalid<`${Kind} "${Name}" is not registered with this Remote domain`>;
|
|
1573
1791
|
/** Nothing when a selection is of the query's entity; otherwise a branded failure naming both. */
|
|
1574
1792
|
export type SelectsEntity<Entity extends string, Of extends string> = [Entity] extends [Of] ? unknown : Invalid<`the selection is of "${Entity}", but the query lists "${Of}"`>;
|
|
1575
|
-
export interface RemoteDescriptor<Entities extends readonly
|
|
1793
|
+
export interface RemoteDescriptor<Entities extends readonly EntityLike[] = readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<any, any, any>[]> {
|
|
1576
1794
|
readonly entities: Entities;
|
|
1577
1795
|
readonly queries: Queries;
|
|
1578
1796
|
readonly mutations: Mutations;
|
|
1579
|
-
readonly Model: Schema.
|
|
1797
|
+
readonly Model: Schema.Codec<RemoteModel, unknown>;
|
|
1580
1798
|
readonly initial: RemoteModel;
|
|
1581
1799
|
readonly Message: Schema.Schema<RemoteMessage>;
|
|
1582
1800
|
readonly update: (model: RemoteModel, message: RemoteMessage) => RemoteModel;
|
|
@@ -1613,7 +1831,17 @@ export interface DomainMutateOptions {
|
|
|
1613
1831
|
}
|
|
1614
1832
|
/** A Foldkit Subscription entry of the Remote domain, emitting its Messages through `RemoteClient`. */
|
|
1615
1833
|
export type RemoteEntry<AppModel, Dependencies> = EntryWithoutKeepAlive<AppModel, RemoteMessage, Dependencies, RemoteClient>;
|
|
1834
|
+
/**
|
|
1835
|
+
* The entries `RemoteDomain.subscriptions` returns for an active record: a read
|
|
1836
|
+
* and a live entry per key (the live one idles when nothing is read live), and
|
|
1837
|
+
* `retain`.
|
|
1838
|
+
*/
|
|
1839
|
+
export type SubscriptionEntries<AppModel, Active> = { readonly [K in keyof Active & (string | number) as `${K}.read` | `${K}.live`]: RemoteEntry<AppModel, any>; } & {
|
|
1840
|
+
readonly retain: RemoteEntry<AppModel, any>;
|
|
1841
|
+
};
|
|
1616
1842
|
export interface SubscriptionsOptions extends ObserveOptions, LiveOptions, RetainOptions {}
|
|
1843
|
+
/** A Remote domain's wiring for an assembly: it routes Remote's Messages into `reduce`, brings its Subscriptions and contract, and requires `RemoteClient` from the runtime's resources Layer. */
|
|
1844
|
+
export type RemoteWiring<AppModel> = Wiring<AppModel, RemoteMessage | RemoteMessageInput, RemoteClient>;
|
|
1617
1845
|
/** What `RemoteDomain.mutate` hands `update`: the Model with the request started, and the Command that settles it. */
|
|
1618
1846
|
export interface MutationStarted<AppModel> {
|
|
1619
1847
|
readonly model: AppModel;
|
|
@@ -1628,15 +1856,15 @@ export interface MutationStarted<AppModel> {
|
|
|
1628
1856
|
* operations over them. Every method compiles to the `Remote.*` function of the
|
|
1629
1857
|
* same name, which stays exported for tooling, SSR, and tests.
|
|
1630
1858
|
*/
|
|
1631
|
-
export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities extends readonly
|
|
1859
|
+
export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities extends readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[]> extends BoundRemote<AppModel, Store, EntityName<Entities[number]>>, RemoteDescriptor<Entities, Queries, Mutations> {
|
|
1632
1860
|
/** `Remote.select`: a Projection reading one entity through a selection of a registered entity. */
|
|
1633
|
-
get<Value, Name extends string>(selection:
|
|
1861
|
+
get<Value, Name extends string>(selection: EntitySelection<Value, Name> & Registered<Name, EntityName<Entities[number]>, 'Entity'>, id: string): Projection<AppModel, RemoteData<Value>>;
|
|
1634
1862
|
/**
|
|
1635
1863
|
* `get`, and the projection also subscribes to the entity's changes: its
|
|
1636
1864
|
* requirements are marked `live`, so `subscriptions` derives a live entry for
|
|
1637
1865
|
* the Surfaces that read it.
|
|
1638
1866
|
*/
|
|
1639
|
-
live<Value, Name extends string>(selection:
|
|
1867
|
+
live<Value, Name extends string>(selection: EntitySelection<Value, Name> & Registered<Name, EntityName<Entities[number]>, 'Entity'>, id: string): Projection<AppModel, RemoteData<Value>>;
|
|
1640
1868
|
/**
|
|
1641
1869
|
* A query connection read as a `Page` of items selected of the query's
|
|
1642
1870
|
* entity: `Initial` until the page and every item's selected fields are
|
|
@@ -1651,6 +1879,8 @@ export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities exte
|
|
|
1651
1879
|
previous<Name extends string, Input>(model: AppModel, projection: QueryProjection<AppModel, any, Name, Input>): QueryRef<Name, Input> | undefined;
|
|
1652
1880
|
/** A Command that runs the query and yields the `ConnectionMerged` (or `QueryFailed`) that reduces it: "load more". */
|
|
1653
1881
|
fetch(ref: QueryRef<string, unknown>): Command<RemoteMessage, never, RemoteClient>;
|
|
1882
|
+
/** `Remote.refresh`: marks what a projection or a Surface requires as due, for its read entry to refetch. */
|
|
1883
|
+
refresh(model: AppModel, target: Projection<AppModel, unknown> | Surface<AppModel, any, any, void>): AppModel;
|
|
1654
1884
|
/**
|
|
1655
1885
|
* The Foldkit Subscription entries for the active Surfaces, keyed for
|
|
1656
1886
|
* `Subscription.make`: a read entry per Surface (`Remote.observe`), a live
|
|
@@ -1659,9 +1889,9 @@ export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities exte
|
|
|
1659
1889
|
* Surface's params are a function of the Model (`Surface.at`), so what is
|
|
1660
1890
|
* fetched, subscribed, and retained follows the Model.
|
|
1661
1891
|
*/
|
|
1662
|
-
subscriptions
|
|
1892
|
+
subscriptions<const Active extends Readonly<Record<string, ActiveSurface<AppModel> | Surface<AppModel, any, any, void>>>>(active: Active, options?: SubscriptionsOptions): SubscriptionEntries<AppModel, Active>;
|
|
1663
1893
|
/** `Remote.plan`: the requirements the store does not satisfy. */
|
|
1664
|
-
plan<Value>(model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions): ReadonlyArray<Requirement
|
|
1894
|
+
plan<Value>(model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions): ReadonlyArray<Requirement>;
|
|
1665
1895
|
/** `Remote.storeOf`: the visible store, base under the pending optimistic layers. */
|
|
1666
1896
|
storeOf(model: AppModel): EntityStore;
|
|
1667
1897
|
/**
|
|
@@ -1677,8 +1907,21 @@ export interface RemoteDomain<AppModel, Store extends RemoteModel, Entities exte
|
|
|
1677
1907
|
* mutation sequence unless `options.requestId` is given.
|
|
1678
1908
|
*/
|
|
1679
1909
|
mutate<M extends MutationDescriptor<any, any, any>>(model: AppModel, mutation: M & Registered<M['name'], MutationName<Mutations[number]>, 'Mutation'>, input: MutationInput<M>, options?: DomainMutateOptions): MutationStarted<AppModel>;
|
|
1910
|
+
/**
|
|
1911
|
+
* What Remote knows of a mutation `mutate` started, by its request id:
|
|
1912
|
+
* pending, applied, or failed with the error the server or transport gave.
|
|
1913
|
+
*/
|
|
1914
|
+
mutation(model: AppModel, requestId: string): MutationStatus;
|
|
1680
1915
|
/** `updateRemote` on the bound slice: reduces one of Remote's Messages, as `RemoteMessage` or as the application's union constructs it. */
|
|
1681
1916
|
reduce(model: AppModel, message: RemoteMessage | RemoteMessageInput): AppModel;
|
|
1917
|
+
/**
|
|
1918
|
+
* How this domain joins an assembly: it routes Remote's Messages into
|
|
1919
|
+
* `reduce`, brings its Subscriptions and contract, and requires
|
|
1920
|
+
* `RemoteClient` from the runtime's resources Layer. One assembly holds at
|
|
1921
|
+
* most one Remote wiring: every domain claims the same tags, and routing
|
|
1922
|
+
* takes the first claimant.
|
|
1923
|
+
*/
|
|
1924
|
+
wiring: <const Active extends Readonly<Record<string, ActiveSurface<AppModel> | Surface<AppModel, any, any, void>>>>(active: Active, options?: SubscriptionsOptions) => RemoteWiring<AppModel>;
|
|
1682
1925
|
/** `Remote.inspect` of the bound slice. */
|
|
1683
1926
|
inspect(model: AppModel): RemoteInspection;
|
|
1684
1927
|
}
|
|
@@ -1700,7 +1943,7 @@ export type QueryWindowOptions = {
|
|
|
1700
1943
|
};
|
|
1701
1944
|
export type QueryOptions<Value, Entity extends string, Of extends string = Entity> = {
|
|
1702
1945
|
/** What to read of each item: a selection of the query's entity (`Of`). */
|
|
1703
|
-
readonly select:
|
|
1946
|
+
readonly select: EntitySelection<Value, Entity> & SelectsEntity<Entity, Of>;
|
|
1704
1947
|
} & QueryWindowOptions;
|
|
1705
1948
|
/** A query connection read as a `Page` of selected items; `ref` is the connection with its first window. */
|
|
1706
1949
|
export interface QueryProjection<AppModel, Value, Name extends string, Input> extends Projection<AppModel, RemoteData<Page<Value>>> {
|
|
@@ -1744,12 +1987,14 @@ declare const PlannedQuery: Schema.Struct<{
|
|
|
1744
1987
|
}>;
|
|
1745
1988
|
/** The dependencies of the read entry: the entity fields to read and the queries to run. */
|
|
1746
1989
|
export interface ReadDependencies {
|
|
1747
|
-
readonly requirements: ReadonlyArray<Requirement
|
|
1990
|
+
readonly requirements: ReadonlyArray<Requirement>;
|
|
1748
1991
|
readonly queries: ReadonlyArray<Schema.Schema.Type<typeof PlannedQuery>>;
|
|
1992
|
+
/** The Model's requested refresh generation: a refresh restarts the entry. */
|
|
1993
|
+
readonly refresh: number;
|
|
1749
1994
|
}
|
|
1750
1995
|
export declare const Remote: {
|
|
1751
1996
|
/** The submodel's schema, the same for every domain; embed it in the application Model. */
|
|
1752
|
-
Model: Schema.
|
|
1997
|
+
Model: Schema.Codec<RemoteModel, unknown, never, never>;
|
|
1753
1998
|
/** The submodel's initial value. */
|
|
1754
1999
|
initial: RemoteModel;
|
|
1755
2000
|
/**
|
|
@@ -1759,7 +2004,7 @@ export declare const Remote: {
|
|
|
1759
2004
|
*/
|
|
1760
2005
|
messages: {
|
|
1761
2006
|
ReadReceived: {
|
|
1762
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
2007
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1763
2008
|
result: Schema.Struct<{
|
|
1764
2009
|
readonly entities: Schema.$Array<Schema.Struct<{
|
|
1765
2010
|
readonly entity: Schema.String;
|
|
@@ -1770,21 +2015,22 @@ export declare const Remote: {
|
|
|
1770
2015
|
now: Schema.Number;
|
|
1771
2016
|
};
|
|
1772
2017
|
ReadFailed: {
|
|
1773
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
2018
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1774
2019
|
error: Schema.Struct<{
|
|
1775
2020
|
readonly _tag: Schema.String;
|
|
1776
2021
|
readonly message: Schema.String;
|
|
1777
2022
|
}>;
|
|
1778
2023
|
};
|
|
1779
2024
|
RefreshStarted: {
|
|
1780
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
2025
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1781
2026
|
};
|
|
1782
2027
|
ReadStarted: {
|
|
1783
|
-
requests: Schema.$Array<Schema.Codec<Requirement
|
|
2028
|
+
requests: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
2029
|
+
refresh: Schema.optional<Schema.Number>;
|
|
1784
2030
|
};
|
|
1785
2031
|
RetentionChanged: {
|
|
1786
2032
|
roots: Schema.Struct<{
|
|
1787
|
-
readonly requirements: Schema.$Array<Schema.Codec<Requirement
|
|
2033
|
+
readonly requirements: Schema.$Array<Schema.Codec<Requirement, Requirement, never, never>>;
|
|
1788
2034
|
readonly connections: Schema.$Array<Schema.Struct<{
|
|
1789
2035
|
readonly identity: Schema.String;
|
|
1790
2036
|
readonly select: Schema.optional<Schema.Codec<RelationRequirement, RelationRequirement, never, never>>;
|
|
@@ -1807,6 +2053,10 @@ export declare const Remote: {
|
|
|
1807
2053
|
readonly values: Schema.$Record<Schema.String, Schema.Unknown>;
|
|
1808
2054
|
}>>;
|
|
1809
2055
|
connections: Schema.optional<Schema.$Array<Schema.Unknown>>;
|
|
2056
|
+
deleted: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
2057
|
+
readonly entity: Schema.String;
|
|
2058
|
+
readonly id: Schema.String;
|
|
2059
|
+
}>>>;
|
|
1810
2060
|
};
|
|
1811
2061
|
MutationFailed: {
|
|
1812
2062
|
requestId: Schema.String;
|
|
@@ -1854,7 +2104,7 @@ export declare const Remote: {
|
|
|
1854
2104
|
* in one step; the result carries the application-facing operations. The
|
|
1855
2105
|
* descriptor alone is `Remote.define`, the binding alone `Remote.at`.
|
|
1856
2106
|
*/
|
|
1857
|
-
make: <AppModel, Store extends RemoteModel, const Entities extends readonly
|
|
2107
|
+
make: <AppModel, Store extends RemoteModel, const Entities extends readonly EntityLike[], const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly [], const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly []>(config: {
|
|
1858
2108
|
readonly model: ModelRef<AppModel, Store>;
|
|
1859
2109
|
readonly entities: Entities;
|
|
1860
2110
|
readonly queries?: Queries;
|
|
@@ -1865,7 +2115,7 @@ export declare const Remote: {
|
|
|
1865
2115
|
* mutations, plus the submodel. For a domain reused across applications or
|
|
1866
2116
|
* bound in a test; `Remote.make` is the one-step form.
|
|
1867
2117
|
*/
|
|
1868
|
-
define: <const Entities extends readonly
|
|
2118
|
+
define: <const Entities extends readonly EntityLike[], const Queries extends readonly QueryDescriptor<any, any, any>[] = readonly QueryDescriptor<any, any, any>[], const Mutations extends readonly MutationDescriptor<any, any, any>[] = readonly MutationDescriptor<any, any, any>[]>(config: {
|
|
1869
2119
|
readonly entities: Entities;
|
|
1870
2120
|
readonly queries?: Queries;
|
|
1871
2121
|
readonly mutations?: Mutations;
|
|
@@ -1875,7 +2125,7 @@ export declare const Remote: {
|
|
|
1875
2125
|
* registered entity names are carried on the returned value, so `Remote.select`
|
|
1876
2126
|
* rejects a selection for an entity this domain never declared.
|
|
1877
2127
|
*/
|
|
1878
|
-
at: <AppModel, Store extends RemoteModel, Entities extends readonly
|
|
2128
|
+
at: <AppModel, Store extends RemoteModel, Entities extends readonly EntityLike[], Queries extends readonly QueryDescriptor<any, any, any>[], Mutations extends readonly MutationDescriptor<any, any, any>[]>(definition: RemoteDescriptor<Entities, Queries, Mutations>, store: ModelRef<AppModel, Store>) => BoundRemote<AppModel, Store, EntityName<Entities[number]>>;
|
|
1879
2129
|
/**
|
|
1880
2130
|
* A Projection node that reads a `RemoteData` value out of the store. The id
|
|
1881
2131
|
* is supplied by the caller, usually from a Surface's params. The assembled
|
|
@@ -1883,13 +2133,13 @@ export declare const Remote: {
|
|
|
1883
2133
|
* as `Failed` instead of being asserted into `Value`. A present value with a
|
|
1884
2134
|
* stale field reads as `Refreshing`: an observer is refetching it.
|
|
1885
2135
|
*/
|
|
1886
|
-
select: <AppModel, Store extends RemoteModel, Names extends string, Value, Name extends string>(bound: BoundRemote<AppModel, Store, Names>,
|
|
2136
|
+
select: <AppModel, Store extends RemoteModel, Names extends string, Value, Name extends string>(bound: BoundRemote<AppModel, Store, Names>, given: EntitySelection<Value, Name> & Registered<Name, Names, "Entity">) => (id: string) => Projection<AppModel, RemoteData<Value>>;
|
|
1887
2137
|
/**
|
|
1888
2138
|
* The pure plan for a projection against a Model: the requirements its
|
|
1889
2139
|
* remote store does not satisfy, under `options` (freshness, force). A
|
|
1890
2140
|
* Surface's projection is `surface.projection(params)`.
|
|
1891
2141
|
*/
|
|
1892
|
-
plan: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store>, model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions) => ReadonlyArray<Requirement
|
|
2142
|
+
plan: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store>, model: AppModel, projection: Projection<AppModel, Value>, options?: PlanOptions) => ReadonlyArray<Requirement>;
|
|
1893
2143
|
/**
|
|
1894
2144
|
* The queries a projection needs run before its connections read: those the
|
|
1895
2145
|
* Model does not hold, or holds stale (every one under `force`).
|
|
@@ -1908,11 +2158,30 @@ export declare const Remote: {
|
|
|
1908
2158
|
* is the clock it reads, so the planner itself stays pure and time-injected.
|
|
1909
2159
|
*/
|
|
1910
2160
|
prefetch: <AppModel, Store extends RemoteModel, Value>(bound: BoundRemote<AppModel, Store, string>, model: AppModel, projection: Projection<AppModel, Value>, options?: ObserveOptions | undefined) => Effect.Effect<Readonly<Record<string, EntityEntry>>, RemoteReadError | RemoteProtocolError, RemoteClient>;
|
|
2161
|
+
/**
|
|
2162
|
+
* Marks what a projection, or a Surface without params, requires as due again.
|
|
2163
|
+
* Called from `update`: every selected field the store holds reads `Refreshing`,
|
|
2164
|
+
* and every loaded query connection is invalidated. Nothing is fetched here.
|
|
2165
|
+
* The read entries `Data.subscriptions` derives refetch it, because a stale
|
|
2166
|
+
* field or connection is planned again under every policy, so a refresh never
|
|
2167
|
+
* sends a request beside the entry already observing the same data.
|
|
2168
|
+
*
|
|
2169
|
+
* A refreshed connection's page replaces its pages, so items the server removed
|
|
2170
|
+
* or reordered follow it; pages loaded past the first are dropped and paged
|
|
2171
|
+
* again with `next`/`previous`. The read entries restart, so a read or query
|
|
2172
|
+
* sent before the refresh is not applied after it.
|
|
2173
|
+
*
|
|
2174
|
+
* The projection must be observed, which it is while it is on screen. Live
|
|
2175
|
+
* subscriptions are left as they are. For data nothing observes (SSR, tests),
|
|
2176
|
+
* use `Remote.prefetch` with `RemotePolicy.networkOnly`. Refreshing what is
|
|
2177
|
+
* already being refreshed returns the same Model.
|
|
2178
|
+
*/
|
|
2179
|
+
refresh: <AppModel, Store extends RemoteModel>(bound: BoundRemote<AppModel, Store>, model: AppModel, target: Projection<AppModel, unknown> | Surface<AppModel, any, any, void>) => AppModel;
|
|
1911
2180
|
/**
|
|
1912
2181
|
* Writes a read result into the store, recording each field's applied window.
|
|
1913
2182
|
* `requests` are the planned requirements the result answers.
|
|
1914
2183
|
*/
|
|
1915
|
-
writeRead: (store: EntityStore, requests: ReadonlyArray<Requirement
|
|
2184
|
+
writeRead: (store: EntityStore, requests: ReadonlyArray<Requirement>, result: Schema.Schema.Type<typeof ReadBatchResult>, now?: number) => EntityStore;
|
|
1916
2185
|
/**
|
|
1917
2186
|
* Adapts an Effect RPC client for `RemoteRpc` to `RemoteClient`, so an
|
|
1918
2187
|
* application provides the transport's RPC layer instead of writing the
|
|
@@ -1987,6 +2256,10 @@ export declare const Remote: {
|
|
|
1987
2256
|
};
|
|
1988
2257
|
}[];
|
|
1989
2258
|
connections: ConnectionChange[];
|
|
2259
|
+
deleted: readonly {
|
|
2260
|
+
readonly entity: string;
|
|
2261
|
+
readonly id: string;
|
|
2262
|
+
}[];
|
|
1990
2263
|
}, RemoteMutationError, RemoteClient>;
|
|
1991
2264
|
/**
|
|
1992
2265
|
* Runs a mutation and reconciles its patches into a `RemoteModel` in one step,
|
|
@@ -2015,10 +2288,10 @@ export declare const Remote: {
|
|
|
2015
2288
|
* from `RemoteModel.live`, so the application tracks no cursor of its own.
|
|
2016
2289
|
*/
|
|
2017
2290
|
live: <AppModel, Store extends RemoteModel, Names extends string, Model, SurfaceMessage, Params, Message = RemoteMessage>(bound: BoundRemote<AppModel, Store, Names>, surface: Surface<AppModel, Model, SurfaceMessage, Params>, params: Params, toMessage?: (message: RemoteMessage) => Message, options?: LiveOptions) => EntryWithoutKeepAlive<AppModel, Message, {
|
|
2018
|
-
readonly requirements: ReadonlyArray<Requirement
|
|
2291
|
+
readonly requirements: ReadonlyArray<Requirement>;
|
|
2019
2292
|
readonly cursor: LiveCursor;
|
|
2020
2293
|
}, RemoteClient>;
|
|
2021
2294
|
};
|
|
2022
2295
|
//#endregion
|
|
2023
|
-
export { Entity$1 as Entity
|
|
2296
|
+
export { Entity$1 as Entity };
|
|
2024
2297
|
//# sourceMappingURL=index.d.mts.map
|