@datafn/client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,248 @@
1
+ import { DatafnEvent, DatafnSignal, DatafnSchema, DatafnPlugin, DatafnErrorCode } from '@datafn/core';
2
+
3
+ /**
4
+ * Event filtering logic
5
+ */
6
+
7
+ interface EventFilter {
8
+ type?: string | string[];
9
+ resource?: string | string[];
10
+ ids?: string | string[];
11
+ mutationId?: string | string[];
12
+ action?: string | string[];
13
+ fields?: string | string[];
14
+ contextKeys?: string[];
15
+ }
16
+ /**
17
+ * Check if an event matches the filter
18
+ */
19
+ declare function matchesFilter(event: DatafnEvent, filter?: EventFilter): boolean;
20
+
21
+ /**
22
+ * In-process event bus
23
+ */
24
+
25
+ type EventHandler = (event: DatafnEvent) => void;
26
+ /**
27
+ * Simple in-process event bus
28
+ */
29
+ declare class EventBus {
30
+ private subscriptions;
31
+ private nextId;
32
+ /**
33
+ * Subscribe to events with optional filtering
34
+ */
35
+ subscribe(handler: EventHandler, filter?: EventFilter): () => void;
36
+ /**
37
+ * Emit an event to all matching subscribers
38
+ */
39
+ emit(event: DatafnEvent): void;
40
+ }
41
+
42
+ /**
43
+ * DataFn Table Handle
44
+ *
45
+ * Represents a table/resource from the schema with methods for query, mutation, signals, and subscriptions.
46
+ */
47
+
48
+ interface DatafnTable<TRecord = unknown> {
49
+ name: string;
50
+ version: number;
51
+ query(q: unknown): Promise<unknown>;
52
+ mutate(m: unknown): Promise<unknown>;
53
+ transact(payload: unknown): Promise<unknown>;
54
+ signal(q: unknown): DatafnSignal<unknown>;
55
+ subscribe(handler: EventHandler, filter?: EventFilter): () => void;
56
+ }
57
+
58
+ /**
59
+ * Storage adapter types for local persistence
60
+ */
61
+ type DatafnHydrationState = "notStarted" | "hydrating" | "ready";
62
+ type DatafnChangelogEntry = {
63
+ /** Monotonic local sequence (assigned by storage adapter). */
64
+ seq: number;
65
+ clientId: string;
66
+ mutationId: string;
67
+ mutation: Record<string, unknown>;
68
+ timestampMs: number;
69
+ };
70
+ interface DatafnStorageAdapter {
71
+ getRecord(resource: string, id: string): Promise<Record<string, unknown> | null>;
72
+ listRecords(resource: string): Promise<Record<string, unknown>[]>;
73
+ upsertRecord(resource: string, record: Record<string, unknown>): Promise<void>;
74
+ deleteRecord(resource: string, id: string): Promise<void>;
75
+ listJoinRows(relationKey: string): Promise<Array<Record<string, unknown>>>;
76
+ upsertJoinRow(relationKey: string, row: Record<string, unknown>): Promise<void>;
77
+ deleteJoinRow(relationKey: string, from: string, to: string): Promise<void>;
78
+ getCursor(resource: string): Promise<string | null>;
79
+ setCursor(resource: string, cursor: string): Promise<void>;
80
+ getHydrationState(resource: string): Promise<DatafnHydrationState>;
81
+ setHydrationState(resource: string, state: DatafnHydrationState): Promise<void>;
82
+ changelogAppend(entry: Omit<DatafnChangelogEntry, "seq">): Promise<DatafnChangelogEntry>;
83
+ changelogList(options?: {
84
+ limit?: number;
85
+ }): Promise<DatafnChangelogEntry[]>;
86
+ changelogAck(options: {
87
+ throughSeq: number;
88
+ }): Promise<void>;
89
+ }
90
+
91
+ /**
92
+ * Sync Facade
93
+ *
94
+ * Client-side sync methods that delegate to remote adapter.
95
+ * When storage is configured, clone/pull results are applied to local storage.
96
+ */
97
+
98
+ interface SyncFacade {
99
+ seed(payload: unknown): Promise<unknown>;
100
+ clone(payload: unknown): Promise<unknown>;
101
+ pull(payload: unknown): Promise<unknown>;
102
+ push(payload: unknown): Promise<unknown>;
103
+ }
104
+
105
+ /**
106
+ * DataFn client factory
107
+ */
108
+
109
+ interface DatafnRemoteAdapter {
110
+ query(q: unknown): Promise<unknown>;
111
+ mutation(m: unknown): Promise<unknown>;
112
+ transact(t: unknown): Promise<unknown>;
113
+ seed(payload: unknown): Promise<unknown>;
114
+ clone(payload: unknown): Promise<unknown>;
115
+ pull(payload: unknown): Promise<unknown>;
116
+ push(payload: unknown): Promise<unknown>;
117
+ }
118
+ interface DatafnClientConfig {
119
+ schema: DatafnSchema;
120
+ remote: DatafnRemoteAdapter;
121
+ /**
122
+ * Optional plugins for client-side hook execution
123
+ */
124
+ plugins?: DatafnPlugin[];
125
+ /**
126
+ * Stable client/device identifier used for idempotency and offline change logs.
127
+ * Required when `storage` is provided.
128
+ */
129
+ clientId?: string;
130
+ /**
131
+ * Local persistence adapter. When provided, sync results are applied to local storage.
132
+ */
133
+ storage?: DatafnStorageAdapter;
134
+ getTimestamp?: () => number;
135
+ }
136
+ interface DatafnClient {
137
+ table<TRecord = unknown>(name: string): DatafnTable<TRecord>;
138
+ query(q: unknown | unknown[]): Promise<unknown>;
139
+ mutate(mutation: unknown | unknown[]): Promise<unknown>;
140
+ transact(payload: unknown): Promise<unknown>;
141
+ subscribe(handler: EventHandler, filter?: EventFilter): () => void;
142
+ sync: SyncFacade;
143
+ }
144
+ /**
145
+ * Create a DataFn client
146
+ */
147
+ declare function createDatafnClient(config: DatafnClientConfig): DatafnClient;
148
+
149
+ /**
150
+ * DataFn Client Error Types
151
+ */
152
+
153
+ type DatafnClientError = {
154
+ code: DatafnErrorCode | "TRANSPORT_ERROR";
155
+ message: string;
156
+ details: {
157
+ path: string;
158
+ [key: string]: unknown;
159
+ };
160
+ };
161
+ /**
162
+ * Create a DataFnClientError and throw it
163
+ */
164
+ declare function createClientError(code: DatafnClientError["code"], message: string, details: {
165
+ path: string;
166
+ [key: string]: unknown;
167
+ }): never;
168
+
169
+ /**
170
+ * Remote Response Unwrapping Utilities
171
+ *
172
+ * Handles both wrapped (DatafnEnvelope) and unwrapped server responses.
173
+ */
174
+ /**
175
+ * Unwrap a remote response that may be wrapped in DatafnEnvelope or unwrapped.
176
+ *
177
+ * - If wrapped success `{ ok: true, result }`, return `result`
178
+ * - If wrapped error `{ ok: false, error }`, throw DatafnClientError
179
+ * - If unwrapped query result `{ data, nextCursor }`, return as-is
180
+ * - If unwrapped aggregate result `{ groups, nextCursor }`, return as-is
181
+ * - Otherwise throw TRANSPORT_ERROR
182
+ */
183
+ declare function unwrapRemoteSuccess<T>(response: unknown): T;
184
+
185
+ /**
186
+ * In-memory storage adapter for testing and development.
187
+ * Implements deterministic ordering and changelog deduplication.
188
+ */
189
+
190
+ declare class MemoryStorageAdapter implements DatafnStorageAdapter {
191
+ private records;
192
+ private joinRows;
193
+ private cursors;
194
+ private hydration;
195
+ private changelog;
196
+ private changelogSeq;
197
+ constructor();
198
+ getRecord(resource: string, id: string): Promise<Record<string, unknown> | null>;
199
+ listRecords(resource: string): Promise<Record<string, unknown>[]>;
200
+ upsertRecord(resource: string, record: Record<string, unknown>): Promise<void>;
201
+ deleteRecord(resource: string, id: string): Promise<void>;
202
+ listJoinRows(relationKey: string): Promise<Array<Record<string, unknown>>>;
203
+ upsertJoinRow(relationKey: string, row: Record<string, unknown>): Promise<void>;
204
+ deleteJoinRow(relationKey: string, from: string, to: string): Promise<void>;
205
+ getCursor(resource: string): Promise<string | null>;
206
+ setCursor(resource: string, cursor: string): Promise<void>;
207
+ getHydrationState(resource: string): Promise<DatafnHydrationState>;
208
+ setHydrationState(resource: string, state: DatafnHydrationState): Promise<void>;
209
+ changelogAppend(entry: Omit<DatafnChangelogEntry, "seq">): Promise<DatafnChangelogEntry>;
210
+ changelogList(options?: {
211
+ limit?: number;
212
+ }): Promise<DatafnChangelogEntry[]>;
213
+ changelogAck(options: {
214
+ throughSeq: number;
215
+ }): Promise<void>;
216
+ clear(): void;
217
+ }
218
+
219
+ /**
220
+ * IndexedDB storage adapter for persistent client storage.
221
+ * Implements deterministic ordering and changelog deduplication.
222
+ */
223
+
224
+ declare class IndexedDbStorageAdapter implements DatafnStorageAdapter {
225
+ private dbPromise;
226
+ constructor(dbName?: string);
227
+ private getStore;
228
+ getRecord(resource: string, id: string): Promise<Record<string, unknown> | null>;
229
+ listRecords(resource: string): Promise<Record<string, unknown>[]>;
230
+ upsertRecord(resource: string, record: Record<string, unknown>): Promise<void>;
231
+ deleteRecord(resource: string, id: string): Promise<void>;
232
+ listJoinRows(relationKey: string): Promise<Array<Record<string, unknown>>>;
233
+ upsertJoinRow(relationKey: string, row: Record<string, unknown>): Promise<void>;
234
+ deleteJoinRow(relationKey: string, from: string, to: string): Promise<void>;
235
+ getCursor(resource: string): Promise<string | null>;
236
+ setCursor(resource: string, cursor: string): Promise<void>;
237
+ getHydrationState(resource: string): Promise<DatafnHydrationState>;
238
+ setHydrationState(resource: string, state: DatafnHydrationState): Promise<void>;
239
+ changelogAppend(entry: Omit<DatafnChangelogEntry, "seq">): Promise<DatafnChangelogEntry>;
240
+ changelogList(options?: {
241
+ limit?: number;
242
+ }): Promise<DatafnChangelogEntry[]>;
243
+ changelogAck(options: {
244
+ throughSeq: number;
245
+ }): Promise<void>;
246
+ }
247
+
248
+ export { type DatafnChangelogEntry, type DatafnClient, type DatafnClientConfig, type DatafnClientError, type DatafnHydrationState, type DatafnRemoteAdapter, type DatafnStorageAdapter, type DatafnTable, EventBus, type EventFilter, type EventHandler, IndexedDbStorageAdapter, MemoryStorageAdapter, createClientError, createDatafnClient, matchesFilter, unwrapRemoteSuccess };