@mdxui/terminal 2.0.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.
Files changed (191) hide show
  1. package/README.md +571 -0
  2. package/dist/ansi-css-Sk5mWtdK.d.ts +119 -0
  3. package/dist/ansi-css-V6JIHGsM.d.ts +119 -0
  4. package/dist/ansi-css-_3eSEU9d.d.ts +119 -0
  5. package/dist/chunk-3EFDH7PK.js +5235 -0
  6. package/dist/chunk-3RG5ZIWI.js +10 -0
  7. package/dist/chunk-3X5IR6WE.js +884 -0
  8. package/dist/chunk-4FV5ZDCE.js +5236 -0
  9. package/dist/chunk-4OVMSF2J.js +243 -0
  10. package/dist/chunk-63FEETIS.js +4048 -0
  11. package/dist/chunk-B43KP7XJ.js +884 -0
  12. package/dist/chunk-BMTJXWUV.js +655 -0
  13. package/dist/chunk-C3SVH4N7.js +882 -0
  14. package/dist/chunk-EVWR7Y47.js +874 -0
  15. package/dist/chunk-F6A5VWUC.js +1285 -0
  16. package/dist/chunk-FD7KW7GE.js +882 -0
  17. package/dist/chunk-GBQ6UD6I.js +655 -0
  18. package/dist/chunk-GMDD3M6U.js +5227 -0
  19. package/dist/chunk-JBHRXOXM.js +1058 -0
  20. package/dist/chunk-JFOO3EYO.js +1182 -0
  21. package/dist/chunk-JQ5H3WXL.js +1291 -0
  22. package/dist/chunk-JQD5NASE.js +234 -0
  23. package/dist/chunk-KRHJP5R7.js +592 -0
  24. package/dist/chunk-KWF6WVJE.js +962 -0
  25. package/dist/chunk-LHYQVN3H.js +1038 -0
  26. package/dist/chunk-M3TLQLGC.js +1032 -0
  27. package/dist/chunk-MVW4Q5OP.js +240 -0
  28. package/dist/chunk-NXCZSWLU.js +1294 -0
  29. package/dist/chunk-O25TNRO6.js +607 -0
  30. package/dist/chunk-PNECDA2I.js +884 -0
  31. package/dist/chunk-QIHWRLJR.js +962 -0
  32. package/dist/chunk-QW5YMQ7K.js +882 -0
  33. package/dist/chunk-R5U7XKVJ.js +16 -0
  34. package/dist/chunk-RP2MVQLR.js +962 -0
  35. package/dist/chunk-TP6RXGXA.js +1087 -0
  36. package/dist/chunk-TQQSTITZ.js +655 -0
  37. package/dist/chunk-X24GWXQV.js +1281 -0
  38. package/dist/components/index.d.ts +802 -0
  39. package/dist/components/index.js +149 -0
  40. package/dist/data/index.d.ts +2554 -0
  41. package/dist/data/index.js +51 -0
  42. package/dist/forms/index.d.ts +1596 -0
  43. package/dist/forms/index.js +464 -0
  44. package/dist/index-CQRFZntR.d.ts +867 -0
  45. package/dist/index.d.ts +579 -0
  46. package/dist/index.js +786 -0
  47. package/dist/interactive-D0JkWosD.d.ts +217 -0
  48. package/dist/keyboard/index.d.ts +2 -0
  49. package/dist/keyboard/index.js +43 -0
  50. package/dist/renderers/index.d.ts +546 -0
  51. package/dist/renderers/index.js +2157 -0
  52. package/dist/storybook/index.d.ts +396 -0
  53. package/dist/storybook/index.js +641 -0
  54. package/dist/theme/index.d.ts +1339 -0
  55. package/dist/theme/index.js +123 -0
  56. package/dist/types-Bxu5PAgA.d.ts +710 -0
  57. package/dist/types-CIlop5Ji.d.ts +701 -0
  58. package/dist/types-Ca8p_p5X.d.ts +710 -0
  59. package/package.json +90 -0
  60. package/src/__tests__/components/data/card.test.ts +458 -0
  61. package/src/__tests__/components/data/list.test.ts +473 -0
  62. package/src/__tests__/components/data/metrics.test.ts +541 -0
  63. package/src/__tests__/components/data/table.test.ts +448 -0
  64. package/src/__tests__/components/input/field.test.ts +555 -0
  65. package/src/__tests__/components/input/form.test.ts +870 -0
  66. package/src/__tests__/components/input/search.test.ts +1238 -0
  67. package/src/__tests__/components/input/select.test.ts +658 -0
  68. package/src/__tests__/components/navigation/breadcrumb.test.ts +923 -0
  69. package/src/__tests__/components/navigation/command-palette.test.ts +1095 -0
  70. package/src/__tests__/components/navigation/sidebar.test.ts +1018 -0
  71. package/src/__tests__/components/navigation/tabs.test.ts +995 -0
  72. package/src/__tests__/components.test.tsx +1197 -0
  73. package/src/__tests__/core/compiler.test.ts +986 -0
  74. package/src/__tests__/core/parser.test.ts +785 -0
  75. package/src/__tests__/core/tier-switcher.test.ts +1103 -0
  76. package/src/__tests__/core/types.test.ts +1398 -0
  77. package/src/__tests__/data/collections.test.ts +1337 -0
  78. package/src/__tests__/data/db.test.ts +1265 -0
  79. package/src/__tests__/data/reactive.test.ts +1010 -0
  80. package/src/__tests__/data/sync.test.ts +1614 -0
  81. package/src/__tests__/errors.test.ts +660 -0
  82. package/src/__tests__/forms/integration.test.ts +444 -0
  83. package/src/__tests__/integration.test.ts +905 -0
  84. package/src/__tests__/keyboard.test.ts +1791 -0
  85. package/src/__tests__/renderer.test.ts +489 -0
  86. package/src/__tests__/renderers/ansi-css.test.ts +948 -0
  87. package/src/__tests__/renderers/ansi.test.ts +1366 -0
  88. package/src/__tests__/renderers/ascii.test.ts +1360 -0
  89. package/src/__tests__/renderers/interactive.test.ts +2353 -0
  90. package/src/__tests__/renderers/markdown.test.ts +1483 -0
  91. package/src/__tests__/renderers/text.test.ts +1369 -0
  92. package/src/__tests__/renderers/unicode.test.ts +1307 -0
  93. package/src/__tests__/theme.test.ts +639 -0
  94. package/src/__tests__/utils/assertions.ts +685 -0
  95. package/src/__tests__/utils/index.ts +115 -0
  96. package/src/__tests__/utils/test-renderer.ts +381 -0
  97. package/src/__tests__/utils/utils.test.ts +560 -0
  98. package/src/components/containers/card.ts +56 -0
  99. package/src/components/containers/dialog.ts +53 -0
  100. package/src/components/containers/index.ts +9 -0
  101. package/src/components/containers/panel.ts +59 -0
  102. package/src/components/feedback/badge.ts +40 -0
  103. package/src/components/feedback/index.ts +8 -0
  104. package/src/components/feedback/spinner.ts +23 -0
  105. package/src/components/helpers.ts +81 -0
  106. package/src/components/index.ts +153 -0
  107. package/src/components/layout/breadcrumb.ts +31 -0
  108. package/src/components/layout/index.ts +10 -0
  109. package/src/components/layout/list.ts +29 -0
  110. package/src/components/layout/sidebar.ts +79 -0
  111. package/src/components/layout/table.ts +62 -0
  112. package/src/components/primitives/box.ts +95 -0
  113. package/src/components/primitives/button.ts +54 -0
  114. package/src/components/primitives/index.ts +11 -0
  115. package/src/components/primitives/input.ts +88 -0
  116. package/src/components/primitives/select.ts +97 -0
  117. package/src/components/primitives/text.ts +60 -0
  118. package/src/components/render.ts +155 -0
  119. package/src/components/templates/app.ts +43 -0
  120. package/src/components/templates/index.ts +8 -0
  121. package/src/components/templates/site.ts +54 -0
  122. package/src/components/types.ts +777 -0
  123. package/src/core/compiler.ts +718 -0
  124. package/src/core/parser.ts +127 -0
  125. package/src/core/tier-switcher.ts +607 -0
  126. package/src/core/types.ts +672 -0
  127. package/src/data/collection.ts +316 -0
  128. package/src/data/collections.ts +50 -0
  129. package/src/data/context.tsx +174 -0
  130. package/src/data/db.ts +127 -0
  131. package/src/data/hooks.ts +532 -0
  132. package/src/data/index.ts +138 -0
  133. package/src/data/reactive.ts +1225 -0
  134. package/src/data/saas-collections.ts +375 -0
  135. package/src/data/sync.ts +1213 -0
  136. package/src/data/types.ts +660 -0
  137. package/src/forms/converters.ts +512 -0
  138. package/src/forms/index.ts +133 -0
  139. package/src/forms/schemas.ts +403 -0
  140. package/src/forms/types.ts +476 -0
  141. package/src/index.ts +542 -0
  142. package/src/keyboard/focus.ts +748 -0
  143. package/src/keyboard/index.ts +96 -0
  144. package/src/keyboard/integration.ts +371 -0
  145. package/src/keyboard/manager.ts +377 -0
  146. package/src/keyboard/presets.ts +90 -0
  147. package/src/renderers/ansi-css.ts +576 -0
  148. package/src/renderers/ansi.ts +802 -0
  149. package/src/renderers/ascii.ts +680 -0
  150. package/src/renderers/breadcrumb.ts +480 -0
  151. package/src/renderers/command-palette.ts +802 -0
  152. package/src/renderers/components/field.ts +210 -0
  153. package/src/renderers/components/form.ts +327 -0
  154. package/src/renderers/components/index.ts +21 -0
  155. package/src/renderers/components/search.ts +449 -0
  156. package/src/renderers/components/select.ts +222 -0
  157. package/src/renderers/index.ts +101 -0
  158. package/src/renderers/interactive/component-handlers.ts +622 -0
  159. package/src/renderers/interactive/cursor-manager.ts +147 -0
  160. package/src/renderers/interactive/focus-manager.ts +279 -0
  161. package/src/renderers/interactive/index.ts +661 -0
  162. package/src/renderers/interactive/input-handler.ts +164 -0
  163. package/src/renderers/interactive/keyboard-handler.ts +212 -0
  164. package/src/renderers/interactive/mouse-handler.ts +167 -0
  165. package/src/renderers/interactive/state-manager.ts +109 -0
  166. package/src/renderers/interactive/types.ts +338 -0
  167. package/src/renderers/interactive-string.ts +299 -0
  168. package/src/renderers/interactive.ts +59 -0
  169. package/src/renderers/markdown.ts +950 -0
  170. package/src/renderers/sidebar.ts +549 -0
  171. package/src/renderers/tabs.ts +682 -0
  172. package/src/renderers/text.ts +791 -0
  173. package/src/renderers/unicode.ts +917 -0
  174. package/src/renderers/utils.ts +942 -0
  175. package/src/router/adapters.ts +383 -0
  176. package/src/router/types.ts +140 -0
  177. package/src/router/utils.ts +452 -0
  178. package/src/schemas.ts +205 -0
  179. package/src/storybook/index.ts +91 -0
  180. package/src/storybook/interactive-decorator.tsx +659 -0
  181. package/src/storybook/keyboard-simulator.ts +501 -0
  182. package/src/theme/ansi-codes.ts +80 -0
  183. package/src/theme/box-drawing.ts +132 -0
  184. package/src/theme/color-convert.ts +254 -0
  185. package/src/theme/color-support.ts +321 -0
  186. package/src/theme/index.ts +134 -0
  187. package/src/theme/strip-ansi.ts +50 -0
  188. package/src/theme/tailwind-map.ts +469 -0
  189. package/src/theme/text-styles.ts +206 -0
  190. package/src/theme/theme-system.ts +568 -0
  191. package/src/types.ts +103 -0
