ai-database 0.1.0 → 0.2.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 (72) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-test.log +102 -0
  3. package/README.md +381 -68
  4. package/TESTING.md +410 -0
  5. package/TEST_SUMMARY.md +250 -0
  6. package/TODO.md +128 -0
  7. package/dist/ai-promise-db.d.ts +370 -0
  8. package/dist/ai-promise-db.d.ts.map +1 -0
  9. package/dist/ai-promise-db.js +839 -0
  10. package/dist/ai-promise-db.js.map +1 -0
  11. package/dist/authorization.d.ts +531 -0
  12. package/dist/authorization.d.ts.map +1 -0
  13. package/dist/authorization.js +632 -0
  14. package/dist/authorization.js.map +1 -0
  15. package/dist/durable-clickhouse.d.ts +193 -0
  16. package/dist/durable-clickhouse.d.ts.map +1 -0
  17. package/dist/durable-clickhouse.js +422 -0
  18. package/dist/durable-clickhouse.js.map +1 -0
  19. package/dist/durable-promise.d.ts +182 -0
  20. package/dist/durable-promise.d.ts.map +1 -0
  21. package/dist/durable-promise.js +409 -0
  22. package/dist/durable-promise.js.map +1 -0
  23. package/dist/execution-queue.d.ts +239 -0
  24. package/dist/execution-queue.d.ts.map +1 -0
  25. package/dist/execution-queue.js +400 -0
  26. package/dist/execution-queue.js.map +1 -0
  27. package/dist/index.d.ts +50 -191
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +79 -462
  30. package/dist/index.js.map +1 -0
  31. package/dist/linguistic.d.ts +115 -0
  32. package/dist/linguistic.d.ts.map +1 -0
  33. package/dist/linguistic.js +379 -0
  34. package/dist/linguistic.js.map +1 -0
  35. package/dist/memory-provider.d.ts +304 -0
  36. package/dist/memory-provider.d.ts.map +1 -0
  37. package/dist/memory-provider.js +785 -0
  38. package/dist/memory-provider.js.map +1 -0
  39. package/dist/schema.d.ts +899 -0
  40. package/dist/schema.d.ts.map +1 -0
  41. package/dist/schema.js +1165 -0
  42. package/dist/schema.js.map +1 -0
  43. package/dist/tests.d.ts +107 -0
  44. package/dist/tests.d.ts.map +1 -0
  45. package/dist/tests.js +568 -0
  46. package/dist/tests.js.map +1 -0
  47. package/dist/types.d.ts +972 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +126 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +37 -37
  52. package/src/ai-promise-db.ts +1243 -0
  53. package/src/authorization.ts +1102 -0
  54. package/src/durable-clickhouse.ts +596 -0
  55. package/src/durable-promise.ts +582 -0
  56. package/src/execution-queue.ts +608 -0
  57. package/src/index.test.ts +868 -0
  58. package/src/index.ts +337 -0
  59. package/src/linguistic.ts +404 -0
  60. package/src/memory-provider.test.ts +1036 -0
  61. package/src/memory-provider.ts +1119 -0
  62. package/src/schema.test.ts +1254 -0
  63. package/src/schema.ts +2296 -0
  64. package/src/tests.ts +725 -0
  65. package/src/types.ts +1177 -0
  66. package/test/README.md +153 -0
  67. package/test/edge-cases.test.ts +646 -0
  68. package/test/provider-resolution.test.ts +402 -0
  69. package/tsconfig.json +9 -0
  70. package/vitest.config.ts +19 -0
  71. package/dist/index.d.mts +0 -195
  72. package/dist/index.mjs +0 -430
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > ai-database@0.2.0 build /Users/nathanclevenger/projects/mdx.org.ai/primitives/packages/ai-database
4
+ > tsc -p tsconfig.json
5
+
@@ -0,0 +1,102 @@
1
+
2
+ > ai-database@0.0.1 test /Users/nathanclevenger/projects/mdx.org.ai/primitives/packages/ai-database
3
+ > vitest
4
+
5
+
6
+ DEV v2.1.9 /Users/nathanclevenger/projects/mdx.org.ai/primitives/packages/ai-database
7
+
8
+ ✓ src/schema.test.ts (83 tests) 13ms
9
+ ✓ src/memory-provider.test.ts (81 tests) 197ms
10
+ ❯ src/index.test.ts (47 tests | 1 failed) 13ms
11
+ × DB integration tests > list and query operations > iterates with options 5ms
12
+ → expected [] to deeply equal [ 'John' ]
13
+ ✓ test/edge-cases.test.ts (43 tests) 9ms
14
+ ✓ test/provider-resolution.test.ts (38 tests) 2ms
15
+
16
+ ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
17
+
18
+ FAIL src/index.test.ts > DB integration tests > list and query operations > iterates with options
19
+ AssertionError: expected [] to deeply equal [ 'John' ]
20
+
21
+ - Expected
22
+ + Received
23
+
24
+ - Array [
25
+ - "John",
26
+ - ]
27
+ + Array []
28
+
29
+ ❯ src/index.test.ts:251:21
30
+ 249| })
31
+ 250|
32
+ 251| expect(names).toEqual(['John'])
33
+ | ^
34
+ 252| })
35
+ 253| })
36
+
37
+ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
38
+
39
+ Test Files 1 failed | 4 passed (5)
40
+ Tests 1 failed | 291 passed (292)
41
+ Start at 14:14:37
42
+ Duration 673ms (transform 184ms, setup 0ms, collect 232ms, tests 235ms, environment 0ms, prepare 43ms)
43
+
44
+ FAIL Tests failed. Watching for file changes...
45
+ press h to show help, press q to quit
46
+ c RERUN src/ai-promise-db.ts
47
+
48
+ ✓ src/index.test.ts (47 tests) 9ms
49
+ ✓ src/schema.test.ts (83 tests) 7ms
50
+ ✓ test/edge-cases.test.ts (43 tests) 9ms
51
+ ✓ test/provider-resolution.test.ts (38 tests) 2ms
52
+
53
+ Test Files 4 passed (4)
54
+ Tests 211 passed (211)
55
+ Start at 14:35:16
56
+ Duration 79ms
57
+
58
+ PASS Waiting for file changes...
59
+ press h to show help, press q to quit
60
+ c RERUN src/ai-promise-db.ts
61
+
62
+ ✓ src/index.test.ts (47 tests) 10ms
63
+ ✓ test/edge-cases.test.ts (43 tests) 9ms
64
+ ✓ src/schema.test.ts (83 tests) 7ms
65
+ ✓ test/provider-resolution.test.ts (38 tests) 2ms
66
+
67
+ Test Files 4 passed (4)
68
+ Tests 211 passed (211)
69
+ Start at 14:35:40
70
+ Duration 70ms
71
+
72
+ PASS Waiting for file changes...
73
+ press h to show help, press q to quit
74
+ c RERUN src/ai-promise-db.ts
75
+
76
+ ✓ src/index.test.ts (47 tests) 10ms
77
+ ✓ test/edge-cases.test.ts (43 tests) 8ms
78
+ ✓ src/schema.test.ts (83 tests) 6ms
79
+ ✓ test/provider-resolution.test.ts (38 tests) 2ms
80
+
81
+ Test Files 4 passed (4)
82
+ Tests 211 passed (211)
83
+ Start at 14:35:53
84
+ Duration 65ms
85
+
86
+ PASS Waiting for file changes...
87
+ press h to show help, press q to quit
88
+ c RERUN src/ai-promise-db.ts
89
+
90
+ ✓ src/index.test.ts (47 tests) 15ms
91
+ ✓ test/edge-cases.test.ts (43 tests) 11ms
92
+ ✓ src/schema.test.ts (83 tests) 9ms
93
+ ✓ test/provider-resolution.test.ts (38 tests) 2ms
94
+
95
+ Test Files 4 passed (4)
96
+ Tests 211 passed (211)
97
+ Start at 01:20:37
98
+ Duration 115ms
99
+
100
+ PASS Waiting for file changes...
101
+ press h to show help, press q to quit
102
+  ELIFECYCLE  Test failed. See above for more details.
package/README.md CHANGED
@@ -1,114 +1,427 @@
1
1
  # ai-database
