@durable-streams/state 0.1.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 +654 -0
- package/STATE-PROTOCOL.md +502 -0
- package/dist/index.cjs +558 -0
- package/dist/index.d.cts +284 -0
- package/dist/index.d.ts +284 -0
- package/dist/index.js +530 -0
- package/package.json +48 -0
- package/src/index.ts +33 -0
- package/src/materialized-state.ts +93 -0
- package/src/stream-db.ts +934 -0
- package/src/types.ts +80 -0
- package/state-protocol.schema.json +186 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { Collection, createOptimisticAction } from "@tanstack/db";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
import { DurableStream, DurableStreamOptions } from "@durable-streams/client";
|
|
4
|
+
|
|
5
|
+
//#region src/types.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Operation types for change events
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Operation types for change events
|
|
11
|
+
*/
|
|
12
|
+
type Operation = `insert` | `update` | `delete` | `upsert`;
|
|
13
|
+
/**
|
|
14
|
+
* A generic value type supporting primitives, arrays, and objects
|
|
15
|
+
*/
|
|
16
|
+
type Value<Extensions = never> = string | number | boolean | bigint | null | Array<Value<Extensions>> | {
|
|
17
|
+
[key: string]: Value<Extensions>;
|
|
18
|
+
} | Extensions;
|
|
19
|
+
/**
|
|
20
|
+
* A row is a record of values
|
|
21
|
+
*/
|
|
22
|
+
type Row<Extensions = never> = Record<string, Value<Extensions>>;
|
|
23
|
+
/**
|
|
24
|
+
* Headers for change messages
|
|
25
|
+
*/
|
|
26
|
+
type ChangeHeaders = {
|
|
27
|
+
operation: Operation;
|
|
28
|
+
txid?: string;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A change event represents a state change event (insert/update/delete)
|
|
33
|
+
*/
|
|
34
|
+
type ChangeEvent<T = unknown> = {
|
|
35
|
+
type: string;
|
|
36
|
+
key: string;
|
|
37
|
+
value?: T;
|
|
38
|
+
old_value?: T;
|
|
39
|
+
headers: ChangeHeaders;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Control event types for stream management
|
|
43
|
+
*/
|
|
44
|
+
type ControlEvent = {
|
|
45
|
+
headers: {
|
|
46
|
+
control: `snapshot-start` | `snapshot-end` | `reset`;
|
|
47
|
+
offset?: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A state event is either a change event or a control event
|
|
52
|
+
*/
|
|
53
|
+
type StateEvent<T = unknown> = ChangeEvent<T> | ControlEvent;
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if an event is a change event
|
|
56
|
+
*/
|
|
57
|
+
declare function isChangeEvent<T = unknown>(event: StateEvent<T>): event is ChangeEvent<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Type guard to check if an event is a control event
|
|
60
|
+
*/
|
|
61
|
+
declare function isControlEvent<T = unknown>(event: StateEvent<T>): event is ControlEvent;
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/materialized-state.d.ts
|
|
65
|
+
/**
|
|
66
|
+
* MaterializedState maintains an in-memory view of state from change events.
|
|
67
|
+
*
|
|
68
|
+
* It organizes data by type, where each type contains a map of key -> value.
|
|
69
|
+
* This supports multi-type streams where different entity types can coexist.
|
|
70
|
+
*/
|
|
71
|
+
declare class MaterializedState {
|
|
72
|
+
private data;
|
|
73
|
+
constructor();
|
|
74
|
+
/**
|
|
75
|
+
* Apply a single change event to update the materialized state
|
|
76
|
+
*/
|
|
77
|
+
apply(event: ChangeEvent): void;
|
|
78
|
+
/**
|
|
79
|
+
* Apply a batch of change events
|
|
80
|
+
*/
|
|
81
|
+
applyBatch(events: Array<ChangeEvent>): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get a specific value by type and key
|
|
84
|
+
*/
|
|
85
|
+
get<T = unknown>(type: string, key: string): T | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Get all entries for a specific type
|
|
88
|
+
*/
|
|
89
|
+
getType(type: string): Map<string, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Clear all state
|
|
92
|
+
*/
|
|
93
|
+
clear(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Get the number of types in the state
|
|
96
|
+
*/
|
|
97
|
+
get typeCount(): number;
|
|
98
|
+
/**
|
|
99
|
+
* Get all type names
|
|
100
|
+
*/
|
|
101
|
+
get types(): Array<string>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/stream-db.d.ts
|
|
106
|
+
/**
|
|
107
|
+
* Definition for a single collection in the stream state
|
|
108
|
+
*/
|
|
109
|
+
interface CollectionDefinition<T = unknown> {
|
|
110
|
+
/** Standard Schema for validating values */
|
|
111
|
+
schema: StandardSchemaV1<T>;
|
|
112
|
+
/** The type field value in change events that map to this collection */
|
|
113
|
+
type: string;
|
|
114
|
+
/** The property name in T that serves as the primary key */
|
|
115
|
+
primaryKey: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Helper methods for creating change events for a collection
|
|
119
|
+
*/
|
|
120
|
+
interface CollectionEventHelpers<T> {
|
|
121
|
+
/**
|
|
122
|
+
* Create an insert change event
|
|
123
|
+
*/
|
|
124
|
+
insert: (params: {
|
|
125
|
+
key?: string;
|
|
126
|
+
value: T;
|
|
127
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
128
|
+
}) => ChangeEvent<T>;
|
|
129
|
+
/**
|
|
130
|
+
* Create an update change event
|
|
131
|
+
*/
|
|
132
|
+
update: (params: {
|
|
133
|
+
key?: string;
|
|
134
|
+
value: T;
|
|
135
|
+
oldValue?: T;
|
|
136
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
137
|
+
}) => ChangeEvent<T>;
|
|
138
|
+
/**
|
|
139
|
+
* Create a delete change event
|
|
140
|
+
*/
|
|
141
|
+
delete: (params: {
|
|
142
|
+
key?: string;
|
|
143
|
+
oldValue?: T;
|
|
144
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
145
|
+
}) => ChangeEvent<T>;
|
|
146
|
+
/**
|
|
147
|
+
* Create an upsert change event (insert or update)
|
|
148
|
+
*/
|
|
149
|
+
upsert: (params: {
|
|
150
|
+
key?: string;
|
|
151
|
+
value: T;
|
|
152
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
153
|
+
}) => ChangeEvent<T>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Collection definition enhanced with event creation helpers
|
|
157
|
+
*/
|
|
158
|
+
type CollectionWithHelpers<T = unknown> = CollectionDefinition<T> & CollectionEventHelpers<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Stream state definition containing all collections
|
|
161
|
+
*/
|
|
162
|
+
type StreamStateDefinition = Record<string, CollectionDefinition>;
|
|
163
|
+
/**
|
|
164
|
+
* Stream state schema with helper methods for creating change events
|
|
165
|
+
*/
|
|
166
|
+
type StateSchema<T extends Record<string, CollectionDefinition>> = { [K in keyof T]: CollectionWithHelpers<T[K] extends CollectionDefinition<infer U> ? U : unknown> };
|
|
167
|
+
/**
|
|
168
|
+
* Definition for a single action that can be passed to createOptimisticAction
|
|
169
|
+
*/
|
|
170
|
+
interface ActionDefinition<TParams = any, TContext = any> {
|
|
171
|
+
onMutate: (params: TParams) => void;
|
|
172
|
+
mutationFn: (params: TParams, context: TContext) => Promise<any>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Factory function for creating actions with access to db and stream context
|
|
176
|
+
*/
|
|
177
|
+
type ActionFactory<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>>> = (context: {
|
|
178
|
+
db: StreamDB<TDef>;
|
|
179
|
+
stream: DurableStream;
|
|
180
|
+
}) => TActions;
|
|
181
|
+
/**
|
|
182
|
+
* Map action definitions to callable action functions
|
|
183
|
+
*/
|
|
184
|
+
type ActionMap<TActions extends Record<string, ActionDefinition<any>>> = { [K in keyof TActions]: ReturnType<typeof createOptimisticAction<any>> };
|
|
185
|
+
/**
|
|
186
|
+
* Options for creating a stream DB
|
|
187
|
+
*/
|
|
188
|
+
interface CreateStreamDBOptions<TDef extends StreamStateDefinition = StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>> = Record<string, never>> {
|
|
189
|
+
/** Options for creating the durable stream (stream is created lazily on preload) */
|
|
190
|
+
streamOptions: DurableStreamOptions;
|
|
191
|
+
/** The stream state definition */
|
|
192
|
+
state: TDef;
|
|
193
|
+
/** Optional factory function to create actions with db and stream context */
|
|
194
|
+
actions?: ActionFactory<TDef, TActions>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Extract the value type from a CollectionDefinition
|
|
198
|
+
*/
|
|
199
|
+
type ExtractCollectionType<T extends CollectionDefinition> = T extends CollectionDefinition<infer U> ? U : unknown;
|
|
200
|
+
/**
|
|
201
|
+
* Map collection definitions to TanStack DB Collection types
|
|
202
|
+
*/
|
|
203
|
+
type CollectionMap<TDef extends StreamStateDefinition> = { [K in keyof TDef]: Collection<ExtractCollectionType<TDef[K]> & object, string> };
|
|
204
|
+
/**
|
|
205
|
+
* The StreamDB interface - provides typed access to collections
|
|
206
|
+
*/
|
|
207
|
+
type StreamDB<TDef extends StreamStateDefinition> = {
|
|
208
|
+
collections: CollectionMap<TDef>;
|
|
209
|
+
} & StreamDBMethods;
|
|
210
|
+
/**
|
|
211
|
+
* StreamDB with actions
|
|
212
|
+
*/
|
|
213
|
+
type StreamDBWithActions<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>>> = StreamDB<TDef> & {
|
|
214
|
+
actions: ActionMap<TActions>;
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Utility methods available on StreamDB
|
|
218
|
+
*/
|
|
219
|
+
interface StreamDBUtils {
|
|
220
|
+
/**
|
|
221
|
+
* Wait for a specific transaction ID to be synced through the stream
|
|
222
|
+
* @param txid The transaction ID to wait for (UUID string)
|
|
223
|
+
* @param timeout Optional timeout in milliseconds (defaults to 5000ms)
|
|
224
|
+
* @returns Promise that resolves when the txid is synced
|
|
225
|
+
*/
|
|
226
|
+
awaitTxId: (txid: string, timeout?: number) => Promise<void>;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Methods available on a StreamDB instance
|
|
230
|
+
*/
|
|
231
|
+
interface StreamDBMethods {
|
|
232
|
+
/**
|
|
233
|
+
* The underlying DurableStream instance
|
|
234
|
+
*/
|
|
235
|
+
stream: DurableStream;
|
|
236
|
+
/**
|
|
237
|
+
* Preload all collections by consuming the stream until up-to-date
|
|
238
|
+
*/
|
|
239
|
+
preload: () => Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Close the stream connection and cleanup
|
|
242
|
+
*/
|
|
243
|
+
close: () => void;
|
|
244
|
+
/**
|
|
245
|
+
* Utility methods for advanced stream operations
|
|
246
|
+
*/
|
|
247
|
+
utils: StreamDBUtils;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Create a state schema definition with typed collections and event helpers
|
|
251
|
+
*/
|
|
252
|
+
declare function createStateSchema<T extends Record<string, CollectionDefinition>>(collections: T): StateSchema<T>;
|
|
253
|
+
/**
|
|
254
|
+
* Create a stream-backed database with TanStack DB collections
|
|
255
|
+
*
|
|
256
|
+
* This function is synchronous - it creates the stream handle and collections
|
|
257
|
+
* but does not start the stream connection. Call `db.preload()` to connect
|
|
258
|
+
* and sync initial data.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const stateSchema = createStateSchema({
|
|
263
|
+
* users: { schema: userSchema, type: "user", primaryKey: "id" },
|
|
264
|
+
* messages: { schema: messageSchema, type: "message", primaryKey: "id" },
|
|
265
|
+
* })
|
|
266
|
+
*
|
|
267
|
+
* // Create a stream DB (synchronous - stream is created lazily on preload)
|
|
268
|
+
* const db = createStreamDB({
|
|
269
|
+
* streamOptions: {
|
|
270
|
+
* url: "https://api.example.com/streams/my-stream",
|
|
271
|
+
* contentType: "application/json",
|
|
272
|
+
* },
|
|
273
|
+
* state: stateSchema,
|
|
274
|
+
* })
|
|
275
|
+
*
|
|
276
|
+
* // preload() creates the stream and loads initial data
|
|
277
|
+
* await db.preload()
|
|
278
|
+
* const user = await db.collections.users.get("123")
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function createStreamDB<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>> = Record<string, never>>(options: CreateStreamDBOptions<TDef, TActions>): TActions extends Record<string, never> ? StreamDB<TDef> : StreamDBWithActions<TDef, TActions>;
|
|
282
|
+
|
|
283
|
+
//#endregion
|
|
284
|
+
export { ActionDefinition, ActionFactory, ActionMap, ChangeEvent, ChangeHeaders, CollectionDefinition, CollectionEventHelpers, CollectionWithHelpers, ControlEvent, CreateStreamDBOptions, MaterializedState, Operation, Row, StateEvent, StateSchema, StreamDB, StreamDBMethods, StreamDBUtils, StreamDBWithActions, StreamStateDefinition, Value, createStateSchema, createStreamDB, isChangeEvent, isControlEvent };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { Collection, createOptimisticAction } from "@tanstack/db";
|
|
2
|
+
import { DurableStream, DurableStreamOptions } from "@durable-streams/client";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
|
|
5
|
+
//#region src/types.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Operation types for change events
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Operation types for change events
|
|
11
|
+
*/
|
|
12
|
+
type Operation = `insert` | `update` | `delete` | `upsert`;
|
|
13
|
+
/**
|
|
14
|
+
* A generic value type supporting primitives, arrays, and objects
|
|
15
|
+
*/
|
|
16
|
+
type Value<Extensions = never> = string | number | boolean | bigint | null | Array<Value<Extensions>> | {
|
|
17
|
+
[key: string]: Value<Extensions>;
|
|
18
|
+
} | Extensions;
|
|
19
|
+
/**
|
|
20
|
+
* A row is a record of values
|
|
21
|
+
*/
|
|
22
|
+
type Row<Extensions = never> = Record<string, Value<Extensions>>;
|
|
23
|
+
/**
|
|
24
|
+
* Headers for change messages
|
|
25
|
+
*/
|
|
26
|
+
type ChangeHeaders = {
|
|
27
|
+
operation: Operation;
|
|
28
|
+
txid?: string;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A change event represents a state change event (insert/update/delete)
|
|
33
|
+
*/
|
|
34
|
+
type ChangeEvent<T = unknown> = {
|
|
35
|
+
type: string;
|
|
36
|
+
key: string;
|
|
37
|
+
value?: T;
|
|
38
|
+
old_value?: T;
|
|
39
|
+
headers: ChangeHeaders;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Control event types for stream management
|
|
43
|
+
*/
|
|
44
|
+
type ControlEvent = {
|
|
45
|
+
headers: {
|
|
46
|
+
control: `snapshot-start` | `snapshot-end` | `reset`;
|
|
47
|
+
offset?: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A state event is either a change event or a control event
|
|
52
|
+
*/
|
|
53
|
+
type StateEvent<T = unknown> = ChangeEvent<T> | ControlEvent;
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if an event is a change event
|
|
56
|
+
*/
|
|
57
|
+
declare function isChangeEvent<T = unknown>(event: StateEvent<T>): event is ChangeEvent<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Type guard to check if an event is a control event
|
|
60
|
+
*/
|
|
61
|
+
declare function isControlEvent<T = unknown>(event: StateEvent<T>): event is ControlEvent;
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/materialized-state.d.ts
|
|
65
|
+
/**
|
|
66
|
+
* MaterializedState maintains an in-memory view of state from change events.
|
|
67
|
+
*
|
|
68
|
+
* It organizes data by type, where each type contains a map of key -> value.
|
|
69
|
+
* This supports multi-type streams where different entity types can coexist.
|
|
70
|
+
*/
|
|
71
|
+
declare class MaterializedState {
|
|
72
|
+
private data;
|
|
73
|
+
constructor();
|
|
74
|
+
/**
|
|
75
|
+
* Apply a single change event to update the materialized state
|
|
76
|
+
*/
|
|
77
|
+
apply(event: ChangeEvent): void;
|
|
78
|
+
/**
|
|
79
|
+
* Apply a batch of change events
|
|
80
|
+
*/
|
|
81
|
+
applyBatch(events: Array<ChangeEvent>): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get a specific value by type and key
|
|
84
|
+
*/
|
|
85
|
+
get<T = unknown>(type: string, key: string): T | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Get all entries for a specific type
|
|
88
|
+
*/
|
|
89
|
+
getType(type: string): Map<string, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Clear all state
|
|
92
|
+
*/
|
|
93
|
+
clear(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Get the number of types in the state
|
|
96
|
+
*/
|
|
97
|
+
get typeCount(): number;
|
|
98
|
+
/**
|
|
99
|
+
* Get all type names
|
|
100
|
+
*/
|
|
101
|
+
get types(): Array<string>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/stream-db.d.ts
|
|
106
|
+
/**
|
|
107
|
+
* Definition for a single collection in the stream state
|
|
108
|
+
*/
|
|
109
|
+
interface CollectionDefinition<T = unknown> {
|
|
110
|
+
/** Standard Schema for validating values */
|
|
111
|
+
schema: StandardSchemaV1<T>;
|
|
112
|
+
/** The type field value in change events that map to this collection */
|
|
113
|
+
type: string;
|
|
114
|
+
/** The property name in T that serves as the primary key */
|
|
115
|
+
primaryKey: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Helper methods for creating change events for a collection
|
|
119
|
+
*/
|
|
120
|
+
interface CollectionEventHelpers<T> {
|
|
121
|
+
/**
|
|
122
|
+
* Create an insert change event
|
|
123
|
+
*/
|
|
124
|
+
insert: (params: {
|
|
125
|
+
key?: string;
|
|
126
|
+
value: T;
|
|
127
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
128
|
+
}) => ChangeEvent<T>;
|
|
129
|
+
/**
|
|
130
|
+
* Create an update change event
|
|
131
|
+
*/
|
|
132
|
+
update: (params: {
|
|
133
|
+
key?: string;
|
|
134
|
+
value: T;
|
|
135
|
+
oldValue?: T;
|
|
136
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
137
|
+
}) => ChangeEvent<T>;
|
|
138
|
+
/**
|
|
139
|
+
* Create a delete change event
|
|
140
|
+
*/
|
|
141
|
+
delete: (params: {
|
|
142
|
+
key?: string;
|
|
143
|
+
oldValue?: T;
|
|
144
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
145
|
+
}) => ChangeEvent<T>;
|
|
146
|
+
/**
|
|
147
|
+
* Create an upsert change event (insert or update)
|
|
148
|
+
*/
|
|
149
|
+
upsert: (params: {
|
|
150
|
+
key?: string;
|
|
151
|
+
value: T;
|
|
152
|
+
headers?: Omit<Record<string, string>, `operation`>;
|
|
153
|
+
}) => ChangeEvent<T>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Collection definition enhanced with event creation helpers
|
|
157
|
+
*/
|
|
158
|
+
type CollectionWithHelpers<T = unknown> = CollectionDefinition<T> & CollectionEventHelpers<T>;
|
|
159
|
+
/**
|
|
160
|
+
* Stream state definition containing all collections
|
|
161
|
+
*/
|
|
162
|
+
type StreamStateDefinition = Record<string, CollectionDefinition>;
|
|
163
|
+
/**
|
|
164
|
+
* Stream state schema with helper methods for creating change events
|
|
165
|
+
*/
|
|
166
|
+
type StateSchema<T extends Record<string, CollectionDefinition>> = { [K in keyof T]: CollectionWithHelpers<T[K] extends CollectionDefinition<infer U> ? U : unknown> };
|
|
167
|
+
/**
|
|
168
|
+
* Definition for a single action that can be passed to createOptimisticAction
|
|
169
|
+
*/
|
|
170
|
+
interface ActionDefinition<TParams = any, TContext = any> {
|
|
171
|
+
onMutate: (params: TParams) => void;
|
|
172
|
+
mutationFn: (params: TParams, context: TContext) => Promise<any>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Factory function for creating actions with access to db and stream context
|
|
176
|
+
*/
|
|
177
|
+
type ActionFactory<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>>> = (context: {
|
|
178
|
+
db: StreamDB<TDef>;
|
|
179
|
+
stream: DurableStream;
|
|
180
|
+
}) => TActions;
|
|
181
|
+
/**
|
|
182
|
+
* Map action definitions to callable action functions
|
|
183
|
+
*/
|
|
184
|
+
type ActionMap<TActions extends Record<string, ActionDefinition<any>>> = { [K in keyof TActions]: ReturnType<typeof createOptimisticAction<any>> };
|
|
185
|
+
/**
|
|
186
|
+
* Options for creating a stream DB
|
|
187
|
+
*/
|
|
188
|
+
interface CreateStreamDBOptions<TDef extends StreamStateDefinition = StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>> = Record<string, never>> {
|
|
189
|
+
/** Options for creating the durable stream (stream is created lazily on preload) */
|
|
190
|
+
streamOptions: DurableStreamOptions;
|
|
191
|
+
/** The stream state definition */
|
|
192
|
+
state: TDef;
|
|
193
|
+
/** Optional factory function to create actions with db and stream context */
|
|
194
|
+
actions?: ActionFactory<TDef, TActions>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Extract the value type from a CollectionDefinition
|
|
198
|
+
*/
|
|
199
|
+
type ExtractCollectionType<T extends CollectionDefinition> = T extends CollectionDefinition<infer U> ? U : unknown;
|
|
200
|
+
/**
|
|
201
|
+
* Map collection definitions to TanStack DB Collection types
|
|
202
|
+
*/
|
|
203
|
+
type CollectionMap<TDef extends StreamStateDefinition> = { [K in keyof TDef]: Collection<ExtractCollectionType<TDef[K]> & object, string> };
|
|
204
|
+
/**
|
|
205
|
+
* The StreamDB interface - provides typed access to collections
|
|
206
|
+
*/
|
|
207
|
+
type StreamDB<TDef extends StreamStateDefinition> = {
|
|
208
|
+
collections: CollectionMap<TDef>;
|
|
209
|
+
} & StreamDBMethods;
|
|
210
|
+
/**
|
|
211
|
+
* StreamDB with actions
|
|
212
|
+
*/
|
|
213
|
+
type StreamDBWithActions<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>>> = StreamDB<TDef> & {
|
|
214
|
+
actions: ActionMap<TActions>;
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Utility methods available on StreamDB
|
|
218
|
+
*/
|
|
219
|
+
interface StreamDBUtils {
|
|
220
|
+
/**
|
|
221
|
+
* Wait for a specific transaction ID to be synced through the stream
|
|
222
|
+
* @param txid The transaction ID to wait for (UUID string)
|
|
223
|
+
* @param timeout Optional timeout in milliseconds (defaults to 5000ms)
|
|
224
|
+
* @returns Promise that resolves when the txid is synced
|
|
225
|
+
*/
|
|
226
|
+
awaitTxId: (txid: string, timeout?: number) => Promise<void>;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Methods available on a StreamDB instance
|
|
230
|
+
*/
|
|
231
|
+
interface StreamDBMethods {
|
|
232
|
+
/**
|
|
233
|
+
* The underlying DurableStream instance
|
|
234
|
+
*/
|
|
235
|
+
stream: DurableStream;
|
|
236
|
+
/**
|
|
237
|
+
* Preload all collections by consuming the stream until up-to-date
|
|
238
|
+
*/
|
|
239
|
+
preload: () => Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Close the stream connection and cleanup
|
|
242
|
+
*/
|
|
243
|
+
close: () => void;
|
|
244
|
+
/**
|
|
245
|
+
* Utility methods for advanced stream operations
|
|
246
|
+
*/
|
|
247
|
+
utils: StreamDBUtils;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Create a state schema definition with typed collections and event helpers
|
|
251
|
+
*/
|
|
252
|
+
declare function createStateSchema<T extends Record<string, CollectionDefinition>>(collections: T): StateSchema<T>;
|
|
253
|
+
/**
|
|
254
|
+
* Create a stream-backed database with TanStack DB collections
|
|
255
|
+
*
|
|
256
|
+
* This function is synchronous - it creates the stream handle and collections
|
|
257
|
+
* but does not start the stream connection. Call `db.preload()` to connect
|
|
258
|
+
* and sync initial data.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const stateSchema = createStateSchema({
|
|
263
|
+
* users: { schema: userSchema, type: "user", primaryKey: "id" },
|
|
264
|
+
* messages: { schema: messageSchema, type: "message", primaryKey: "id" },
|
|
265
|
+
* })
|
|
266
|
+
*
|
|
267
|
+
* // Create a stream DB (synchronous - stream is created lazily on preload)
|
|
268
|
+
* const db = createStreamDB({
|
|
269
|
+
* streamOptions: {
|
|
270
|
+
* url: "https://api.example.com/streams/my-stream",
|
|
271
|
+
* contentType: "application/json",
|
|
272
|
+
* },
|
|
273
|
+
* state: stateSchema,
|
|
274
|
+
* })
|
|
275
|
+
*
|
|
276
|
+
* // preload() creates the stream and loads initial data
|
|
277
|
+
* await db.preload()
|
|
278
|
+
* const user = await db.collections.users.get("123")
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function createStreamDB<TDef extends StreamStateDefinition, TActions extends Record<string, ActionDefinition<any>> = Record<string, never>>(options: CreateStreamDBOptions<TDef, TActions>): TActions extends Record<string, never> ? StreamDB<TDef> : StreamDBWithActions<TDef, TActions>;
|
|
282
|
+
|
|
283
|
+
//#endregion
|
|
284
|
+
export { ActionDefinition, ActionFactory, ActionMap, ChangeEvent, ChangeHeaders, CollectionDefinition, CollectionEventHelpers, CollectionWithHelpers, ControlEvent, CreateStreamDBOptions, MaterializedState, Operation, Row, StateEvent, StateSchema, StreamDB, StreamDBMethods, StreamDBUtils, StreamDBWithActions, StreamStateDefinition, Value, createStateSchema, createStreamDB, isChangeEvent, isControlEvent };
|