@@ -0,0 +1,2554 @@
1
+ import { ZodSchema, z } from 'zod';
2
+ import * as React from 'react';
3
+ import { ReactNode } from 'react';
4
+
5
+ /**
6
+ * @mdxui/terminal Data Layer Types
7
+ *
8
+ * Type definitions for the TanStack DB-like integration.
9
+ * Provides a type-safe, reactive in-memory database with Zod validation,
10
+ * filtering, sorting, pagination, and optimistic updates.
11
+ */
12
+
13
+ /**
14
+ * Comparison operators for filtering database queries
15
+ *
16
+ * @template T - The type of the field being compared
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Using comparison operators in a where clause
21
+ * {
22
+ * $eq: 5, // Equal to 5
23
+ * $ne: 10, // Not equal to 10
24
+ * $gt: 3, // Greater than 3
25
+ * $gte: 3, // Greater than or equal to 3
26
+ * $lt: 100, // Less than 100
27
+ * $lte: 100, // Less than or equal to 100
28
+ * $in: [1, 2, 3], // In array [1, 2, 3]
29
+ * $nin: [1, 2, 3], // Not in array [1, 2, 3]
30
+ * }
31
+ * ```
32
+ */
33
+ interface ComparisonOperators<T> {
34
+ /** Equality match */
35
+ $eq?: T;
36
+ /** Not equal to */
37
+ $ne?: T;
38
+ /** Greater than */
39
+ $gt?: T;
40
+ /** Greater than or equal to */
41
+ $gte?: T;
42
+ /** Less than */
43
+ $lt?: T;
44
+ /** Less than or equal to */
45
+ $lte?: T;
46
+ /** Value is in array */
47
+ $in?: T[];
48
+ /** Value is not in array */
49
+ $nin?: T[];
50
+ }
51
+ /**
52
+ * Field filter - either a direct value for equality or comparison operators
53
+ *
54
+ * @template T - The type of the field
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Direct equality
59
+ * type Filter = FieldFilter<number> // number
60
+ * const filter: Filter = 5
61
+ *
62
+ * // With operators
63
+ * const filter: Filter = { $gt: 5 }
64
+ * ```
65
+ */
66
+ type FieldFilter<T> = T | ComparisonOperators<T>;
67
+ /**
68
+ * Where clause for filtering - supports equality, comparison operators, and $or
69
+ *
70
+ * @template T - The document type being queried
71
+ *
72
+ * @remarks
73
+ * - Uses AND logic for multiple field conditions
74
+ * - `$or` is an array of alternative conditions (OR logic)
75
+ * - Can combine $or with other fields (fields AND ($or[...]))
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * // Simple equality
80
+ * const where: WhereClause<User> = { role: 'admin' }
81
+ *
82
+ * // With comparison operators
83
+ * const where: WhereClause<User> = { age: { $gte: 18 } }
84
+ *
85
+ * // Multiple conditions (AND)
86
+ * const where: WhereClause<User> = {
87
+ * role: 'admin',
88
+ * age: { $gte: 18 }
89
+ * }
90
+ *
91
+ * // OR conditions
92
+ * const where: WhereClause<User> = {
93
+ * $or: [
94
+ * { role: 'admin' },
95
+ * { role: 'moderator' }
96
+ * ]
97
+ * }
98
+ *
99
+ * // Combined AND/OR
100
+ * const where: WhereClause<User> = {
101
+ * status: 'active',
102
+ * $or: [
103
+ * { role: 'admin' },
104
+ * { role: 'moderator' }
105
+ * ]
106
+ * }
107
+ * ```
108
+ */
109
+ type WhereClause<T> = {
110
+ [K in keyof T]?: FieldFilter<T[K]>;
111
+ } & {
112
+ $or?: Array<WhereClause<T>>;
113
+ };
114
+ /**
115
+ * Sort direction for ordering results
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * type Direction = OrderDirection
120
+ * const ascending: Direction = 'asc'
121
+ * const descending: Direction = 'desc'
122
+ * ```
123
+ */
124
+ type OrderDirection = 'asc' | 'desc';
125
+ /**
126
+ * Order by clause for sorting results
127
+ *
128
+ * @template T - The document type being sorted
129
+ *
130
+ * @remarks
131
+ * Maps field names to sort directions (asc/desc)
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * // Sort by age ascending
136
+ * const orderBy: OrderByClause<User> = { age: 'asc' }
137
+ *
138
+ * // Sort by multiple fields
139
+ * const orderByArray: OrderByClause<User>[] = [
140
+ * { role: 'asc' },
141
+ * { age: 'desc' }
142
+ * ]
143
+ * ```
144
+ */
145
+ type OrderByClause<T> = {
146
+ [K in keyof T]?: OrderDirection;
147
+ };
148
+ /**
149
+ * A typed in-memory collection with CRUD operations, filtering, sorting, and reactive subscriptions
150
+ *
151
+ * @template T - The document type stored in this collection
152
+ *
153
+ * @remarks
154
+ * - All documents are validated against the schema on insert/update
155
+ * - Provides reactive subscriptions for real-time updates
156
+ * - Supports filtering with where clauses and comparison operators
157
+ * - Supports sorting with orderBy and multiple sort fields
158
+ * - Supports pagination with limit and offset
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * const collection = createCollection<User>({
163
+ * name: 'users',
164
+ * schema: UserSchema
165
+ * })
166
+ *
167
+ * // CRUD operations
168
+ * const user = await collection.insert({ id: '1', name: 'Alice', ... })
169
+ * const updated = await collection.update({ id: '1' }, { name: 'Alicia' })
170
+ * const found = await collection.findOne({ id: '1' })
171
+ * const all = await collection.findMany()
172
+ * await collection.delete({ id: '1' })
173
+ *
174
+ * // Subscribe to changes
175
+ * const unsubscribe = collection.subscribe((data) => {
176
+ * console.log('Collection changed:', data)
177
+ * })
178
+ * ```
179
+ */
180
+ interface Collection<T> {
181
+ /** Collection name - used to reference in queries */
182
+ name: string;
183
+ /** Zod schema for validation */
184
+ schema: ZodSchema<T>;
185
+ /** Primary key field name */
186
+ primaryKey: string;
187
+ /** Indexed field names */
188
+ indexes: string[];
189
+ /**
190
+ * Insert a new document into the collection
191
+ *
192
+ * @param data - Document to insert (must match schema)
193
+ * @returns The validated document
194
+ * @throws If document fails schema validation or primary key already exists
195
+ */
196
+ insert(data: T): Promise<T>;
197
+ /**
198
+ * Update one or more documents matching the filter
199
+ *
200
+ * @param filter - Documents matching this filter will be updated
201
+ * @param data - Partial updates to apply (merged with existing data)
202
+ * @returns Array of updated documents
203
+ * @throws If updated documents fail schema validation
204
+ */
205
+ update(filter: Partial<T>, data: Partial<T>): Promise<T[]>;
206
+ /**
207
+ * Delete one or more documents matching the filter
208
+ *
209
+ * @param filter - Documents matching this filter will be deleted
210
+ * @returns void
211
+ */
212
+ delete(filter: Partial<T>): Promise<void>;
213
+ /**
214
+ * Find a single document matching the filter
215
+ *
216
+ * @param filter - Equality filter conditions
217
+ * @returns First matching document or null if not found
218
+ */
219
+ findOne(filter: Partial<T>): Promise<T | null>;
220
+ /**
221
+ * Find multiple documents with optional filtering, sorting, and pagination
222
+ *
223
+ * @param options - Query options (where, orderBy, limit, offset)
224
+ * @returns Array of matching documents
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * // Get all
229
+ * const all = await collection.findMany()
230
+ *
231
+ * // With filter
232
+ * const admins = await collection.findMany({
233
+ * where: { role: 'admin' }
234
+ * })
235
+ *
236
+ * // With sorting and pagination
237
+ * const page = await collection.findMany({
238
+ * where: { status: 'active' },
239
+ * orderBy: { createdAt: 'desc' },
240
+ * limit: 20,
241
+ * offset: 0
242
+ * })
243
+ * ```
244
+ */
245
+ findMany(options?: FindManyOptions<T>): Promise<T[]>;
246
+ /**
247
+ * Subscribe to collection changes
248
+ *
249
+ * @param callback - Called whenever data changes with current full collection state
250
+ * @returns Unsubscribe function to remove listener
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * const unsubscribe = collection.subscribe((data) => {
255
+ * console.log('Collection now contains:', data)
256
+ * })
257
+ *
258
+ * // Later: stop listening
259
+ * unsubscribe()
260
+ * ```
261
+ */
262
+ subscribe(callback: (data: T[]) => void): () => void;
263
+ /** Internal: notify all subscribers of changes */
264
+ _notify(): void;
265
+ }
266
+ /**
267
+ * Sync adapter interface for remote synchronization
268
+ *
269
+ * @remarks
270
+ * Implement this interface to add custom sync behavior (WebSockets, server polling, etc.)
271
+ * The database automatically calls these methods when mutations occur (if optimistic mode enabled)
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * const syncAdapter: SyncAdapter = {
276
+ * async push(changes) {
277
+ * // Send to server
278
+ * await fetch('/api/sync', { method: 'POST', body: JSON.stringify(changes) })
279
+ * },
280
+ * async pull() {
281
+ * // Get from server
282
+ * const res = await fetch('/api/sync')
283
+ * return res.json()
284
+ * },
285
+ * subscribe(callback) {
286
+ * // Listen for remote changes
287
+ * const ws = new WebSocket('wss://...')
288
+ * ws.onmessage = (e) => callback(e.data)
289
+ * return () => ws.close()
290
+ * }
291
+ * }
292
+ * ```
293
+ */
294
+ interface SyncAdapter {
295
+ /**
296
+ * Push local changes to remote
297
+ *
298
+ * @param changes - Array of change objects to send to remote
299
+ * @throws Error if push fails - mutation will be rolled back if optimistic
300
+ */
301
+ push(changes: unknown[]): Promise<void>;
302
+ /**
303
+ * Pull remote changes
304
+ *
305
+ * @returns Array of changes from remote
306
+ */
307
+ pull(): Promise<unknown[]>;
308
+ /**
309
+ * Subscribe to remote changes
310
+ *
311
+ * @param callback - Called with remote changes
312
+ * @returns Unsubscribe function
313
+ */
314
+ subscribe(callback: (changes: unknown[]) => void): () => void;
315
+ }
316
+ /**
317
+ * Database configuration for creating a DB instance
318
+ *
319
+ * @example
320
+ * ```typescript
321
+ * const config: DBConfig = {
322
+ * collections: [usersCollection, todosCollection],
323
+ * sync: customSyncAdapter
324
+ * }
325
+ * ```
326
+ */
327
+ interface DBConfig {
328
+ /** Collections to register in the database */
329
+ collections?: Collection<any>[];
330
+ /** Optional sync adapter for remote synchronization */
331
+ sync?: SyncAdapter;
332
+ }
333
+ /**
334
+ * Database instance - main entry point for accessing collections and syncing
335
+ *
336
+ * @remarks
337
+ * - Collections are accessed by name via `db.collections[name]`
338
+ * - Provides centralized management of all collections
339
+ * - Optional sync adapter for remote data synchronization
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const db = createDB({
344
+ * collections: [usersCollection, todosCollection],
345
+ * sync: syncAdapter
346
+ * })
347
+ *
348
+ * // Access collections
349
+ * const users = await db.collections.users.findMany()
350
+ *
351
+ * // Clear all data
352
+ * await db.clear()
353
+ *
354
+ * // Close resources
355
+ * db.close()
356
+ * ```
357
+ */
358
+ interface DB {
359
+ /** Registered collections by name - access with `db.collections[collectionName]` */
360
+ collections: Record<string, Collection<any>>;
361
+ /** Optional sync adapter if configured */
362
+ sync?: SyncAdapter;
363
+ /**
364
+ * Close the database connection and clean up resources
365
+ */
366
+ close(): void;
367
+ /**
368
+ * Clear all data from all collections
369
+ *
370
+ * @returns Promise that resolves when all data is cleared
371
+ */
372
+ clear(): Promise<void>;
373
+ }
374
+ /**
375
+ * Options for collection.findMany() - internal collection query
376
+ *
377
+ * @template T - The document type
378
+ *
379
+ * @remarks
380
+ * Unlike `QueryOptions`, this doesn't include `from` since it's called on a collection directly
381
+ *
382
+ * @example
383
+ * ```typescript
384
+ * const options: FindManyOptions<User> = {
385
+ * where: { role: 'admin' },
386
+ * orderBy: { name: 'asc' },
387
+ * limit: 10,
388
+ * offset: 0
389
+ * }
390
+ * const users = await collection.findMany(options)
391
+ * ```
392
+ */
393
+ interface FindManyOptions<T> {
394
+ /** Filter conditions using WhereClause syntax */
395
+ where?: WhereClause<T>;
396
+ /** Sort order - single field or array of fields with directions */
397
+ orderBy?: OrderByClause<T> | OrderByClause<T>[];
398
+ /** Maximum number of results to return */
399
+ limit?: number;
400
+ /** Number of results to skip (for pagination) */
401
+ offset?: number;
402
+ }
403
+ /**
404
+ * Options for useQuery hook - React hook query interface
405
+ *
406
+ * @template T - The document type being queried
407
+ *
408
+ * @remarks
409
+ * Extends `FindManyOptions` with `from` to specify which collection to query.
410
+ * Called within a `DBProvider` context.
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const { data, isLoading, error } = useQuery<User>({
415
+ * from: 'users',
416
+ * where: { role: 'admin', age: { $gte: 18 } },
417
+ * orderBy: { name: 'asc' },
418
+ * limit: 20
419
+ * })
420
+ * ```
421
+ */
422
+ interface QueryOptions<T> extends FindManyOptions<T> {
423
+ /** Collection name to query from */
424
+ from: string;
425
+ }
426
+ /**
427
+ * Result of useQuery hook - reactive query state and refetch control
428
+ *
429
+ * @template T - The document type
430
+ *
431
+ * @remarks
432
+ * - `data` starts as undefined while loading
433
+ * - `isLoading` is true until first query completes
434
+ * - Automatically updates when collection changes (reactive)
435
+ * - Subscribe callbacks automatically re-apply filters and sorting
436
+ *
437
+ * @example
438
+ * ```typescript
439
+ * const { data, isLoading, error, refetch } = useQuery<User>({
440
+ * from: 'users'
441
+ * })
442
+ *
443
+ * if (isLoading) return <Spinner />
444
+ * if (error) return <Error message={error.message} />
445
+ *
446
+ * return (
447
+ * <div>
448
+ * {data?.map(user => (
449
+ * <UserCard key={user.id} user={user} />
450
+ * ))}
451
+ * <button onClick={refetch}>Refresh</button>
452
+ * </div>
453
+ * )
454
+ * ```
455
+ */
456
+ interface QueryResult<T> {
457
+ /** Query results - undefined while loading, array when loaded */
458
+ data: T[] | undefined;
459
+ /** True while initial query is executing */
460
+ isLoading: boolean;
461
+ /** Error object if query failed, undefined if successful */
462
+ error: Error | undefined;
463
+ /** Function to manually refetch the query */
464
+ refetch: () => void;
465
+ }
466
+ /**
467
+ * Type of mutation operation
468
+ *
469
+ * @example
470
+ * ```typescript
471
+ * type Op = MutationOperation
472
+ * const operation: Op = 'insert'
473
+ * ```
474
+ */
475
+ type MutationOperation = 'insert' | 'update' | 'delete';
476
+ /**
477
+ * Options for useMutation hook
478
+ *
479
+ * @remarks
480
+ * - `insert`: Creates new document
481
+ * - `update`: Updates existing documents matching filter
482
+ * - `delete`: Removes documents matching filter
483
+ * - `optimistic`: If true, updates UI immediately before server confirmation
484
+ * (on error, automatically rolls back)
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * const { mutate, isPending, error } = useMutation({
489
+ * collection: 'users',
490
+ * operation: 'insert',
491
+ * optimistic: true
492
+ * })
493
+ * ```
494
+ */
495
+ interface MutationOptions {
496
+ /** Collection name to mutate */
497
+ collection: string;
498
+ /** Type of operation: insert, update, or delete */
499
+ operation: MutationOperation;
500
+ /** Enable optimistic updates (show change immediately, rollback on error) */
501
+ optimistic?: boolean;
502
+ }
503
+ /**
504
+ * Data format for update mutations
505
+ *
506
+ * @template T - The document type
507
+ *
508
+ * @example
509
+ * ```typescript
510
+ * const updateData: UpdateMutationData<User> = {
511
+ * where: { id: '1' },
512
+ * data: { name: 'Updated Name' }
513
+ * }
514
+ * ```
515
+ */
516
+ interface UpdateMutationData<T> {
517
+ /** Filter to select which documents to update */
518
+ where: Partial<T>;
519
+ /** Partial updates to apply to matching documents */
520
+ data: Partial<T>;
521
+ }
522
+ /**
523
+ * Data format for delete mutations
524
+ *
525
+ * @template T - The document type (generic for flexibility)
526
+ *
527
+ * @example
528
+ * ```typescript
529
+ * const deleteData: DeleteMutationData<User> = {
530
+ * id: 'user-123'
531
+ * }
532
+ * ```
533
+ */
534
+ interface DeleteMutationData<T> {
535
+ /** ID of document to delete */
536
+ id: string;
537
+ }
538
+ /**
539
+ * Result of useMutation hook - mutation execution and state control
540
+ *
541
+ * @template T - The document type
542
+ *
543
+ * @remarks
544
+ * - Call `mutate()` with data to execute the operation
545
+ * - `isPending` is true while mutation is executing
546
+ * - On error, `error` contains the Error object
547
+ * - Use `reset()` to clear error state after handling
548
+ * - For optimistic updates, local UI updates immediately
549
+ * (automatic rollback if sync fails)
550
+ *
551
+ * @example
552
+ * ```typescript
553
+ * const { mutate, isPending, error, reset } = useMutation<User>({
554
+ * collection: 'users',
555
+ * operation: 'insert'
556
+ * })
557
+ *
558
+ * const handleCreate = async () => {
559
+ * try {
560
+ * await mutate({
561
+ * id: '2',
562
+ * name: 'Bob',
563
+ * email: 'bob@example.com',
564
+ * role: 'user'
565
+ * })
566
+ * } catch (err) {
567
+ * console.error('Failed:', err)
568
+ * }
569
+ * }
570
+ *
571
+ * return (
572
+ * <form onSubmit={handleCreate}>
573
+ * <button disabled={isPending}>
574
+ * {isPending ? 'Creating...' : 'Create'}
575
+ * </button>
576
+ * {error && <Error message={error.message} onDismiss={reset} />}
577
+ * </form>
578
+ * )
579
+ * ```
580
+ */
581
+ interface MutationResult<T> {
582
+ /**
583
+ * Execute the mutation with data
584
+ * Data format depends on operation: T for insert, UpdateMutationData<T> for update, DeleteMutationData<T> for delete
585
+ */
586
+ mutate: (data: T | UpdateMutationData<T> | DeleteMutationData<T>) => Promise<void>;
587
+ /** True while mutation is being executed */
588
+ isPending: boolean;
589
+ /** Error object if mutation failed, undefined if successful */
590
+ error: Error | undefined;
591
+ /** Reset mutation state (clears error and pending flags) */
592
+ reset: () => void;
593
+ }
594
+
595
+ /**
596
+ * @mdxui/terminal Database Implementation
597
+ *
598
+ * In-memory database with collection management, sync adapter support,
599
+ * and centralized data access for React applications.
600
+ */
601
+
602
+ /**
603
+ * Create a database instance with collections and optional sync adapter
604
+ *
605
+ * @param config - Database configuration with collections and sync adapter
606
+ * @returns A fully typed database instance for accessing collections
607
+ *
608
+ * @remarks
609
+ * - Collections are accessed via `db.collections[name]`
610
+ * - All data is stored in-memory (cleared on process exit)
611
+ * - Optional sync adapter can push/pull changes to a remote backend
612
+ * - Use within `DBProvider` for React applications
613
+ * - Thread-safe for concurrent operations
614
+ *
615
+ * @example
616
+ * ```typescript
617
+ * import { z } from 'zod'
618
+ * import { createDB, createCollection } from '@mdxui/terminal'
619
+ *
620
+ * // Define schemas
621
+ * const UserSchema = z.object({
622
+ * id: z.string(),
623
+ * name: z.string(),
624
+ * email: z.string().email(),
625
+ * role: z.enum(['admin', 'user', 'guest'])
626
+ * })
627
+ *
628
+ * // Create collections
629
+ * const usersCollection = createCollection({
630
+ * name: 'users',
631
+ * schema: UserSchema,
632
+ * primaryKey: 'id'
633
+ * })
634
+ *
635
+ * // Create database with collections
636
+ * const db = createDB({
637
+ * collections: [usersCollection],
638
+ * sync: customSyncAdapter // optional
639
+ * })
640
+ *
641
+ * // Access collections
642
+ * const user = await db.collections.users.insert({
643
+ * id: '1',
644
+ * name: 'Alice',
645
+ * email: 'alice@example.com',
646
+ * role: 'admin'
647
+ * })
648
+ *
649
+ * const all = await db.collections.users.findMany()
650
+ * const admins = await db.collections.users.findMany({
651
+ * where: { role: 'admin' }
652
+ * })
653
+ *
654
+ * // Clean up
655
+ * await db.clear()
656
+ * db.close()
657
+ * ```
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * // With sync adapter for remote sync
662
+ * const syncAdapter = {
663
+ * async push(changes) {
664
+ * await fetch('/api/sync', {
665
+ * method: 'POST',
666
+ * body: JSON.stringify(changes)
667
+ * })
668
+ * },
669
+ * async pull() {
670
+ * const res = await fetch('/api/sync')
671
+ * return res.json()
672
+ * },
673
+ * subscribe(callback) {
674
+ * const ws = new WebSocket('wss://...')
675
+ * ws.onmessage = (e) => callback(e.data)
676
+ * return () => ws.close()
677
+ * }
678
+ * }
679
+ *
680
+ * const db = createDB({
681
+ * collections: [usersCollection],
682
+ * sync: syncAdapter
683
+ * })
684
+ * ```
685
+ */
686
+ declare function createDB(config?: DBConfig): DB;
687
+
688
+ /**
689
+ * @mdxui/terminal Collection Implementation
690
+ *
691
+ * In-memory collection with Zod validation, reactive subscriptions, filtering,
692
+ * sorting, and pagination support. Provides full CRUD operations with type safety.
693
+ */
694
+
695
+ /**
696
+ * Configuration for creating a collection
697
+ *
698
+ * @template T - The document type stored in this collection
699
+ *
700
+ * @example
701
+ * ```typescript
702
+ * const config: CreateCollectionConfig<User> = {
703
+ * name: 'users',
704
+ * schema: UserSchema,
705
+ * primaryKey: 'id',
706
+ * indexes: ['email', 'role']
707
+ * }
708
+ * ```
709
+ */
710
+ interface CreateCollectionConfig<T> {
711
+ /** Collection name - used to reference in queries and mutations */
712
+ name: string;
713
+ /** Zod schema for automatic validation on all insert/update operations */
714
+ schema: ZodSchema<T>;
715
+ /** Primary key field (defaults to 'id'). Used for duplicate detection */
716
+ primaryKey?: string;
717
+ /** Fields to index for faster queries (metadata only for future optimization) */
718
+ indexes?: string[];
719
+ }
720
+ /**
721
+ * Create a typed in-memory collection with Zod validation
722
+ *
723
+ * @template T - The document type (must be a Record for proper typing)
724
+ *
725
+ * @param config - Collection configuration (name, schema, primaryKey, indexes)
726
+ * @returns A fully typed collection instance with CRUD operations and subscriptions
727
+ *
728
+ * @remarks
729
+ * - All documents are validated against the provided Zod schema on insert/update
730
+ * - Primary key defaults to 'id' if not specified
731
+ * - Provides reactive subscriptions for real-time updates
732
+ * - Supports filtering with where clauses and comparison operators
733
+ * - Supports sorting with orderBy and multiple sort fields
734
+ * - Supports pagination with limit and offset
735
+ * - Thread-safe for concurrent operations (in-memory only)
736
+ *
737
+ * @example
738
+ * ```typescript
739
+ * import { z } from 'zod'
740
+ * import { createCollection } from '@mdxui/terminal'
741
+ *
742
+ * // Define schema
743
+ * const UserSchema = z.object({
744
+ * id: z.string(),
745
+ * name: z.string(),
746
+ * email: z.string().email(),
747
+ * age: z.number().optional(),
748
+ * role: z.enum(['admin', 'user', 'guest'])
749
+ * })
750
+ *
751
+ * type User = z.infer<typeof UserSchema>
752
+ *
753
+ * // Create collection
754
+ * const users = createCollection<User>({
755
+ * name: 'users',
756
+ * schema: UserSchema,
757
+ * primaryKey: 'id',
758
+ * indexes: ['email', 'role']
759
+ * })
760
+ *
761
+ * // CRUD Operations
762
+ * const user = await users.insert({
763
+ * id: '1',
764
+ * name: 'Alice',
765
+ * email: 'alice@example.com',
766
+ * role: 'admin'
767
+ * })
768
+ *
769
+ * const updated = await users.update(
770
+ * { id: '1' },
771
+ * { name: 'Alicia' }
772
+ * )
773
+ *
774
+ * const found = await users.findOne({ id: '1' })
775
+ *
776
+ * const admins = await users.findMany({
777
+ * where: { role: 'admin' },
778
+ * orderBy: { name: 'asc' }
779
+ * })
780
+ *
781
+ * await users.delete({ id: '1' })
782
+ *
783
+ * // Subscribe to changes
784
+ * const unsubscribe = users.subscribe((allUsers) => {
785
+ * console.log('Users updated:', allUsers)
786
+ * })
787
+ * ```
788
+ */
789
+ declare function createCollection<T extends Record<string, any>>(config: CreateCollectionConfig<T>): Collection<T>;
790
+
791
+ /**
792
+ * @mdxui/terminal DO Sync Adapter
793
+ *
794
+ * Durable Objects sync adapter for bidirectional data synchronization
795
+ * via WebSocket connection. Provides:
796
+ * - WebSocket connection lifecycle management
797
+ * - Bidirectional data synchronization
798
+ * - Auth header injection for authenticated requests
799
+ * - Optimistic updates with server confirmation
800
+ * - Automatic reconnection with exponential backoff + jitter
801
+ * - Offline mutation queue for resilience
802
+ * - Connection state observable
803
+ * - Error categorization (recoverable vs fatal)
804
+ *
805
+ * @remarks
806
+ * ## Connection State Machine
807
+ *
808
+ * ```
809
+ * ┌─────────────┐ connect() ┌────────────┐
810
+ * │ disconnected│──────────────►│ connecting │
811
+ * └─────────────┘ └────────────┘
812
+ * ▲ │
813
+ * │ │ onopen
814
+ * │ close() ▼
815
+ * │ ┌───────────┐
816
+ * │◄──────────────────────│ connected │
817
+ * │ close() / fatal err └───────────┘
818
+ * │ │
819
+ * │ │ recoverable error / close
820
+ * │ ▼
821
+ * │ ┌─────────────┐
822
+ * │◄─────────────────────│ reconnecting│───► (loop with backoff)
823
+ * │ max attempts └─────────────┘
824
+ * ```
825
+ *
826
+ * ## Error Categories
827
+ *
828
+ * **Recoverable errors** - trigger reconnection:
829
+ * - Network timeouts
830
+ * - Temporary server unavailability
831
+ * - WebSocket close codes 1001 (going away), 1006 (abnormal closure)
832
+ *
833
+ * **Fatal errors** - require user intervention:
834
+ * - Authentication failures (401, 403)
835
+ * - Invalid namespace URL
836
+ * - WebSocket close code 1008 (policy violation)
837
+ * - Close code 4000+ (application-level errors)
838
+ *
839
+ * @module
840
+ */
841
+
842
+ /**
843
+ * Connection state for monitoring adapter health.
844
+ *
845
+ * State transitions follow a deterministic state machine pattern:
846
+ *
847
+ * @remarks
848
+ * - `disconnected`: No active WebSocket connection. Initial state and terminal state.
849
+ * - `connecting`: WebSocket connection in progress. Transitions to `connected` on success,
850
+ * `disconnected` on fatal error, or `reconnecting` on recoverable error (if enabled).
851
+ * - `connected`: Active WebSocket connection ready for sync. Can transition to
852
+ * `disconnected` on close/fatal error or `reconnecting` on recoverable error.
853
+ * - `reconnecting`: Attempting to re-establish connection after a recoverable failure.
854
+ * Includes exponential backoff with jitter. Transitions to `connecting` when attempting,
855
+ * `disconnected` when max attempts reached or user calls close().
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * const sync = createDOSync({ namespaceUrl: '...' })
860
+ *
861
+ * sync.onConnectionStateChange((state) => {
862
+ * switch (state) {
863
+ * case 'disconnected':
864
+ * showOfflineIndicator()
865
+ * break
866
+ * case 'connecting':
867
+ * case 'reconnecting':
868
+ * showConnectingSpinner()
869
+ * break
870
+ * case 'connected':
871
+ * hideOfflineIndicator()
872
+ * break
873
+ * }
874
+ * })
875
+ * ```
876
+ */
877
+ type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
878
+ /**
879
+ * Queued mutation for offline resilience.
880
+ *
881
+ * @remarks
882
+ * When the adapter is offline, mutations are queued and automatically
883
+ * retried once the connection is re-established. This ensures no data
884
+ * is lost during temporary disconnections.
885
+ *
886
+ * ## Lifecycle
887
+ * 1. Push fails due to connection error
888
+ * 2. Mutation is added to queue with timestamp
889
+ * 3. Connection is restored
890
+ * 4. Queue is flushed in FIFO order
891
+ * 5. Successful mutations are removed from queue
892
+ * 6. Failed mutations remain with incremented retryCount
893
+ *
894
+ * ## Inspection
895
+ * Use `getQueuedMutations()` to inspect the queue for debugging
896
+ * or displaying pending sync status to users.
897
+ *
898
+ * @example
899
+ * ```typescript
900
+ * // Display pending changes to user
901
+ * const pending = adapter.getQueuedMutations()
902
+ * if (pending.length > 0) {
903
+ * console.log(`${pending.length} changes waiting to sync`)
904
+ * }
905
+ * ```
906
+ */
907
+ interface QueuedMutation {
908
+ /** Unique identifier for this mutation (auto-generated) */
909
+ id: string;
910
+ /** The changes to sync to the server */
911
+ changes: unknown[];
912
+ /** Timestamp (ms since epoch) when mutation was queued */
913
+ queuedAt: number;
914
+ /** Number of failed retry attempts (0 = first attempt pending) */
915
+ retryCount: number;
916
+ }
917
+ /**
918
+ * Reconnection configuration options.
919
+ *
920
+ * @remarks
921
+ * Configures automatic reconnection behavior with exponential backoff.
922
+ * When enabled, the adapter will automatically attempt to reconnect
923
+ * on connection loss until maxAttempts is reached.
924
+ *
925
+ * ## Defaults
926
+ * - `enabled`: false (opt-in for auto-reconnect)
927
+ * - `maxAttempts`: Infinity (keep trying forever)
928
+ * - `initialDelay`: 1000ms (1 second)
929
+ * - `maxDelay`: 30000ms (30 seconds cap)
930
+ *
931
+ * ## Backoff Formula
932
+ * `delay = min(initialDelay * 2^attempt, maxDelay)`
933
+ *
934
+ * @example
935
+ * ```typescript
936
+ * // Recommended production config
937
+ * const sync = createDOSync({
938
+ * namespaceUrl: '...',
939
+ * reconnect: {
940
+ * enabled: true,
941
+ * maxAttempts: 10,
942
+ * initialDelay: 1000,
943
+ * maxDelay: 30000
944
+ * }
945
+ * })
946
+ * ```
947
+ */
948
+ interface ReconnectOptions {
949
+ /**
950
+ * Whether to automatically reconnect on connection loss.
951
+ * @defaultValue false
952
+ */
953
+ enabled?: boolean;
954
+ /**
955
+ * Maximum number of reconnection attempts before giving up.
956
+ * Set to Infinity to retry indefinitely.
957
+ * @defaultValue Infinity
958
+ */
959
+ maxAttempts?: number;
960
+ /**
961
+ * Initial delay in ms before first reconnection attempt.
962
+ * Subsequent delays are calculated with exponential backoff.
963
+ * @defaultValue 1000
964
+ */
965
+ initialDelay?: number;
966
+ /**
967
+ * Maximum delay in ms between reconnection attempts (backoff cap).
968
+ * @defaultValue 30000
969
+ */
970
+ maxDelay?: number;
971
+ }
972
+ /**
973
+ * Conflict resolution strategy for handling server-client data conflicts.
974
+ *
975
+ * @remarks
976
+ * - `server-wins`: Server version is authoritative, client changes discarded
977
+ * - `client-wins`: Client version is authoritative, server changes overwritten
978
+ * - `merge`: Attempt to merge both versions (server determines merge logic)
979
+ * - `throw`: Reject push with conflict error, let caller handle
980
+ * - `custom`: Call `onConflict` callback for custom resolution logic
981
+ */
982
+ type ConflictResolution = 'server-wins' | 'client-wins' | 'merge' | 'throw' | 'custom';
983
+ /**
984
+ * Conflict details returned by server when client/server versions diverge.
985
+ */
986
+ interface Conflict {
987
+ /** ID of the conflicting entity */
988
+ id: string;
989
+ /** Server's current version of the entity */
990
+ serverVersion: Record<string, unknown>;
991
+ }
992
+ /**
993
+ * Configuration for creating a DO Sync adapter.
994
+ *
995
+ * @remarks
996
+ * ## Minimal Configuration
997
+ * ```typescript
998
+ * const sync = createDOSync({
999
+ * namespaceUrl: 'https://api.example.com/namespace'
1000
+ * })
1001
+ * ```
1002
+ *
1003
+ * ## Full Configuration
1004
+ * ```typescript
1005
+ * const sync = createDOSync({
1006
+ * namespaceUrl: 'https://api.example.com/namespace',
1007
+ * authToken: 'jwt-token',
1008
+ * reconnect: { enabled: true, maxAttempts: 10 },
1009
+ * conflictResolution: 'server-wins',
1010
+ * requestTimeout: 10000
1011
+ * })
1012
+ * ```
1013
+ */
1014
+ interface DOSyncConfig {
1015
+ /**
1016
+ * URL of the Durable Objects namespace endpoint.
1017
+ * Will be converted to WebSocket URL (https -> wss, http -> ws).
1018
+ *
1019
+ * @example 'https://api.example.com/namespace'
1020
+ */
1021
+ namespaceUrl: string;
1022
+ /**
1023
+ * Optional auth token for authenticated connections.
1024
+ * Sent as URL query param and in message payloads.
1025
+ * Can be updated dynamically via `setAuthToken()`.
1026
+ */
1027
+ authToken?: string;
1028
+ /**
1029
+ * Automatic reconnection options.
1030
+ * @see ReconnectOptions for defaults and configuration
1031
+ */
1032
+ reconnect?: ReconnectOptions;
1033
+ /**
1034
+ * Strategy for resolving server-client data conflicts.
1035
+ * @defaultValue 'server-wins' (implicit - server decides)
1036
+ */
1037
+ conflictResolution?: ConflictResolution;
1038
+ /**
1039
+ * Custom conflict resolver callback.
1040
+ * Required when `conflictResolution` is 'custom'.
1041
+ *
1042
+ * @param conflicts - Array of conflicting entities with server versions
1043
+ * @returns Promise resolving to `{ resolved: true }` when conflicts handled
1044
+ */
1045
+ onConflict?: (conflicts: Conflict[]) => Promise<{
1046
+ resolved: boolean;
1047
+ }>;
1048
+ /**
1049
+ * Request timeout in milliseconds for push/pull operations.
1050
+ * Operations will reject with timeout error if no response received.
1051
+ * @defaultValue 30000 (30 seconds)
1052
+ */
1053
+ requestTimeout?: number;
1054
+ }
1055
+ /**
1056
+ * Connection state observer callback type.
1057
+ *
1058
+ * @remarks
1059
+ * Called whenever the connection state changes. Useful for UI feedback
1060
+ * (e.g., showing "offline" status, disabling sync buttons, etc.).
1061
+ *
1062
+ * @param state - The new connection state
1063
+ */
1064
+ type ConnectionStateObserver = (state: ConnectionState) => void;
1065
+ /**
1066
+ * Extended sync adapter with connection management and state monitoring.
1067
+ *
1068
+ * @remarks
1069
+ * Extends the base SyncAdapter with:
1070
+ * - Connection lifecycle management (`close()`)
1071
+ * - Dynamic auth token updates (`setAuthToken()`)
1072
+ * - Reactive connection state (`onConnectionStateChange()`, `getConnectionState()`)
1073
+ * - Offline queue inspection (`getQueuedMutations()`, `getQueueStats()`)
1074
+ *
1075
+ * ## Offline Resilience
1076
+ * When push operations fail due to connection errors, mutations are
1077
+ * automatically queued and retried when the connection is restored.
1078
+ * This ensures no data is lost during temporary disconnections.
1079
+ *
1080
+ * @example
1081
+ * ```typescript
1082
+ * const sync = createDOSync({ namespaceUrl: '...' })
1083
+ *
1084
+ * // React to connection state changes
1085
+ * sync.onConnectionStateChange((state) => {
1086
+ * updateStatusIndicator(state)
1087
+ * })
1088
+ *
1089
+ * // Check pending changes
1090
+ * const { count, oldestAt } = sync.getQueueStats()
1091
+ * if (count > 0) {
1092
+ * showPendingBanner(`${count} changes pending since ${new Date(oldestAt!)}`)
1093
+ * }
1094
+ *
1095
+ * // Cleanup on unmount
1096
+ * sync.close()
1097
+ * ```
1098
+ */
1099
+ interface DOSyncAdapter extends SyncAdapter {
1100
+ /**
1101
+ * Close the WebSocket connection and stop all reconnection attempts.
1102
+ * Call this when unmounting or navigating away to clean up resources.
1103
+ */
1104
+ close(): void;
1105
+ /**
1106
+ * Update the auth token dynamically.
1107
+ * Useful for refreshing expired tokens without recreating the adapter.
1108
+ * The new token will be used for subsequent connections.
1109
+ *
1110
+ * @param token - New auth token
1111
+ */
1112
+ setAuthToken(token: string): void;
1113
+ /**
1114
+ * Subscribe to connection state changes.
1115
+ * Callback is called immediately with current state, then on each change.
1116
+ *
1117
+ * @param callback - Observer function called on state changes
1118
+ * @returns Unsubscribe function
1119
+ */
1120
+ onConnectionStateChange(callback: ConnectionStateObserver): () => void;
1121
+ /**
1122
+ * Get current connection state without subscribing.
1123
+ * Use for one-time checks; use `onConnectionStateChange()` for reactive updates.
1124
+ *
1125
+ * @returns Current connection state
1126
+ */
1127
+ getConnectionState(): ConnectionState;
1128
+ /**
1129
+ * Get all mutations currently in the offline queue.
1130
+ * Useful for debugging or displaying pending sync status.
1131
+ *
1132
+ * @returns Array of queued mutations
1133
+ */
1134
+ getQueuedMutations(): QueuedMutation[];
1135
+ /**
1136
+ * Get summary statistics about the offline queue.
1137
+ *
1138
+ * @returns Object with:
1139
+ * - `count`: Number of pending mutations
1140
+ * - `oldestAt`: Timestamp of oldest mutation (null if empty)
1141
+ */
1142
+ getQueueStats(): {
1143
+ count: number;
1144
+ oldestAt: number | null;
1145
+ };
1146
+ }
1147
+ /**
1148
+ * Create a Durable Objects sync adapter
1149
+ *
1150
+ * @param config - Configuration options
1151
+ * @returns A sync adapter instance for use with createDB
1152
+ *
1153
+ * @throws Error if namespaceUrl is empty or invalid
1154
+ *
1155
+ * @example
1156
+ * ```typescript
1157
+ * import { createDOSync } from '@mdxui/terminal'
1158
+ *
1159
+ * const sync = createDOSync({
1160
+ * namespaceUrl: 'https://api.example.com/namespace',
1161
+ * authToken: 'your-auth-token',
1162
+ * reconnect: { enabled: true, maxAttempts: 5 }
1163
+ * })
1164
+ *
1165
+ * const db = createDB({
1166
+ * collections: [usersCollection],
1167
+ * sync
1168
+ * })
1169
+ * ```
1170
+ */
1171
+ declare function createDOSync(config: DOSyncConfig): DOSyncAdapter;
1172
+
1173
+ /**
1174
+ * @mdxui/terminal Database Context
1175
+ *
1176
+ * React Context API provider for database access throughout component tree.
1177
+ * Enables hooks like `useQuery` and `useMutation` to access the database
1178
+ * without prop drilling.
1179
+ */
1180
+
1181
+ /**
1182
+ * Props for DBProvider component
1183
+ *
1184
+ * @example
1185
+ * ```typescript
1186
+ * const props: DBProviderProps = {
1187
+ * db: myDatabase,
1188
+ * children: <App />
1189
+ * }
1190
+ * ```
1191
+ */
1192
+ interface DBProviderProps {
1193
+ /** Database instance to provide to all children */
1194
+ db: DB;
1195
+ /** React components that will have access to the database */
1196
+ children: ReactNode;
1197
+ }
1198
+ /**
1199
+ * Database provider component - wraps your app to provide database context
1200
+ *
1201
+ * Provides database access to all child components via React Context.
1202
+ * Must wrap any component using `useQuery` or `useMutation` hooks.
1203
+ *
1204
+ * @remarks
1205
+ * - Use at the top level of your app (e.g., around `<App />`)
1206
+ * - Can have multiple DBProviders with different database instances
1207
+ * - All useQuery and useMutation hooks must be within a DBProvider
1208
+ * - Throws error if hooks are used outside DBProvider
1209
+ *
1210
+ * @example
1211
+ * ```tsx
1212
+ * import { z } from 'zod'
1213
+ * import { createDB, createCollection, DBProvider } from '@mdxui/terminal'
1214
+ *
1215
+ * // Create database
1216
+ * const db = createDB({
1217
+ * collections: [usersCollection, todosCollection]
1218
+ * })
1219
+ *
1220
+ * // Wrap app with provider
1221
+ * export function App() {
1222
+ * return (
1223
+ * <DBProvider db={db}>
1224
+ * <UserList />
1225
+ * <TodoForm />
1226
+ * </DBProvider>
1227
+ * )
1228
+ * }
1229
+ *
1230
+ * // Now these hooks work:
1231
+ * function UserList() {
1232
+ * const { data, isLoading } = useQuery({
1233
+ * from: 'users',
1234
+ * where: { role: 'admin' }
1235
+ * })
1236
+ *
1237
+ * if (isLoading) return <div>Loading...</div>
1238
+ * return (
1239
+ * <ul>
1240
+ * {data?.map(user => (
1241
+ * <li key={user.id}>{user.name}</li>
1242
+ * ))}
1243
+ * </ul>
1244
+ * )
1245
+ * }
1246
+ *
1247
+ * function TodoForm() {
1248
+ * const { mutate, isPending } = useMutation({
1249
+ * collection: 'todos',
1250
+ * operation: 'insert'
1251
+ * })
1252
+ *
1253
+ * return (
1254
+ * <form onSubmit={(e) => {
1255
+ * e.preventDefault()
1256
+ * mutate({ id: '1', title: 'New', completed: false })
1257
+ * }}>
1258
+ * <button disabled={isPending}>Add Todo</button>
1259
+ * </form>
1260
+ * )
1261
+ * }
1262
+ * ```
1263
+ */
1264
+ declare function DBProvider({ db, children }: DBProviderProps): React.ReactElement;
1265
+ /**
1266
+ * Hook to access the database instance from context
1267
+ *
1268
+ * @returns The database instance from the nearest DBProvider
1269
+ * @throws Error if used outside a DBProvider component
1270
+ *
1271
+ * @remarks
1272
+ * - Must be called within a component tree wrapped by DBProvider
1273
+ * - Allows direct access to collections (advanced use case)
1274
+ * - Most apps use useQuery/useMutation instead
1275
+ * - Useful for manual collection operations outside hooks
1276
+ *
1277
+ * @example
1278
+ * ```tsx
1279
+ * // Direct database access (advanced)
1280
+ * function MyComponent() {
1281
+ * const db = useDBContext()
1282
+ *
1283
+ * // Manually query
1284
+ * const handleClick = async () => {
1285
+ * const admins = await db.collections.users.findMany({
1286
+ * where: { role: 'admin' }
1287
+ * })
1288
+ * console.log('Admins:', admins)
1289
+ * }
1290
+ *
1291
+ * return <button onClick={handleClick}>Get Admins</button>
1292
+ * }
1293
+ * ```
1294
+ *
1295
+ * @example
1296
+ * ```tsx
1297
+ * // Subscribe to collection changes (advanced)
1298
+ * function CollectionMonitor() {
1299
+ * const db = useDBContext()
1300
+ *
1301
+ * React.useEffect(() => {
1302
+ * const unsubscribe = db.collections.users.subscribe((users) => {
1303
+ * console.log('Users changed:', users)
1304
+ * })
1305
+ * return unsubscribe
1306
+ * }, [db])
1307
+ *
1308
+ * return <div>Monitoring changes...</div>
1309
+ * }
1310
+ * ```
1311
+ */
1312
+ declare function useDBContext(): DB;
1313
+
1314
+ /**
1315
+ * @mdxui/terminal Data Hooks
1316
+ *
1317
+ * React hooks for reactive queries and mutations with optimistic updates.
1318
+ * Provides type-safe hooks for querying and mutating database collections
1319
+ * within a DBProvider context.
1320
+ */
1321
+
1322
+ /**
1323
+ * React hook for reactive data queries with filtering, sorting, and pagination
1324
+ *
1325
+ * @template T - The document type being queried
1326
+ *
1327
+ * @param options - Query options (collection name, filters, sorting, pagination)
1328
+ * @returns Query result with reactive data, loading/error states, and refetch control
1329
+ *
1330
+ * @remarks
1331
+ * - Must be used within a DBProvider component
1332
+ * - Automatically fetches initial data on mount
1333
+ * - Reactively updates when collection changes (subscriptions)
1334
+ * - Filters, sorting, and pagination are re-applied when data changes
1335
+ * - `data` is undefined while loading, array when loaded
1336
+ * - `isLoading` is true for the initial fetch only
1337
+ * - Manual refetch available via `refetch()` function
1338
+ * - Error state persists until query succeeds
1339
+ *
1340
+ * @example
1341
+ * ```tsx
1342
+ * // Basic query - get all documents
1343
+ * function AllUsers() {
1344
+ * const { data, isLoading, error } = useQuery({
1345
+ * from: 'users'
1346
+ * })
1347
+ *
1348
+ * if (isLoading) return <div>Loading...</div>
1349
+ * if (error) return <div>Error: {error.message}</div>
1350
+ *
1351
+ * return (
1352
+ * <ul>
1353
+ * {data?.map(user => (
1354
+ * <li key={user.id}>{user.name}</li>
1355
+ * ))}
1356
+ * </ul>
1357
+ * )
1358
+ * }
1359
+ * ```
1360
+ *
1361
+ * @example
1362
+ * ```tsx
1363
+ * // With filtering
1364
+ * function AdminUsers() {
1365
+ * const { data } = useQuery({
1366
+ * from: 'users',
1367
+ * where: { role: 'admin' }
1368
+ * })
1369
+ *
1370
+ * return data?.map(user => <AdminCard key={user.id} user={user} />)
1371
+ * }
1372
+ * ```
1373
+ *
1374
+ * @example
1375
+ * ```tsx
1376
+ * // With sorting and pagination
1377
+ * function UsersPaginated() {
1378
+ * const { data, refetch } = useQuery({
1379
+ * from: 'users',
1380
+ * where: { status: 'active' },
1381
+ * orderBy: { createdAt: 'desc' },
1382
+ * limit: 20,
1383
+ * offset: 0
1384
+ * })
1385
+ *
1386
+ * return (
1387
+ * <div>
1388
+ * <Users data={data} />
1389
+ * <button onClick={refetch}>Refresh</button>
1390
+ * </div>
1391
+ * )
1392
+ * }
1393
+ * ```
1394
+ *
1395
+ * @example
1396
+ * ```tsx
1397
+ * // With comparison operators
1398
+ * function AdultUsers() {
1399
+ * const { data } = useQuery({
1400
+ * from: 'users',
1401
+ * where: { age: { $gte: 18 } }
1402
+ * })
1403
+ *
1404
+ * return data?.map(user => <Card key={user.id} user={user} />)
1405
+ * }
1406
+ * ```
1407
+ *
1408
+ * @example
1409
+ * ```tsx
1410
+ * // With OR conditions
1411
+ * function AdminsOrModerators() {
1412
+ * const { data } = useQuery({
1413
+ * from: 'users',
1414
+ * where: {
1415
+ * $or: [
1416
+ * { role: 'admin' },
1417
+ * { role: 'moderator' }
1418
+ * ]
1419
+ * }
1420
+ * })
1421
+ *
1422
+ * return data?.map(user => <Card key={user.id} user={user} />)
1423
+ * }
1424
+ * ```
1425
+ *
1426
+ * @example
1427
+ * ```tsx
1428
+ * // With multiple sort fields
1429
+ * function UsersSorted() {
1430
+ * const { data } = useQuery({
1431
+ * from: 'users',
1432
+ * orderBy: [
1433
+ * { role: 'asc' },
1434
+ * { name: 'asc' }
1435
+ * ]
1436
+ * })
1437
+ *
1438
+ * return data?.map(user => <Card key={user.id} user={user} />)
1439
+ * }
1440
+ * ```
1441
+ */
1442
+ declare function useQuery<T extends Record<string, any>>(options: QueryOptions<T>): QueryResult<T>;
1443
+ /**
1444
+ * React hook for data mutations (insert, update, delete) with optimistic updates
1445
+ *
1446
+ * @template T - The document type being mutated
1447
+ *
1448
+ * @param options - Mutation options (collection, operation, optimistic mode)
1449
+ * @returns Mutation result with mutate function, pending/error states, and reset
1450
+ *
1451
+ * @remarks
1452
+ * - Must be used within a DBProvider component
1453
+ * - Supports three operations: insert, update, delete
1454
+ * - Optimistic updates: UI updates immediately, rolls back on error
1455
+ * - Manual updates: UI updates only after server confirmation
1456
+ * - `isPending` is true while mutation is executing
1457
+ * - Error state persists until mutation succeeds or `reset()` is called
1458
+ * - Data format depends on operation type:
1459
+ * - `insert`: T (full document)
1460
+ * - `update`: UpdateMutationData<T> (where + data)
1461
+ * - `delete`: DeleteMutationData<T> (id)
1462
+ * - Sync adapter is called when optimistic=true and sync is configured
1463
+ *
1464
+ * @example
1465
+ * ```tsx
1466
+ * // Insert with optimistic update
1467
+ * function CreateUserForm() {
1468
+ * const { mutate, isPending, error, reset } = useMutation({
1469
+ * collection: 'users',
1470
+ * operation: 'insert',
1471
+ * optimistic: true
1472
+ * })
1473
+ *
1474
+ * const handleSubmit = async (formData) => {
1475
+ * try {
1476
+ * await mutate({
1477
+ * id: crypto.randomUUID(),
1478
+ * name: formData.name,
1479
+ * email: formData.email,
1480
+ * role: 'user'
1481
+ * })
1482
+ * console.log('User created!')
1483
+ * } catch (err) {
1484
+ * console.error('Failed to create user')
1485
+ * }
1486
+ * }
1487
+ *
1488
+ * return (
1489
+ * <form onSubmit={async (e) => {
1490
+ * e.preventDefault()
1491
+ * await handleSubmit(Object.fromEntries(new FormData(e.currentTarget)))
1492
+ * }}>
1493
+ * <input name="name" required />
1494
+ * <input name="email" type="email" required />
1495
+ * <button disabled={isPending}>
1496
+ * {isPending ? 'Creating...' : 'Create'}
1497
+ * </button>
1498
+ * {error && (
1499
+ * <div>
1500
+ * <p>Error: {error.message}</p>
1501
+ * <button onClick={reset}>Dismiss</button>
1502
+ * </div>
1503
+ * )}
1504
+ * </form>
1505
+ * )
1506
+ * }
1507
+ * ```
1508
+ *
1509
+ * @example
1510
+ * ```tsx
1511
+ * // Update mutation
1512
+ * function EditUserForm({ userId }) {
1513
+ * const { mutate, isPending } = useMutation({
1514
+ * collection: 'users',
1515
+ * operation: 'update'
1516
+ * })
1517
+ *
1518
+ * const handleSave = async (updates) => {
1519
+ * await mutate({
1520
+ * where: { id: userId },
1521
+ * data: updates
1522
+ * })
1523
+ * }
1524
+ *
1525
+ * return <Form onSave={handleSave} disabled={isPending} />
1526
+ * }
1527
+ * ```
1528
+ *
1529
+ * @example
1530
+ * ```tsx
1531
+ * // Delete mutation
1532
+ * function DeleteUserButton({ userId }) {
1533
+ * const { mutate, isPending } = useMutation({
1534
+ * collection: 'users',
1535
+ * operation: 'delete'
1536
+ * })
1537
+ *
1538
+ * const handleDelete = async () => {
1539
+ * if (confirm('Really delete?')) {
1540
+ * await mutate({ id: userId })
1541
+ * }
1542
+ * }
1543
+ *
1544
+ * return (
1545
+ * <button onClick={handleDelete} disabled={isPending}>
1546
+ * {isPending ? 'Deleting...' : 'Delete'}
1547
+ * </button>
1548
+ * )
1549
+ * }
1550
+ * ```
1551
+ *
1552
+ * @example
1553
+ * ```tsx
1554
+ * // Optimistic vs non-optimistic
1555
+ * function UserActions() {
1556
+ * // UI updates immediately, auto-rollback on error
1557
+ * const { mutate: optimisticInsert } = useMutation({
1558
+ * collection: 'users',
1559
+ * operation: 'insert',
1560
+ * optimistic: true // Default UI update
1561
+ * })
1562
+ *
1563
+ * // UI updates only after server confirms
1564
+ * const { mutate: carefullInsert } = useMutation({
1565
+ * collection: 'users',
1566
+ * operation: 'insert',
1567
+ * optimistic: false // Wait for server
1568
+ * })
1569
+ *
1570
+ * return (
1571
+ * <div>
1572
+ * <button onClick={() => optimisticInsert(newUser)}>
1573
+ * Quick Add (optimistic)
1574
+ * </button>
1575
+ * <button onClick={() => carefullInsert(newUser)}>
1576
+ * Safe Add (wait for server)
1577
+ * </button>
1578
+ * </div>
1579
+ * )
1580
+ * }
1581
+ * ```
1582
+ */
1583
+ declare function useMutation<T extends Record<string, any>>(options: MutationOptions): MutationResult<T>;
1584
+
1585
+ /**
1586
+ * @mdxui/terminal Reactive Data Hooks for Data Components
1587
+ *
1588
+ * This module provides React hooks for connecting data components (Table, List,
1589
+ * Card, Metrics) to TanStack DB collections with reactive updates and optimistic
1590
+ * mutations.
1591
+ *
1592
+ * Key features:
1593
+ * - Reactive data binding - UI updates automatically when collection data changes
1594
+ * - Optimistic updates - UI updates immediately, rolls back on error
1595
+ * - Type-safe queries - Full TypeScript support with Zod validation
1596
+ * - Live subscriptions - Real-time updates from collection changes
1597
+ *
1598
+ * @example
1599
+ * ```tsx
1600
+ * import { useReactiveTable, useReactiveList } from '@mdxui/terminal'
1601
+ *
1602
+ * function UsersTable() {
1603
+ * const { data, isLoading, mutate, sort, setSort } = useReactiveTable({
1604
+ * collection: 'users',
1605
+ * where: { status: 'active' },
1606
+ * orderBy: { name: 'asc' },
1607
+ * })
1608
+ *
1609
+ * // Data updates reactively when collection changes
1610
+ * return (
1611
+ * <Table
1612
+ * columns={[
1613
+ * { key: 'name', header: 'Name', sortable: true },
1614
+ * { key: 'email', header: 'Email' },
1615
+ * ]}
1616
+ * data={data}
1617
+ * sortBy={sort.field}
1618
+ * sortDirection={sort.direction}
1619
+ * onSort={(field) => setSort(field)}
1620
+ * onRowAction={(action, row) => {
1621
+ * if (action === 'delete') {
1622
+ * mutate.delete({ id: row.id })
1623
+ * }
1624
+ * }}
1625
+ * />
1626
+ * )
1627
+ * }
1628
+ * ```
1629
+ */
1630
+
1631
+ /**
1632
+ * Sort state for reactive data components
1633
+ *
1634
+ * @example
1635
+ * ```typescript
1636
+ * const sort: SortState = {
1637
+ * field: 'createdAt',
1638
+ * direction: 'desc',
1639
+ * }
1640
+ * ```
1641
+ */
1642
+ interface SortState {
1643
+ /** Field to sort by */
1644
+ field: string | null;
1645
+ /** Sort direction: 'asc' or 'desc' */
1646
+ direction: OrderDirection;
1647
+ }
1648
+ /**
1649
+ * Selection state for reactive data components
1650
+ *
1651
+ * @example
1652
+ * ```typescript
1653
+ * const selection: SelectionState = {
1654
+ * mode: 'multi',
1655
+ * selected: new Set(['user-1', 'user-3']),
1656
+ * }
1657
+ * ```
1658
+ */
1659
+ interface SelectionState {
1660
+ /** Selection mode: 'single', 'multi', or 'none' */
1661
+ mode: 'single' | 'multi' | 'none';
1662
+ /** Set of selected item IDs */
1663
+ selected: Set<string>;
1664
+ }
1665
+ /**
1666
+ * Pagination state for reactive data components
1667
+ *
1668
+ * @example
1669
+ * ```typescript
1670
+ * const pagination: PaginationState = {
1671
+ * page: 1,
1672
+ * pageSize: 20,
1673
+ * total: 150,
1674
+ * }
1675
+ * ```
1676
+ */
1677
+ interface PaginationState {
1678
+ /** Current page (1-indexed) */
1679
+ page: number;
1680
+ /** Items per page */
1681
+ pageSize: number;
1682
+ /** Total item count (from query) */
1683
+ total: number;
1684
+ }
1685
+ /**
1686
+ * Options for useReactiveData hook
1687
+ *
1688
+ * @template T - The document type
1689
+ *
1690
+ * @remarks
1691
+ * Extends QueryOptions with reactive-specific options like selection, sorting,
1692
+ * and pagination control.
1693
+ *
1694
+ * @example
1695
+ * ```typescript
1696
+ * const options: ReactiveDataOptions<User> = {
1697
+ * collection: 'users',
1698
+ * where: { role: 'admin' },
1699
+ * orderBy: { createdAt: 'desc' },
1700
+ * limit: 20,
1701
+ * selectable: 'multi',
1702
+ * optimistic: true,
1703
+ * }
1704
+ * ```
1705
+ */
1706
+ interface ReactiveDataOptions<T> {
1707
+ /** Collection name to query from */
1708
+ collection: string;
1709
+ /** Filter conditions */
1710
+ where?: WhereClause<T>;
1711
+ /** Sort order */
1712
+ orderBy?: OrderByClause<T> | OrderByClause<T>[];
1713
+ /** Maximum items to return */
1714
+ limit?: number;
1715
+ /** Items to skip (for pagination) */
1716
+ offset?: number;
1717
+ /** Enable selection: 'single', 'multi', or false */
1718
+ selectable?: 'single' | 'multi' | boolean;
1719
+ /** Enable optimistic updates (default: true) */
1720
+ optimistic?: boolean;
1721
+ /** Primary key field (default: 'id') */
1722
+ primaryKey?: keyof T;
1723
+ }
1724
+ /**
1725
+ * Result of useReactiveData hook
1726
+ *
1727
+ * @template T - The document type
1728
+ *
1729
+ * @remarks
1730
+ * Provides reactive data, loading/error states, mutation functions, and
1731
+ * controls for sorting, selection, and pagination.
1732
+ *
1733
+ * @example
1734
+ * ```typescript
1735
+ * const {
1736
+ * data,
1737
+ * isLoading,
1738
+ * error,
1739
+ * mutate,
1740
+ * sort,
1741
+ * setSort,
1742
+ * selection,
1743
+ * toggleSelect,
1744
+ * pagination,
1745
+ * setPage,
1746
+ * } = useReactiveData<User>({ collection: 'users' })
1747
+ * ```
1748
+ */
1749
+ interface ReactiveDataResult<T> {
1750
+ /** Reactive data array - updates when collection changes */
1751
+ data: T[];
1752
+ /** True while initial query is executing */
1753
+ isLoading: boolean;
1754
+ /** Error if query or mutation failed */
1755
+ error: Error | undefined;
1756
+ /** Manual refetch function */
1757
+ refetch: () => void;
1758
+ /** Mutation functions for insert, update, delete */
1759
+ mutate: {
1760
+ /** Insert a new document */
1761
+ insert: (data: T) => Promise<void>;
1762
+ /** Update documents matching filter */
1763
+ update: (filter: Partial<T>, updates: Partial<T>) => Promise<void>;
1764
+ /** Delete a document by ID */
1765
+ delete: (filter: {
1766
+ id: string;
1767
+ } | Partial<T>) => Promise<void>;
1768
+ };
1769
+ /** True while any mutation is pending */
1770
+ isMutating: boolean;
1771
+ /** Current sort state */
1772
+ sort: SortState;
1773
+ /** Set sort field (toggles direction if same field) */
1774
+ setSort: (field: string) => void;
1775
+ /** Current selection state */
1776
+ selection: SelectionState;
1777
+ /** Toggle selection for an item */
1778
+ toggleSelect: (id: string) => void;
1779
+ /** Select all items */
1780
+ selectAll: () => void;
1781
+ /** Clear all selections */
1782
+ clearSelection: () => void;
1783
+ /** Current pagination state */
1784
+ pagination: PaginationState;
1785
+ /** Go to a specific page */
1786
+ setPage: (page: number) => void;
1787
+ /** Change page size */
1788
+ setPageSize: (size: number) => void;
1789
+ }
1790
+ /**
1791
+ * Options for useReactiveTable hook
1792
+ *
1793
+ * @template T - The document type
1794
+ *
1795
+ * @remarks
1796
+ * Table-specific options extending ReactiveDataOptions with column definitions.
1797
+ */
1798
+ interface ReactiveTableOptions<T> extends ReactiveDataOptions<T> {
1799
+ /** Column definitions for the table */
1800
+ columns?: Array<{
1801
+ key: keyof T;
1802
+ header: string;
1803
+ sortable?: boolean;
1804
+ width?: number;
1805
+ align?: 'left' | 'center' | 'right';
1806
+ }>;
1807
+ }
1808
+ /**
1809
+ * Options for useReactiveList hook
1810
+ *
1811
+ * @template T - The document type
1812
+ *
1813
+ * @remarks
1814
+ * List-specific options extending ReactiveDataOptions.
1815
+ */
1816
+ interface ReactiveListOptions<T> extends ReactiveDataOptions<T> {
1817
+ /** Field to use as display text */
1818
+ labelField?: keyof T;
1819
+ /** Field to use as icon */
1820
+ iconField?: keyof T;
1821
+ }
1822
+ /**
1823
+ * Options for useReactiveMetrics hook
1824
+ *
1825
+ * @template T - The document type
1826
+ *
1827
+ * @remarks
1828
+ * Metrics-specific options for aggregated data display.
1829
+ */
1830
+ interface ReactiveMetricsOptions<T> extends Omit<ReactiveDataOptions<T>, 'limit' | 'offset'> {
1831
+ /** Metrics to compute from collection data */
1832
+ metrics: Array<{
1833
+ /** Unique key for the metric */
1834
+ key: string;
1835
+ /** Display label */
1836
+ label: string;
1837
+ /** Field to aggregate */
1838
+ field: keyof T;
1839
+ /** Aggregation function */
1840
+ aggregate: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'latest';
1841
+ /** Format for display */
1842
+ format?: 'number' | 'currency' | 'percentage';
1843
+ /** Unit suffix */
1844
+ unit?: string;
1845
+ }>;
1846
+ }
1847
+ /**
1848
+ * Single metric result
1849
+ */
1850
+ interface MetricValue {
1851
+ /** Metric key */
1852
+ key: string;
1853
+ /** Display label */
1854
+ label: string;
1855
+ /** Computed value */
1856
+ value: number | string;
1857
+ /** Trend direction (computed from previous values if available) */
1858
+ trend?: 'up' | 'down' | 'neutral';
1859
+ /** Trend percentage change */
1860
+ trendValue?: number;
1861
+ /** Optional sparkline data */
1862
+ sparkline?: number[];
1863
+ }
1864
+ /**
1865
+ * Result of useReactiveMetrics hook
1866
+ */
1867
+ interface ReactiveMetricsResult {
1868
+ /** Computed metric values */
1869
+ metrics: MetricValue[];
1870
+ /** True while initial query is executing */
1871
+ isLoading: boolean;
1872
+ /** Error if query failed */
1873
+ error: Error | undefined;
1874
+ /** Manual refetch function */
1875
+ refetch: () => void;
1876
+ }
1877
+ /**
1878
+ * Options for useReactiveCard hook
1879
+ *
1880
+ * @template T - The document type
1881
+ *
1882
+ * @remarks
1883
+ * Card-specific options for single-record display.
1884
+ */
1885
+ interface ReactiveCardOptions<T> {
1886
+ /** Collection name */
1887
+ collection: string;
1888
+ /** Filter to find single record */
1889
+ where: WhereClause<T>;
1890
+ /** Fields to display as key-value pairs */
1891
+ fields?: Array<{
1892
+ key: keyof T;
1893
+ label: string;
1894
+ format?: 'string' | 'date' | 'currency' | 'badge';
1895
+ }>;
1896
+ /** Enable optimistic updates */
1897
+ optimistic?: boolean;
1898
+ }
1899
+ /**
1900
+ * Result of useReactiveCard hook
1901
+ */
1902
+ interface ReactiveCardResult<T> {
1903
+ /** Single record data */
1904
+ data: T | null;
1905
+ /** True while loading */
1906
+ isLoading: boolean;
1907
+ /** Error if query failed */
1908
+ error: Error | undefined;
1909
+ /** Refetch function */
1910
+ refetch: () => void;
1911
+ /** Update the record */
1912
+ update: (updates: Partial<T>) => Promise<void>;
1913
+ /** True while updating */
1914
+ isUpdating: boolean;
1915
+ }
1916
+ /**
1917
+ * Hook for reactive data binding with TanStack DB collections
1918
+ *
1919
+ * Provides reactive data updates, optimistic mutations, sorting, selection,
1920
+ * and pagination for data components like Table and List.
1921
+ *
1922
+ * @template T - The document type (must extend Record<string, any>)
1923
+ *
1924
+ * @param options - Configuration for collection, filters, and behavior
1925
+ * @returns ReactiveDataResult with data, mutations, and state controls
1926
+ *
1927
+ * @remarks
1928
+ * - Data updates automatically when collection changes (via subscriptions)
1929
+ * - Optimistic updates show changes immediately, roll back on error
1930
+ * - Sort state toggles direction when same field is selected
1931
+ * - Selection supports single and multi-select modes
1932
+ * - Pagination is handled client-side with limit/offset
1933
+ *
1934
+ * @example
1935
+ * ```tsx
1936
+ * function UserList() {
1937
+ * const {
1938
+ * data,
1939
+ * isLoading,
1940
+ * mutate,
1941
+ * sort,
1942
+ * setSort,
1943
+ * selection,
1944
+ * toggleSelect,
1945
+ * } = useReactiveData<User>({
1946
+ * collection: 'users',
1947
+ * where: { status: 'active' },
1948
+ * orderBy: { name: 'asc' },
1949
+ * selectable: 'multi',
1950
+ * })
1951
+ *
1952
+ * if (isLoading) return <Spinner />
1953
+ *
1954
+ * return (
1955
+ * <List
1956
+ * items={data.map(user => ({
1957
+ * id: user.id,
1958
+ * text: user.name,
1959
+ * selected: selection.selected.has(user.id),
1960
+ * }))}
1961
+ * onItemClick={(id) => toggleSelect(id)}
1962
+ * onDelete={(id) => mutate.delete({ id })}
1963
+ * />
1964
+ * )
1965
+ * }
1966
+ * ```
1967
+ *
1968
+ * @example
1969
+ * ```tsx
1970
+ * // With optimistic updates
1971
+ * function QuickAddUser() {
1972
+ * const { mutate, isMutating } = useReactiveData<User>({
1973
+ * collection: 'users',
1974
+ * optimistic: true,
1975
+ * })
1976
+ *
1977
+ * const handleAdd = async () => {
1978
+ * // UI updates immediately, rolls back if server fails
1979
+ * await mutate.insert({
1980
+ * id: crypto.randomUUID(),
1981
+ * name: 'New User',
1982
+ * status: 'active',
1983
+ * })
1984
+ * }
1985
+ *
1986
+ * return (
1987
+ * <button onClick={handleAdd} disabled={isMutating}>
1988
+ * {isMutating ? 'Adding...' : 'Add User'}
1989
+ * </button>
1990
+ * )
1991
+ * }
1992
+ * ```
1993
+ */
1994
+ declare function useReactiveData<T extends Record<string, any>>(options: ReactiveDataOptions<T>): ReactiveDataResult<T>;
1995
+ /**
1996
+ * Hook for reactive table data with TanStack DB integration
1997
+ *
1998
+ * Specialized version of useReactiveData for Table components with
1999
+ * column-aware sorting and selection.
2000
+ *
2001
+ * @template T - The document type
2002
+ *
2003
+ * @param options - Table-specific options including column definitions
2004
+ * @returns ReactiveDataResult with table-optimized behavior
2005
+ *
2006
+ * @example
2007
+ * ```tsx
2008
+ * function UsersTable() {
2009
+ * const {
2010
+ * data,
2011
+ * sort,
2012
+ * setSort,
2013
+ * selection,
2014
+ * toggleSelect,
2015
+ * } = useReactiveTable<User>({
2016
+ * collection: 'users',
2017
+ * columns: [
2018
+ * { key: 'name', header: 'Name', sortable: true },
2019
+ * { key: 'email', header: 'Email' },
2020
+ * { key: 'role', header: 'Role', sortable: true },
2021
+ * ],
2022
+ * selectable: 'multi',
2023
+ * })
2024
+ *
2025
+ * return (
2026
+ * <Table
2027
+ * columns={columns}
2028
+ * data={data}
2029
+ * sortBy={sort.field}
2030
+ * sortDirection={sort.direction}
2031
+ * onSort={setSort}
2032
+ * selectedRows={Array.from(selection.selected)}
2033
+ * onRowSelect={toggleSelect}
2034
+ * />
2035
+ * )
2036
+ * }
2037
+ * ```
2038
+ */
2039
+ declare function useReactiveTable<T extends Record<string, any>>(options: ReactiveTableOptions<T>): ReactiveDataResult<T>;
2040
+ /**
2041
+ * Hook for reactive list data with TanStack DB integration
2042
+ *
2043
+ * Specialized version of useReactiveData for List components with
2044
+ * item-level selection and actions.
2045
+ *
2046
+ * @template T - The document type
2047
+ *
2048
+ * @param options - List-specific options
2049
+ * @returns ReactiveDataResult with list-optimized behavior
2050
+ *
2051
+ * @example
2052
+ * ```tsx
2053
+ * function TaskList() {
2054
+ * const {
2055
+ * data,
2056
+ * mutate,
2057
+ * toggleSelect,
2058
+ * } = useReactiveList<Task>({
2059
+ * collection: 'tasks',
2060
+ * where: { completed: false },
2061
+ * orderBy: { priority: 'desc' },
2062
+ * labelField: 'title',
2063
+ * selectable: 'single',
2064
+ * })
2065
+ *
2066
+ * return (
2067
+ * <List
2068
+ * items={data.map(task => ({
2069
+ * id: task.id,
2070
+ * content: task.title,
2071
+ * icon: task.priority === 'high' ? 'alert' : 'task',
2072
+ * }))}
2073
+ * onItemClick={(id) => toggleSelect(id)}
2074
+ * onDelete={(id) => mutate.delete({ id })}
2075
+ * />
2076
+ * )
2077
+ * }
2078
+ * ```
2079
+ */
2080
+ declare function useReactiveList<T extends Record<string, any>>(options: ReactiveListOptions<T>): ReactiveDataResult<T>;
2081
+ /**
2082
+ * Hook for reactive metrics computed from TanStack DB collections
2083
+ *
2084
+ * Aggregates collection data into metric values with optional trend
2085
+ * computation and sparkline data.
2086
+ *
2087
+ * @template T - The document type
2088
+ *
2089
+ * @param options - Metrics configuration with aggregation definitions
2090
+ * @returns ReactiveMetricsResult with computed metric values
2091
+ *
2092
+ * @example
2093
+ * ```tsx
2094
+ * function DashboardMetrics() {
2095
+ * const { metrics, isLoading } = useReactiveMetrics<Order>({
2096
+ * collection: 'orders',
2097
+ * where: { status: 'completed' },
2098
+ * metrics: [
2099
+ * {
2100
+ * key: 'total-orders',
2101
+ * label: 'Total Orders',
2102
+ * field: 'id',
2103
+ * aggregate: 'count',
2104
+ * },
2105
+ * {
2106
+ * key: 'revenue',
2107
+ * label: 'Revenue',
2108
+ * field: 'total',
2109
+ * aggregate: 'sum',
2110
+ * format: 'currency',
2111
+ * },
2112
+ * {
2113
+ * key: 'avg-order',
2114
+ * label: 'Avg Order',
2115
+ * field: 'total',
2116
+ * aggregate: 'avg',
2117
+ * format: 'currency',
2118
+ * },
2119
+ * ],
2120
+ * })
2121
+ *
2122
+ * if (isLoading) return <Spinner />
2123
+ *
2124
+ * return (
2125
+ * <Metrics
2126
+ * metrics={metrics.map(m => ({
2127
+ * label: m.label,
2128
+ * value: m.value,
2129
+ * trend: m.trend,
2130
+ * trendValue: m.trendValue,
2131
+ * }))}
2132
+ * />
2133
+ * )
2134
+ * }
2135
+ * ```
2136
+ */
2137
+ declare function useReactiveMetrics<T extends Record<string, any>>(options: ReactiveMetricsOptions<T>): ReactiveMetricsResult;
2138
+ /**
2139
+ * Hook for reactive single-record card data with TanStack DB integration
2140
+ *
2141
+ * Fetches and subscribes to a single record from a collection for
2142
+ * Card component display.
2143
+ *
2144
+ * @template T - The document type
2145
+ *
2146
+ * @param options - Card-specific options
2147
+ * @returns ReactiveCardResult with single record and update function
2148
+ *
2149
+ * @example
2150
+ * ```tsx
2151
+ * function UserProfileCard({ userId }: { userId: string }) {
2152
+ * const {
2153
+ * data,
2154
+ * isLoading,
2155
+ * update,
2156
+ * isUpdating,
2157
+ * } = useReactiveCard<User>({
2158
+ * collection: 'users',
2159
+ * where: { id: userId },
2160
+ * fields: [
2161
+ * { key: 'name', label: 'Name' },
2162
+ * { key: 'email', label: 'Email' },
2163
+ * { key: 'role', label: 'Role', format: 'badge' },
2164
+ * ],
2165
+ * })
2166
+ *
2167
+ * if (isLoading) return <Spinner />
2168
+ * if (!data) return <Empty message="User not found" />
2169
+ *
2170
+ * return (
2171
+ * <Card
2172
+ * title={data.name}
2173
+ * subtitle={data.email}
2174
+ * pairs={[
2175
+ * { key: 'Role', value: data.role },
2176
+ * { key: 'Status', value: data.status },
2177
+ * ]}
2178
+ * actions={[
2179
+ * {
2180
+ * label: isUpdating ? 'Saving...' : 'Edit',
2181
+ * action: () => update({ status: 'updated' }),
2182
+ * },
2183
+ * ]}
2184
+ * />
2185
+ * )
2186
+ * }
2187
+ * ```
2188
+ */
2189
+ declare function useReactiveCard<T extends Record<string, any>>(options: ReactiveCardOptions<T>): ReactiveCardResult<T>;
2190
+
2191
+ /**
2192
+ * @mdxui/terminal SaaS Collections
2193
+ *
2194
+ * Pre-built Zod schemas and collections for common SaaS primitives:
2195
+ * - Users: Authentication and user management
2196
+ * - APIKeys: API key management with permissions
2197
+ * - Webhooks: Webhook configuration and event subscriptions
2198
+ * - Teams: Team/organization management with members
2199
+ * - Usage: Usage metrics tracking
2200
+ *
2201
+ * @example
2202
+ * ```typescript
2203
+ * import {
2204
+ * UsersCollection,
2205
+ * APIKeysCollection,
2206
+ * WebhooksCollection,
2207
+ * TeamsCollection,
2208
+ * UsageCollection,
2209
+ * type User,
2210
+ * type APIKey,
2211
+ * } from '@mdxui/terminal'
2212
+ *
2213
+ * // Create collections
2214
+ * const users = UsersCollection()
2215
+ * const apiKeys = APIKeysCollection()
2216
+ *
2217
+ * // Insert data
2218
+ * await users.insert({
2219
+ * id: 'user-1',
2220
+ * name: 'Alice',
2221
+ * email: 'alice@example.com',
2222
+ * role: 'admin',
2223
+ * createdAt: new Date(),
2224
+ * })
2225
+ *
2226
+ * // Query
2227
+ * const admins = await users.findMany({
2228
+ * where: { role: 'admin' }
2229
+ * })
2230
+ * ```
2231
+ */
2232
+
2233
+ /**
2234
+ * User role enum - defines access levels
2235
+ */
2236
+ declare const UserRoleSchema: z.ZodEnum<["admin", "user", "viewer"]>;
2237
+ /**
2238
+ * User schema - validates user account information
2239
+ *
2240
+ * @example
2241
+ * ```typescript
2242
+ * const user = UserSchema.parse({
2243
+ * id: 'user-1',
2244
+ * name: 'Alice',
2245
+ * email: 'alice@example.com',
2246
+ * role: 'admin',
2247
+ * createdAt: new Date(),
2248
+ * })
2249
+ * ```
2250
+ */
2251
+ declare const UserSchema: z.ZodObject<{
2252
+ /** Unique user identifier */
2253
+ id: z.ZodString;
2254
+ /** User's display name */
2255
+ name: z.ZodString;
2256
+ /** User's email address (validated format) */
2257
+ email: z.ZodString;
2258
+ /** User's role: admin, user, or viewer */
2259
+ role: z.ZodEnum<["admin", "user", "viewer"]>;
2260
+ /** When the user account was created */
2261
+ createdAt: z.ZodDate;
2262
+ }, "strip", z.ZodTypeAny, {
2263
+ email: string;
2264
+ name: string;
2265
+ id: string;
2266
+ role: "user" | "admin" | "viewer";
2267
+ createdAt: Date;
2268
+ }, {
2269
+ email: string;
2270
+ name: string;
2271
+ id: string;
2272
+ role: "user" | "admin" | "viewer";
2273
+ createdAt: Date;
2274
+ }>;
2275
+ /**
2276
+ * APIKey schema - validates API key configuration
2277
+ *
2278
+ * @example
2279
+ * ```typescript
2280
+ * const key = APIKeySchema.parse({
2281
+ * id: 'key-1',
2282
+ * key: 'sk_test_abc123',
2283
+ * name: 'Development',
2284
+ * permissions: ['read:api', 'write:webhooks'],
2285
+ * expiresAt: new Date('2025-12-31'),
2286
+ * })
2287
+ * ```
2288
+ */
2289
+ declare const APIKeySchema: z.ZodObject<{
2290
+ /** Unique key identifier */
2291
+ id: z.ZodString;
2292
+ /** The actual API key string (secret) */
2293
+ key: z.ZodString;
2294
+ /** Human-readable name for the key */
2295
+ name: z.ZodString;
2296
+ /** Array of permission strings this key grants */
2297
+ permissions: z.ZodArray<z.ZodString, "many">;
2298
+ /** When the key expires */
2299
+ expiresAt: z.ZodDate;
2300
+ }, "strip", z.ZodTypeAny, {
2301
+ name: string;
2302
+ key: string;
2303
+ id: string;
2304
+ permissions: string[];
2305
+ expiresAt: Date;
2306
+ }, {
2307
+ name: string;
2308
+ key: string;
2309
+ id: string;
2310
+ permissions: string[];
2311
+ expiresAt: Date;
2312
+ }>;
2313
+ /**
2314
+ * Webhook schema - validates webhook configuration
2315
+ *
2316
+ * @example
2317
+ * ```typescript
2318
+ * const webhook = WebhookSchema.parse({
2319
+ * id: 'webhook-1',
2320
+ * url: 'https://example.com/webhook',
2321
+ * events: ['user.created', 'user.updated'],
2322
+ * secret: 'whsec_test_abc123',
2323
+ * active: true,
2324
+ * })
2325
+ * ```
2326
+ */
2327
+ declare const WebhookSchema: z.ZodObject<{
2328
+ /** Unique webhook identifier */
2329
+ id: z.ZodString;
2330
+ /** Webhook endpoint URL (validated format) */
2331
+ url: z.ZodString;
2332
+ /** Events this webhook listens to (non-empty array) */
2333
+ events: z.ZodArray<z.ZodString, "many">;
2334
+ /** Webhook signing secret */
2335
+ secret: z.ZodString;
2336
+ /** Whether the webhook is currently active */
2337
+ active: z.ZodBoolean;
2338
+ }, "strip", z.ZodTypeAny, {
2339
+ url: string;
2340
+ active: boolean;
2341
+ id: string;
2342
+ events: string[];
2343
+ secret: string;
2344
+ }, {
2345
+ url: string;
2346
+ active: boolean;
2347
+ id: string;
2348
+ events: string[];
2349
+ secret: string;
2350
+ }>;
2351
+ /**
2352
+ * Team schema - validates team configuration
2353
+ *
2354
+ * @example
2355
+ * ```typescript
2356
+ * const team = TeamSchema.parse({
2357
+ * id: 'team-1',
2358
+ * name: 'Engineering',
2359
+ * members: ['user-1', 'user-2', 'user-3'],
2360
+ * })
2361
+ * ```
2362
+ */
2363
+ declare const TeamSchema: z.ZodObject<{
2364
+ /** Unique team identifier */
2365
+ id: z.ZodString;
2366
+ /** Team name */
2367
+ name: z.ZodString;
2368
+ /** Array of user IDs who are members */
2369
+ members: z.ZodArray<z.ZodString, "many">;
2370
+ }, "strip", z.ZodTypeAny, {
2371
+ name: string;
2372
+ id: string;
2373
+ members: string[];
2374
+ }, {
2375
+ name: string;
2376
+ id: string;
2377
+ members: string[];
2378
+ }>;
2379
+ /**
2380
+ * Usage schema - validates usage metrics
2381
+ *
2382
+ * @example
2383
+ * ```typescript
2384
+ * const usage = UsageSchema.parse({
2385
+ * id: 'usage-1',
2386
+ * metric: 'api_calls',
2387
+ * value: 1500,
2388
+ * timestamp: new Date(),
2389
+ * })
2390
+ * ```
2391
+ */
2392
+ declare const UsageSchema: z.ZodObject<{
2393
+ /** Unique usage record identifier */
2394
+ id: z.ZodString;
2395
+ /** Name of the metric being tracked */
2396
+ metric: z.ZodString;
2397
+ /** Numeric value of the metric */
2398
+ value: z.ZodNumber;
2399
+ /** When this metric was recorded */
2400
+ timestamp: z.ZodDate;
2401
+ }, "strip", z.ZodTypeAny, {
2402
+ value: number;
2403
+ id: string;
2404
+ metric: string;
2405
+ timestamp: Date;
2406
+ }, {
2407
+ value: number;
2408
+ id: string;
2409
+ metric: string;
2410
+ timestamp: Date;
2411
+ }>;
2412
+ /** User type - inferred from UserSchema */
2413
+ type User = z.infer<typeof UserSchema>;
2414
+ /** APIKey type - inferred from APIKeySchema */
2415
+ type APIKey = z.infer<typeof APIKeySchema>;
2416
+ /** Webhook type - inferred from WebhookSchema */
2417
+ type Webhook = z.infer<typeof WebhookSchema>;
2418
+ /** Team type - inferred from TeamSchema */
2419
+ type Team = z.infer<typeof TeamSchema>;
2420
+ /** Usage type - inferred from UsageSchema */
2421
+ type Usage = z.infer<typeof UsageSchema>;
2422
+ /** User role type - admin, user, or viewer */
2423
+ type UserRole = z.infer<typeof UserRoleSchema>;
2424
+ /**
2425
+ * Creates a Users collection with Zod validation
2426
+ *
2427
+ * @returns A typed Collection<User> for managing user accounts
2428
+ *
2429
+ * @example
2430
+ * ```typescript
2431
+ * const users = UsersCollection()
2432
+ *
2433
+ * // Insert a user
2434
+ * const user = await users.insert({
2435
+ * id: 'user-1',
2436
+ * name: 'Alice',
2437
+ * email: 'alice@example.com',
2438
+ * role: 'admin',
2439
+ * createdAt: new Date(),
2440
+ * })
2441
+ *
2442
+ * // Find admins
2443
+ * const admins = await users.findMany({
2444
+ * where: { role: 'admin' }
2445
+ * })
2446
+ *
2447
+ * // Subscribe to changes
2448
+ * const unsubscribe = users.subscribe((allUsers) => {
2449
+ * console.log('Users changed:', allUsers.length)
2450
+ * })
2451
+ * ```
2452
+ */
2453
+ declare function UsersCollection(): Collection<User>;
2454
+ /**
2455
+ * Creates an APIKeys collection with Zod validation
2456
+ *
2457
+ * @returns A typed Collection<APIKey> for managing API keys
2458
+ *
2459
+ * @example
2460
+ * ```typescript
2461
+ * const apiKeys = APIKeysCollection()
2462
+ *
2463
+ * // Create a new key
2464
+ * const key = await apiKeys.insert({
2465
+ * id: 'key-1',
2466
+ * key: 'sk_test_abc123',
2467
+ * name: 'Development',
2468
+ * permissions: ['read:api'],
2469
+ * expiresAt: new Date('2025-12-31'),
2470
+ * })
2471
+ *
2472
+ * // Find non-expired keys
2473
+ * const validKeys = await apiKeys.findMany({
2474
+ * where: { expiresAt: { $gt: new Date() } }
2475
+ * })
2476
+ * ```
2477
+ */
2478
+ declare function APIKeysCollection(): Collection<APIKey>;
2479
+ /**
2480
+ * Creates a Webhooks collection with Zod validation
2481
+ *
2482
+ * @returns A typed Collection<Webhook> for managing webhook configurations
2483
+ *
2484
+ * @example
2485
+ * ```typescript
2486
+ * const webhooks = WebhooksCollection()
2487
+ *
2488
+ * // Create a webhook
2489
+ * await webhooks.insert({
2490
+ * id: 'webhook-1',
2491
+ * url: 'https://example.com/webhook',
2492
+ * events: ['user.created'],
2493
+ * secret: 'whsec_abc123',
2494
+ * active: true,
2495
+ * })
2496
+ *
2497
+ * // Find active webhooks
2498
+ * const active = await webhooks.findMany({
2499
+ * where: { active: true }
2500
+ * })
2501
+ * ```
2502
+ */
2503
+ declare function WebhooksCollection(): Collection<Webhook>;
2504
+ /**
2505
+ * Creates a Teams collection with Zod validation
2506
+ *
2507
+ * @returns A typed Collection<Team> for managing teams and their members
2508
+ *
2509
+ * @example
2510
+ * ```typescript
2511
+ * const teams = TeamsCollection()
2512
+ *
2513
+ * // Create a team
2514
+ * await teams.insert({
2515
+ * id: 'team-1',
2516
+ * name: 'Engineering',
2517
+ * members: ['user-1', 'user-2'],
2518
+ * })
2519
+ *
2520
+ * // Add a member
2521
+ * await teams.update(
2522
+ * { id: 'team-1' },
2523
+ * { members: ['user-1', 'user-2', 'user-3'] }
2524
+ * )
2525
+ * ```
2526
+ */
2527
+ declare function TeamsCollection(): Collection<Team>;
2528
+ /**
2529
+ * Creates a Usage collection with Zod validation
2530
+ *
2531
+ * @returns A typed Collection<Usage> for tracking usage metrics
2532
+ *
2533
+ * @example
2534
+ * ```typescript
2535
+ * const usage = UsageCollection()
2536
+ *
2537
+ * // Record usage
2538
+ * await usage.insert({
2539
+ * id: 'usage-1',
2540
+ * metric: 'api_calls',
2541
+ * value: 1500,
2542
+ * timestamp: new Date(),
2543
+ * })
2544
+ *
2545
+ * // Get usage for a specific metric
2546
+ * const apiCalls = await usage.findMany({
2547
+ * where: { metric: 'api_calls' },
2548
+ * orderBy: { timestamp: 'desc' }
2549
+ * })
2550
+ * ```
2551
+ */
2552
+ declare function UsageCollection(): Collection<Usage>;
2553
+
2554
+ export { type APIKey, APIKeySchema, APIKeysCollection, type Collection, type ComparisonOperators, type ConflictResolution, type DB, type DBConfig, DBProvider, type DBProviderProps, type DOSyncAdapter, type DOSyncConfig, type FieldFilter, type FindManyOptions, type MetricValue, type MutationOperation, type MutationOptions, type MutationResult, type OrderByClause, type OrderDirection, type PaginationState, type QueryOptions, type QueryResult, type ReactiveCardOptions, type ReactiveCardResult, type ReactiveDataOptions, type ReactiveDataResult, type ReactiveListOptions, type ReactiveMetricsOptions, type ReactiveMetricsResult, type ReactiveTableOptions, type ReconnectOptions, type SelectionState, type SortState, type SyncAdapter, type Team, TeamSchema, TeamsCollection, type Usage, UsageCollection, UsageSchema, type User, type UserRole, UserRoleSchema, UserSchema, UsersCollection, type Webhook, WebhookSchema, WebhooksCollection, type WhereClause, createCollection, createDB, createDOSync, useDBContext, useMutation, useQuery, useReactiveCard, useReactiveData, useReactiveList, useReactiveMetrics, useReactiveTable };