2
2
 
3
- Direct interface to Payload CMS with database.do compatibility.
3
+ Your data, flowing like conversation.
4
4
 
5
- ## Installation
5
+ ```typescript
6
+ import { DB } from 'ai-database'
6
7
 
7
- ```bash
8
- npm install ai-database
9
- # or
10
- yarn add ai-database
11
- # or
12
- pnpm add ai-database
8
+ const { db } = DB({
9
+ Lead: { name: 'string', company: 'Company.leads' },
10
+ Company: { name: 'string' }
11
+ })
12
+
13
+ // Chain without await
14
+ const leads = db.Lead.list()
15
+ const qualified = await leads.filter(l => l.score > 80)
16
+
17
+ // Batch relationship loading
18
+ const enriched = await leads.map(lead => ({
19
+ name: lead.name,
20
+ company: lead.company, // Batch loaded!
21
+ }))
13
22
  ```
14
23
 
15
- ## Usage
24
+ ## Promise Pipelining
16
25
 
17
- ### Node.js Environment
26
+ Chain database operations without `await`:
18
27
 
19
28
  ```typescript
20
- import { getPayload } from 'payload'
21
- import config from '@payload-config'
22
- import { DB } from 'ai-database'
29
+ const leads = db.Lead.list()
30
+ const topLeads = leads.filter(l => l.score > 80)
31
+ const names = topLeads.map(l => l.name)
23
32
 
