@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,660 @@
1
+ /**
2
+ * @mdxui/terminal Data Layer Types
3
+ *
4
+ * Type definitions for the TanStack DB-like integration.
5
+ * Provides a type-safe, reactive in-memory database with Zod validation,
6
+ * filtering, sorting, pagination, and optimistic updates.
7
+ */
8
+
9
+ import type { ZodSchema, ZodRawShape, z } from 'zod'
10
+
11
+ // ============================================================================
12
+ // Query Filter Types
13
+ // ============================================================================
14
+
15
+ /**
16
+ * Comparison operators for filtering database queries
17
+ *
18
+ * @template T - The type of the field being compared
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * // Using comparison operators in a where clause
23
+ * {
24
+ * $eq: 5, // Equal to 5
25
+ * $ne: 10, // Not equal to 10
26
+ * $gt: 3, // Greater than 3
27
+ * $gte: 3, // Greater than or equal to 3
28
+ * $lt: 100, // Less than 100
29
+ * $lte: 100, // Less than or equal to 100
30
+ * $in: [1, 2, 3], // In array [1, 2, 3]
31
+ * $nin: [1, 2, 3], // Not in array [1, 2, 3]
32
+ * }
33
+ * ```
34
+ */
35
+ export interface ComparisonOperators<T> {
36
+ /** Equality match */
37
+ $eq?: T
38
+ /** Not equal to */
39
+ $ne?: T
40
+ /** Greater than */
41
+ $gt?: T
42
+ /** Greater than or equal to */
43
+ $gte?: T
44
+ /** Less than */
45
+ $lt?: T
46
+ /** Less than or equal to */
47
+ $lte?: T
48
+ /** Value is in array */
49
+ $in?: T[]
50
+ /** Value is not in array */
51
+ $nin?: T[]
52
+ }
53
+
54
+ /**
55
+ * Field filter - either a direct value for equality or comparison operators
56
+ *
57
+ * @template T - The type of the field
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // Direct equality
62
+ * type Filter = FieldFilter<number> // number
63
+ * const filter: Filter = 5
64
+ *
65
+ * // With operators
66
+ * const filter: Filter = { $gt: 5 }
67
+ * ```
68
+ */
69
+ export type FieldFilter<T> = T | ComparisonOperators<T>
70
+
71
+ /**
72
+ * Where clause for filtering - supports equality, comparison operators, and $or
73
+ *
74
+ * @template T - The document type being queried
75
+ *
76
+ * @remarks
77
+ * - Uses AND logic for multiple field conditions
78
+ * - `$or` is an array of alternative conditions (OR logic)
79
+ * - Can combine $or with other fields (fields AND ($or[...]))
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // Simple equality
84
+ * const where: WhereClause<User> = { role: 'admin' }
85
+ *
86
+ * // With comparison operators
87
+ * const where: WhereClause<User> = { age: { $gte: 18 } }
88
+ *
89
+ * // Multiple conditions (AND)
90
+ * const where: WhereClause<User> = {
91
+ * role: 'admin',
92
+ * age: { $gte: 18 }
93
+ * }
94
+ *
95
+ * // OR conditions
96
+ * const where: WhereClause<User> = {
97
+ * $or: [
98
+ * { role: 'admin' },
99
+ * { role: 'moderator' }
100
+ * ]
101
+ * }
102
+ *
103
+ * // Combined AND/OR
104
+ * const where: WhereClause<User> = {
105
+ * status: 'active',
106
+ * $or: [
107
+ * { role: 'admin' },
108
+ * { role: 'moderator' }
109
+ * ]
110
+ * }
111
+ * ```
112
+ */
113
+ export type WhereClause<T> = {
114
+ [K in keyof T]?: FieldFilter<T[K]>
115
+ } & {
116
+ $or?: Array<WhereClause<T>>
117
+ }
118
+
119
+ /**
120
+ * Sort direction for ordering results
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * type Direction = OrderDirection
125
+ * const ascending: Direction = 'asc'
126
+ * const descending: Direction = 'desc'
127
+ * ```
128
+ */
129
+ export type OrderDirection = 'asc' | 'desc'
130
+
131
+ /**
132
+ * Order by clause for sorting results
133
+ *
134
+ * @template T - The document type being sorted
135
+ *
136
+ * @remarks
137
+ * Maps field names to sort directions (asc/desc)
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * // Sort by age ascending
142
+ * const orderBy: OrderByClause<User> = { age: 'asc' }
143
+ *
144
+ * // Sort by multiple fields
145
+ * const orderByArray: OrderByClause<User>[] = [
146
+ * { role: 'asc' },
147
+ * { age: 'desc' }
148
+ * ]
149
+ * ```
150
+ */
151
+ export type OrderByClause<T> = {
152
+ [K in keyof T]?: OrderDirection
153
+ }
154
+
155
+ // ============================================================================
156
+ // Collection Types
157
+ // ============================================================================
158
+
159
+ /**
160
+ * Configuration for creating a collection
161
+ *
162
+ * @template T - The Zod schema shape for the collection
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * const config: CollectionConfig<typeof UserSchema.shape> = {
167
+ * name: 'users',
168
+ * schema: UserSchema,
169
+ * primaryKey: 'id',
170
+ * indexes: ['email', 'role']
171
+ * }
172
+ * ```
173
+ */
174
+ export interface CollectionConfig<T extends ZodRawShape> {
175
+ /** Collection name - used to reference in queries */
176
+ name: string
177
+ /** Zod schema for automatic validation on insert/update */
178
+ schema: ZodSchema<z.infer<z.ZodObject<T>>>
179
+ /** Primary key field (defaults to 'id'). Used for duplicate detection */
180
+ primaryKey?: keyof z.infer<z.ZodObject<T>>
181
+ /** Fields to index for faster queries (metadata only, used for optimization hints) */
182
+ indexes?: Array<keyof z.infer<z.ZodObject<T>>>
183
+ }
184
+
185
+ /**
186
+ * A typed in-memory collection with CRUD operations, filtering, sorting, and reactive subscriptions
187
+ *
188
+ * @template T - The document type stored in this collection
189
+ *
190
+ * @remarks
191
+ * - All documents are validated against the schema on insert/update
192
+ * - Provides reactive subscriptions for real-time updates
193
+ * - Supports filtering with where clauses and comparison operators
194
+ * - Supports sorting with orderBy and multiple sort fields
195
+ * - Supports pagination with limit and offset
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * const collection = createCollection<User>({
200
+ * name: 'users',
201
+ * schema: UserSchema
202
+ * })
203
+ *
204
+ * // CRUD operations
205
+ * const user = await collection.insert({ id: '1', name: 'Alice', ... })
206
+ * const updated = await collection.update({ id: '1' }, { name: 'Alicia' })
207
+ * const found = await collection.findOne({ id: '1' })
208
+ * const all = await collection.findMany()
209
+ * await collection.delete({ id: '1' })
210
+ *
211
+ * // Subscribe to changes
212
+ * const unsubscribe = collection.subscribe((data) => {
213
+ * console.log('Collection changed:', data)
214
+ * })
215
+ * ```
216
+ */
217
+ export interface Collection<T> {
218
+ /** Collection name - used to reference in queries */
219
+ name: string
220
+ /** Zod schema for validation */
221
+ schema: ZodSchema<T>
222
+ /** Primary key field name */
223
+ primaryKey: string
224
+ /** Indexed field names */
225
+ indexes: string[]
226
+
227
+ /**
228
+ * Insert a new document into the collection
229
+ *
230
+ * @param data - Document to insert (must match schema)
231
+ * @returns The validated document
232
+ * @throws If document fails schema validation or primary key already exists
233
+ */
234
+ insert(data: T): Promise<T>
235
+
236
+ /**
237
+ * Update one or more documents matching the filter
238
+ *
239
+ * @param filter - Documents matching this filter will be updated
240
+ * @param data - Partial updates to apply (merged with existing data)
241
+ * @returns Array of updated documents
242
+ * @throws If updated documents fail schema validation
243
+ */
244
+ update(filter: Partial<T>, data: Partial<T>): Promise<T[]>
245
+
246
+ /**
247
+ * Delete one or more documents matching the filter
248
+ *
249
+ * @param filter - Documents matching this filter will be deleted
250
+ * @returns void
251
+ */
252
+ delete(filter: Partial<T>): Promise<void>
253
+
254
+ /**
255
+ * Find a single document matching the filter
256
+ *
257
+ * @param filter - Equality filter conditions
258
+ * @returns First matching document or null if not found
259
+ */
260
+ findOne(filter: Partial<T>): Promise<T | null>
261
+
262
+ /**
263
+ * Find multiple documents with optional filtering, sorting, and pagination
264
+ *
265
+ * @param options - Query options (where, orderBy, limit, offset)
266
+ * @returns Array of matching documents
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * // Get all
271
+ * const all = await collection.findMany()
272
+ *
273
+ * // With filter
274
+ * const admins = await collection.findMany({
275
+ * where: { role: 'admin' }
276
+ * })
277
+ *
278
+ * // With sorting and pagination
279
+ * const page = await collection.findMany({
280
+ * where: { status: 'active' },
281
+ * orderBy: { createdAt: 'desc' },
282
+ * limit: 20,
283
+ * offset: 0
284
+ * })
285
+ * ```
286
+ */
287
+ findMany(options?: FindManyOptions<T>): Promise<T[]>
288
+
289
+ /**
290
+ * Subscribe to collection changes
291
+ *
292
+ * @param callback - Called whenever data changes with current full collection state
293
+ * @returns Unsubscribe function to remove listener
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * const unsubscribe = collection.subscribe((data) => {
298
+ * console.log('Collection now contains:', data)
299
+ * })
300
+ *
301
+ * // Later: stop listening
302
+ * unsubscribe()
303
+ * ```
304
+ */
305
+ subscribe(callback: (data: T[]) => void): () => void
306
+
307
+ /** Internal: notify all subscribers of changes */
308
+ _notify(): void
309
+ }
310
+
311
+ // ============================================================================
312
+ // Database Types
313
+ // ============================================================================
314
+
315
+ /**
316
+ * Sync adapter interface for remote synchronization
317
+ *
318
+ * @remarks
319
+ * Implement this interface to add custom sync behavior (WebSockets, server polling, etc.)
320
+ * The database automatically calls these methods when mutations occur (if optimistic mode enabled)
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * const syncAdapter: SyncAdapter = {
325
+ * async push(changes) {
326
+ * // Send to server
327
+ * await fetch('/api/sync', { method: 'POST', body: JSON.stringify(changes) })
328
+ * },
329
+ * async pull() {
330
+ * // Get from server
331
+ * const res = await fetch('/api/sync')
332
+ * return res.json()
333
+ * },
334
+ * subscribe(callback) {
335
+ * // Listen for remote changes
336
+ * const ws = new WebSocket('wss://...')
337
+ * ws.onmessage = (e) => callback(e.data)
338
+ * return () => ws.close()
339
+ * }
340
+ * }
341
+ * ```
342
+ */
343
+ export interface SyncAdapter {
344
+ /**
345
+ * Push local changes to remote
346
+ *
347
+ * @param changes - Array of change objects to send to remote
348
+ * @throws Error if push fails - mutation will be rolled back if optimistic
349
+ */
350
+ push(changes: unknown[]): Promise<void>
351
+
352
+ /**
353
+ * Pull remote changes
354
+ *
355
+ * @returns Array of changes from remote
356
+ */
357
+ pull(): Promise<unknown[]>
358
+
359
+ /**
360
+ * Subscribe to remote changes
361
+ *
362
+ * @param callback - Called with remote changes
363
+ * @returns Unsubscribe function
364
+ */
365
+ subscribe(callback: (changes: unknown[]) => void): () => void
366
+ }
367
+
368
+ /**
369
+ * Database configuration for creating a DB instance
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * const config: DBConfig = {
374
+ * collections: [usersCollection, todosCollection],
375
+ * sync: customSyncAdapter
376
+ * }
377
+ * ```
378
+ */
379
+ export interface DBConfig {
380
+ /** Collections to register in the database */
381
+ collections?: Collection<any>[]
382
+ /** Optional sync adapter for remote synchronization */
383
+ sync?: SyncAdapter
384
+ }
385
+
386
+ /**
387
+ * Database instance - main entry point for accessing collections and syncing
388
+ *
389
+ * @remarks
390
+ * - Collections are accessed by name via `db.collections[name]`
391
+ * - Provides centralized management of all collections
392
+ * - Optional sync adapter for remote data synchronization
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * const db = createDB({
397
+ * collections: [usersCollection, todosCollection],
398
+ * sync: syncAdapter
399
+ * })
400
+ *
401
+ * // Access collections
402
+ * const users = await db.collections.users.findMany()
403
+ *
404
+ * // Clear all data
405
+ * await db.clear()
406
+ *
407
+ * // Close resources
408
+ * db.close()
409
+ * ```
410
+ */
411
+ export interface DB {
412
+ /** Registered collections by name - access with `db.collections[collectionName]` */
413
+ collections: Record<string, Collection<any>>
414
+ /** Optional sync adapter if configured */
415
+ sync?: SyncAdapter
416
+
417
+ /**
418
+ * Close the database connection and clean up resources
419
+ */
420
+ close(): void
421
+
422
+ /**
423
+ * Clear all data from all collections
424
+ *
425
+ * @returns Promise that resolves when all data is cleared
426
+ */
427
+ clear(): Promise<void>
428
+ }
429
+
430
+ // ============================================================================
431
+ // Hook Types
432
+ // ============================================================================
433
+
434
+ /**
435
+ * Options for collection.findMany() - internal collection query
436
+ *
437
+ * @template T - The document type
438
+ *
439
+ * @remarks
440
+ * Unlike `QueryOptions`, this doesn't include `from` since it's called on a collection directly
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * const options: FindManyOptions<User> = {
445
+ * where: { role: 'admin' },
446
+ * orderBy: { name: 'asc' },
447
+ * limit: 10,
448
+ * offset: 0
449
+ * }
450
+ * const users = await collection.findMany(options)
451
+ * ```
452
+ */
453
+ export interface FindManyOptions<T> {
454
+ /** Filter conditions using WhereClause syntax */
455
+ where?: WhereClause<T>
456
+ /** Sort order - single field or array of fields with directions */
457
+ orderBy?: OrderByClause<T> | OrderByClause<T>[]
458
+ /** Maximum number of results to return */
459
+ limit?: number
460
+ /** Number of results to skip (for pagination) */
461
+ offset?: number
462
+ }
463
+
464
+ /**
465
+ * Options for useQuery hook - React hook query interface
466
+ *
467
+ * @template T - The document type being queried
468
+ *
469
+ * @remarks
470
+ * Extends `FindManyOptions` with `from` to specify which collection to query.
471
+ * Called within a `DBProvider` context.
472
+ *
473
+ * @example
474
+ * ```typescript
475
+ * const { data, isLoading, error } = useQuery<User>({
476
+ * from: 'users',
477
+ * where: { role: 'admin', age: { $gte: 18 } },
478
+ * orderBy: { name: 'asc' },
479
+ * limit: 20
480
+ * })
481
+ * ```
482
+ */
483
+ export interface QueryOptions<T> extends FindManyOptions<T> {
484
+ /** Collection name to query from */
485
+ from: string
486
+ }
487
+
488
+ /**
489
+ * Result of useQuery hook - reactive query state and refetch control
490
+ *
491
+ * @template T - The document type
492
+ *
493
+ * @remarks
494
+ * - `data` starts as undefined while loading
495
+ * - `isLoading` is true until first query completes
496
+ * - Automatically updates when collection changes (reactive)
497
+ * - Subscribe callbacks automatically re-apply filters and sorting
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * const { data, isLoading, error, refetch } = useQuery<User>({
502
+ * from: 'users'
503
+ * })
504
+ *
505
+ * if (isLoading) return <Spinner />
506
+ * if (error) return <Error message={error.message} />
507
+ *
508
+ * return (
509
+ * <div>
510
+ * {data?.map(user => (
511
+ * <UserCard key={user.id} user={user} />
512
+ * ))}
513
+ * <button onClick={refetch}>Refresh</button>
514
+ * </div>
515
+ * )
516
+ * ```
517
+ */
518
+ export interface QueryResult<T> {
519
+ /** Query results - undefined while loading, array when loaded */
520
+ data: T[] | undefined
521
+ /** True while initial query is executing */
522
+ isLoading: boolean
523
+ /** Error object if query failed, undefined if successful */
524
+ error: Error | undefined
525
+ /** Function to manually refetch the query */
526
+ refetch: () => void
527
+ }
528
+
529
+ /**
530
+ * Type of mutation operation
531
+ *
532
+ * @example
533
+ * ```typescript
534
+ * type Op = MutationOperation
535
+ * const operation: Op = 'insert'
536
+ * ```
537
+ */
538
+ export type MutationOperation = 'insert' | 'update' | 'delete'
539
+
540
+ /**
541
+ * Options for useMutation hook
542
+ *
543
+ * @remarks
544
+ * - `insert`: Creates new document
545
+ * - `update`: Updates existing documents matching filter
546
+ * - `delete`: Removes documents matching filter
547
+ * - `optimistic`: If true, updates UI immediately before server confirmation
548
+ * (on error, automatically rolls back)
549
+ *
550
+ * @example
551
+ * ```typescript
552
+ * const { mutate, isPending, error } = useMutation({
553
+ * collection: 'users',
554
+ * operation: 'insert',
555
+ * optimistic: true
556
+ * })
557
+ * ```
558
+ */
559
+ export interface MutationOptions {
560
+ /** Collection name to mutate */
561
+ collection: string
562
+ /** Type of operation: insert, update, or delete */
563
+ operation: MutationOperation
564
+ /** Enable optimistic updates (show change immediately, rollback on error) */
565
+ optimistic?: boolean
566
+ }
567
+
568
+ /**
569
+ * Data format for update mutations
570
+ *
571
+ * @template T - The document type
572
+ *
573
+ * @example
574
+ * ```typescript
575
+ * const updateData: UpdateMutationData<User> = {
576
+ * where: { id: '1' },
577
+ * data: { name: 'Updated Name' }
578
+ * }
579
+ * ```
580
+ */
581
+ export interface UpdateMutationData<T> {
582
+ /** Filter to select which documents to update */
583
+ where: Partial<T>
584
+ /** Partial updates to apply to matching documents */
585
+ data: Partial<T>
586
+ }
587
+
588
+ /**
589
+ * Data format for delete mutations
590
+ *
591
+ * @template T - The document type (generic for flexibility)
592
+ *
593
+ * @example
594
+ * ```typescript
595
+ * const deleteData: DeleteMutationData<User> = {
596
+ * id: 'user-123'
597
+ * }
598
+ * ```
599
+ */
600
+ export interface DeleteMutationData<T> {
601
+ /** ID of document to delete */
602
+ id: string
603
+ }
604
+
605
+ /**
606
+ * Result of useMutation hook - mutation execution and state control
607
+ *
608
+ * @template T - The document type
609
+ *
610
+ * @remarks
611
+ * - Call `mutate()` with data to execute the operation
612
+ * - `isPending` is true while mutation is executing
613
+ * - On error, `error` contains the Error object
614
+ * - Use `reset()` to clear error state after handling
615
+ * - For optimistic updates, local UI updates immediately
616
+ * (automatic rollback if sync fails)
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * const { mutate, isPending, error, reset } = useMutation<User>({
621
+ * collection: 'users',
622
+ * operation: 'insert'
623
+ * })
624
+ *
625
+ * const handleCreate = async () => {
626
+ * try {
627
+ * await mutate({
628
+ * id: '2',
629
+ * name: 'Bob',
630
+ * email: 'bob@example.com',
631
+ * role: 'user'
632
+ * })
633
+ * } catch (err) {
634
+ * console.error('Failed:', err)
635
+ * }
636
+ * }
637
+ *
638
+ * return (
639
+ * <form onSubmit={handleCreate}>
640
+ * <button disabled={isPending}>
641
+ * {isPending ? 'Creating...' : 'Create'}
642
+ * </button>
643
+ * {error && <Error message={error.message} onDismiss={reset} />}
644
+ * </form>
645
+ * )
646
+ * ```
647
+ */
648
+ export interface MutationResult<T> {
649
+ /**
650
+ * Execute the mutation with data
651
+ * Data format depends on operation: T for insert, UpdateMutationData<T> for update, DeleteMutationData<T> for delete
652
+ */
653
+ mutate: (data: T | UpdateMutationData<T> | DeleteMutationData<T>) => Promise<void>
654
+ /** True while mutation is being executed */
655
+ isPending: boolean
656
+ /** Error object if mutation failed, undefined if successful */
657
+ error: Error | undefined
658
+ /** Reset mutation state (clears error and pending flags) */
659
+ reset: () => void
660
+ }