24
- // Initialize with Payload instance
25
- const payload = await getPayload({ config })
26
- const db = DB({ payload })
33
+ // Only await when you need the result
34
+ const result = await names
35
+ ```
27
36
 
28
- // Use the same interface as database.do
29
- const posts = await db.posts.find({
30
- where: { status: 'published' },
31
- limit: 10,
32
- })
37
+ ## Batch Relationship Loading
38
+
39
+ Eliminate N+1 queries automatically:
40
+
41
+ ```typescript
42
+ // Old way - N+1 queries
43
+ const leads = await db.Lead.list()
44
+ for (const lead of leads) {
45
+ const company = await db.Company.get(lead.companyId) // N queries!
46
+ }
33
47
 
34
- const post = await db.posts.findOne('post-123')
48
+ // New way - batch loaded
49
+ const enriched = await db.Lead.list().map(lead => ({
50
+ lead,
51
+ company: lead.company, // All companies loaded in ONE query
52
+ }))
35
53
  ```
36
54
 
37
- ### Edge Environment
55
+ ## Natural Language Queries
56
+
57
+ Ask your database questions:
38
58
 
39
59
  ```typescript
40
- import { DB } from 'ai-database'
60
+ const results = await db.Lead`who closed deals this month?`
61
+ const pending = await db.Order`what's stuck in processing?`
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Real-World Examples
67
+
68
+ ### Sales Pipeline
41
69
 
42
- // Initialize with REST API URL
43
- const db = DB({
44
- apiUrl: 'https://your-payload-api.com/api',
45
- apiKey: 'your-api-key',
70
+ ```typescript
71
+ const { db } = DB({
72
+ Lead: {
73
+ name: 'string',
74
+ email: 'string',
75
+ score: 'number',
76
+ company: 'Company.leads',
77
+ },
78
+ Company: {
79
+ name: 'string',
80
+ industry: 'string',
81
+ }
46
82
  })
47
83
 
48
- // Use the same interface as database.do
49
- const posts = await db.posts.find({
50
- where: { status: 'published' },
51
- limit: 10,
84
+ // Find high-value leads with their companies
85
+ const qualified = await db.Lead.list()
86
+ .filter(lead => lead.score > 80)
87
+ .map(lead => ({
88
+ lead,
89
+ company: lead.company,
90
+ }))
91
+
92
+ // Ask questions naturally
93
+ const results = await db.Lead`who hasn't responded in 2 weeks?`
94
+ ```
95
+
96
+ ### Customer Success
97
+
98
+ ```typescript
99
+ const { db } = DB({
100
+ Customer: {
101
+ name: 'string',
102
+ healthScore: 'number',
103
+ mrr: 'number',
104
+ csm: 'User.customers',
105
+ },
106
+ User: { name: 'string' }
52
107
  })
53
108
 
54
- const post = await db.posts.findOne('post-123')
109
+ // At-risk customers with their CSMs
110
+ const atRisk = await db.Customer.list()
111
+ .filter(c => c.healthScore < 50)
112
+ .map(c => ({
113
+ customer: c,
114
+ csm: c.csm,
115
+ mrr: c.mrr,
116
+ }))
55
117
  ```
56
118
 
57
- ### Generating Embeddings
119
+ ### Order Management
58
120
 
59
121
  ```typescript
60
- import { generateEmbedding, calculateSimilarity } from 'ai-database'
122
+ const { db } = DB({
123
+ Order: {
124
+ status: 'string',
125
+ total: 'number',
126
+ customer: 'Customer.orders',
127
+ items: ['OrderItem.order'],
128
+ },
129
+ OrderItem: { product: 'string', quantity: 'number' },
130
+ Customer: { name: 'string' }
131
+ })
132
+
133
+ // Pending orders with all details
134
+ const pending = await db.Order
135
+ .find({ status: 'pending' })
136
+ .map(order => ({
137
+ order,
138
+ customer: order.customer,
139
+ items: order.items,
140
+ }))
141
+ ```
61
142
 
62
- // Generate embeddings for text
63
- const result = await generateEmbedding('Text to embed')
143
+ ---
64
144
 
65
- if (result.success) {
66
- console.log('Embedding:', result.embedding)
67
- console.log('Model used:', result.model)
145
+ ## Schema Definition
68
146
 
69
- // Calculate similarity between two embeddings
70
- const embedding1 = result.embedding[0]
71
- const embedding2 = await generateEmbedding('Similar text').then((r) => r.embedding?.[0])
147
+ Define once, get typed operations everywhere:
72
148
 
73
- if (embedding1 && embedding2) {
74
- const similarity = calculateSimilarity(embedding1, embedding2)
75
- console.log('Similarity score:', similarity)
149
+ ```typescript
150
+ const { db, events, actions, nouns, verbs } = DB({
151
+ Post: {
152
+ title: 'string',
153
+ content: 'markdown',
154
+ author: 'Author.posts', // Creates both directions
155
+ },
156
+ Author: {
157
+ name: 'string',
158
+ // posts: Post[] auto-created from backref
76
159
  }
77
- }
160
+ })
161
+ ```
162
+
163
+ ### Field Types
164
+
165
+ | Type | Description |
166
+ |------|-------------|
167
+ | `string` | Text |
168
+ | `number` | Numeric |
169
+ | `boolean` | True/false |
170
+ | `date` | Date only |
171
+ | `datetime` | Date and time |
172
+ | `markdown` | Rich text |
173
+ | `json` | Structured data |
174
+ | `url` | URL string |
175
+
176
+ ### Relationships
177
+
178
+ ```typescript
179
+ // One-to-many: Post has one Author, Author has many Posts
180
+ Post: { author: 'Author.posts' }
181
+
182
+ // Many-to-many: Post has many Tags, Tag has many Posts
183
+ Post: { tags: ['Tag.posts'] }
78
184
  ```
79
185
 
80
- ## API
186
+ ---
81
187
 
82
- The API is compatible with `database.do`, providing the same methods for each collection:
188
+ ## CRUD Operations
83
189
 
84
- - `find(options?)`: Find documents in the collection
85
- - `findOne(id)`: Find a single document by ID
86
- - `create(data)`: Create a new document
87
- - `update(id, data)`: Update an existing document
88
- - `delete(id)`: Delete a document
89
- - `search(query, options?)`: Search for documents
190
+ All operations return `DBPromise` for chaining:
90
191
 
91
- ## Environment-specific Adapters
192
+ ```typescript
193
+ // Read
194
+ const lead = await db.Lead.get('lead-123')
195
+ const leads = await db.Lead.list()
196
+ const first = await db.Lead.first()
197
+ const found = await db.Lead.find({ status: 'active' })
198
+
199
+ // Search
200
+ const results = await db.Lead.search('enterprise SaaS')
201
+
202
+ // Write (returns regular Promise)
203
+ const lead = await db.Lead.create({ name: 'Acme Corp' })
204
+ await db.Lead.update(lead.$id, { score: 90 })
205
+ await db.Lead.delete(lead.$id)
206
+ ```
92
207
 
93
- For more control over environment-specific initialization:
208
+ ### Chainable Methods
94
209
 
95
210
  ```typescript
96
- import { createNodeClient, createEdgeClient } from 'ai-database/adapters'
211
+ db.Lead.list()
212
+ .filter(l => l.score > 50)
213
+ .sort((a, b) => b.score - a.score)
214
+ .limit(10)
215
+ .map(l => ({ name: l.name, score: l.score }))
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Events
97
221
 
98
- // Node.js
99
- const nodeDb = createNodeClient({ payload })
222
+ React to changes in real-time:
223
+
224
+ ```typescript
225
+ events.on('Lead.created', event => {
226
+ notifySlack(`New lead: ${event.data.name}`)
227
+ })
100
228
 
101
- // Edge
102
- const edgeDb = createEdgeClient({
103
- apiUrl: 'https://your-payload-api.com/api',
229
+ events.on('*.updated', event => {
230
+ logChange(event)
104
231
  })
105
232
  ```
106
233
 
107
- ## Embedding Functions
234
+ ## forEach - Large-Scale Processing
108
235
 
109
- - `generateEmbedding(text, options?)`: Generate embeddings for text using the AI SDK
110
- - `calculateSimilarity(embedding1, embedding2)`: Calculate cosine similarity between two embeddings
236
+ Process thousands of items with concurrency, progress tracking, and error handling:
237
+
238
+ ```typescript
239
+ // Simple iteration
240
+ await db.Lead.forEach(lead => {
241
+ console.log(lead.name)
242
+ })
243
+
244
+ // With AI and concurrency
245
+ const result = await db.Lead.forEach(async lead => {
246
+ const analysis = await ai`analyze ${lead}`
247
+ await db.Lead.update(lead.$id, { analysis })
248
+ }, {
249
+ concurrency: 10,
250
+ onProgress: p => console.log(`${p.completed}/${p.total} (${p.rate.toFixed(1)}/s)`),
251
+ })
252
+
253
+ // With error handling and retries
254
+ await db.Order.forEach(async order => {
255
+ await sendInvoice(order)
256
+ }, {
257
+ concurrency: 5,
258
+ maxRetries: 3,
259
+ retryDelay: attempt => 1000 * Math.pow(2, attempt), // Exponential backoff
260
+ onError: (err, order) => err.code === 'RATE_LIMIT' ? 'retry' : 'continue',
261
+ })
262
+
263
+ console.log(`Completed: ${result.completed}, Failed: ${result.failed}`)
264
+ ```
265
+
266
+ ### forEach Options
267
+
268
+ | Option | Type | Description |
269
+ |--------|------|-------------|
270
+ | `concurrency` | `number` | Max parallel operations (default: 1) |
271
+ | `maxRetries` | `number` | Retries per item (default: 0) |
272
+ | `retryDelay` | `number \| fn` | Delay between retries |
273
+ | `onProgress` | `fn` | Progress callback |
274
+ | `onError` | `'continue' \| 'retry' \| 'skip' \| 'stop' \| fn` | Error handling |
275
+ | `timeout` | `number` | Timeout per item in ms |
276
+ | `persist` | `boolean \| string` | Enable durability (string = custom action name) |
277
+ | `resume` | `string` | Resume from action ID |
278
+
279
+ ### Durable forEach
280
+
281
+ Persist progress to survive crashes:
282
+
283
+ ```typescript
284
+ // Enable persistence - auto-names action as "Lead.forEach"
285
+ const result = await db.Lead.forEach(processLead, {
286
+ concurrency: 10,
287
+ persist: true,
288
+ })
289
+
290
+ console.log(`Action ID: ${result.actionId}`)
291
+ ```
292
+
293
+ Custom action name:
294
+
295
+ ```typescript
296
+ await db.Lead.forEach(processLead, {
297
+ persist: 'analyze-leads', // Custom action name
298
+ })
299
+ ```
300
+
301
+ Resume after a crash:
302
+
303
+ ```typescript
304
+ await db.Lead.forEach(processLead, {
305
+ resume: 'action-123', // Skips already-processed items
306
+ })
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Actions
312
+
313
+ Track long-running operations:
314
+
315
+ ```typescript
316
+ const action = await actions.create({
317
+ type: 'import-leads',
318
+ data: { file: 'leads.csv' },
319
+ total: 1000,
320
+ })
321
+
322
+ await actions.update(action.id, { progress: 500 })
323
+ await actions.update(action.id, { status: 'completed' })
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Installation
329
+
330
+ ```bash
331
+ pnpm add ai-database
332
+ ```
333
+
334
+ ## Configuration
335
+
336
+ ```bash
337
+ DATABASE_URL=./content # filesystem (default)
338
+ DATABASE_URL=sqlite://./data # SQLite
339
+ DATABASE_URL=:memory: # in-memory
340
+ ```
341
+
342
+ ## Documentation
343
+
344
+ - [Full Documentation](https://primitives.org.ai/database)
345
+ - [CRUD Operations](https://primitives.org.ai/database/create)
346
+ - [Schema Types](https://primitives.org.ai/database/schema)
347
+ - [Events](https://primitives.org.ai/database/events)
348
+
349
+ ## Document Database Interface
350
+
351
+ In addition to the schema-first graph model, `ai-database` also exports environment-agnostic types for document-based storage (MDX files with frontmatter). These types are used by `@mdxdb/*` adapters and work in any JavaScript runtime (Node.js, Bun, Deno, Workers, Browser).
352
+
353
+ ```typescript
354
+ import type {
355
+ DocumentDatabase,
356
+ DocListOptions,
357
+ DocSearchOptions,
358
+ Document,
359
+ } from 'ai-database'
360
+
361
+ // The DocumentDatabase interface
362
+ interface DocumentDatabase<TData> {
363
+ list(options?: DocListOptions): Promise<DocListResult<TData>>
364
+ search(options: DocSearchOptions): Promise<DocSearchResult<TData>>
365
+ get(id: string, options?: DocGetOptions): Promise<Document<TData> | null>
366
+ set(id: string, doc: Document<TData>, options?: DocSetOptions): Promise<DocSetResult>
367
+ delete(id: string, options?: DocDeleteOptions): Promise<DocDeleteResult>
368
+ close?(): Promise<void>
369
+ }
370
+ ```
371
+
372
+ ### Document Types
373
+
374
+ | Type | Description |
375
+ |------|-------------|
376
+ | `Document<TData>` | MDX document with id, type, context, data, and content |
377
+ | `DocumentDatabase<TData>` | Interface for document storage adapters |
378
+ | `DocListOptions` | Options for listing documents (limit, offset, sortBy, type, prefix) |
379
+ | `DocListResult<TData>` | List result with documents, total, hasMore |
380
+ | `DocSearchOptions` | Search options (query, fields, semantic) |
381
+ | `DocSearchResult<TData>` | Search result with scores |
382
+ | `DocGetOptions` | Get options (includeAst, includeCode) |
383
+ | `DocSetOptions` | Set options (createOnly, updateOnly, version) |
384
+ | `DocSetResult` | Set result (id, version, created) |
385
+ | `DocDeleteOptions` | Delete options (soft, version) |
386
+ | `DocDeleteResult` | Delete result (id, deleted) |
387
+
388
+ ### View Types
389
+
390
+ For bi-directional relationship rendering:
391
+
392
+ | Type | Description |
393
+ |------|-------------|
394
+ | `ViewManager` | Interface for managing views |
395
+ | `ViewDocument` | View template definition |
396
+ | `ViewContext` | Context for rendering a view |
397
+ | `ViewRenderResult` | Rendered markdown and entities |
398
+ | `ViewSyncResult` | Mutations from extracting edited markdown |
399
+ | `DocumentDatabaseWithViews` | Database with view support |
400
+
401
+ ### Usage with @mdxdb adapters
402
+
403
+ ```typescript
404
+ // Filesystem adapter
405
+ import { createFsDatabase } from '@mdxdb/fs'
406
+ const db = createFsDatabase({ root: './content' })
407
+
408
+ // API adapter
409
+ import { createApiDatabase } from '@mdxdb/api'
410
+ const db = createApiDatabase({ baseUrl: 'https://api.example.com' })
411
+
412
+ // SQLite adapter
413
+ import { createSqliteDatabase } from '@mdxdb/sqlite'
414
+ const db = createSqliteDatabase({ path: './data.db' })
415
+
416
+ // Same DocumentDatabase interface regardless of backend
417
+ const doc = await db.get('posts/hello-world')
418
+ await db.set('posts/new', { data: { title: 'New Post' }, content: '# Hello' })
419
+ ```
111
420
 
112
- ## License
421
+ ## Related
113
422
 
114
- MIT
423
+ - [ai-functions](https://github.com/ai-primitives/ai-primitives/tree/main/packages/ai-functions) - AI-powered functions
424
+ - [ai-workflows](https://github.com/ai-primitives/ai-primitives/tree/main/packages/ai-workflows) - Event-driven workflows
425
+ - [@mdxdb/fs](https://github.com/ai-primitives/mdx.org.ai/tree/main/packages/@mdxdb/fs) - Filesystem adapter
426
+ - [@mdxdb/sqlite](https://github.com/ai-primitives/mdx.org.ai/tree/main/packages/@mdxdb/sqlite) - SQLite adapter
427
+ - [@mdxdb/api](https://github.com/ai-primitives/mdx.org.ai/tree/main/packages/@mdxdb/api) - HTTP API client