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.
- package/.turbo/turbo-build.log +5 -0
- package/.turbo/turbo-test.log +102 -0
- package/README.md +381 -68
- package/TESTING.md +410 -0
- package/TEST_SUMMARY.md +250 -0
- package/TODO.md +128 -0
- package/dist/ai-promise-db.d.ts +370 -0
- package/dist/ai-promise-db.d.ts.map +1 -0
- package/dist/ai-promise-db.js +839 -0
- package/dist/ai-promise-db.js.map +1 -0
- package/dist/authorization.d.ts +531 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +632 -0
- package/dist/authorization.js.map +1 -0
- package/dist/durable-clickhouse.d.ts +193 -0
- package/dist/durable-clickhouse.d.ts.map +1 -0
- package/dist/durable-clickhouse.js +422 -0
- package/dist/durable-clickhouse.js.map +1 -0
- package/dist/durable-promise.d.ts +182 -0
- package/dist/durable-promise.d.ts.map +1 -0
- package/dist/durable-promise.js +409 -0
- package/dist/durable-promise.js.map +1 -0
- package/dist/execution-queue.d.ts +239 -0
- package/dist/execution-queue.d.ts.map +1 -0
- package/dist/execution-queue.js +400 -0
- package/dist/execution-queue.js.map +1 -0
- package/dist/index.d.ts +50 -191
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -462
- package/dist/index.js.map +1 -0
- package/dist/linguistic.d.ts +115 -0
- package/dist/linguistic.d.ts.map +1 -0
- package/dist/linguistic.js +379 -0
- package/dist/linguistic.js.map +1 -0
- package/dist/memory-provider.d.ts +304 -0
- package/dist/memory-provider.d.ts.map +1 -0
- package/dist/memory-provider.js +785 -0
- package/dist/memory-provider.js.map +1 -0
- package/dist/schema.d.ts +899 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +1165 -0
- package/dist/schema.js.map +1 -0
- package/dist/tests.d.ts +107 -0
- package/dist/tests.d.ts.map +1 -0
- package/dist/tests.js +568 -0
- package/dist/tests.js.map +1 -0
- package/dist/types.d.ts +972 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +126 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -37
- package/src/ai-promise-db.ts +1243 -0
- package/src/authorization.ts +1102 -0
- package/src/durable-clickhouse.ts +596 -0
- package/src/durable-promise.ts +582 -0
- package/src/execution-queue.ts +608 -0
- package/src/index.test.ts +868 -0
- package/src/index.ts +337 -0
- package/src/linguistic.ts +404 -0
- package/src/memory-provider.test.ts +1036 -0
- package/src/memory-provider.ts +1119 -0
- package/src/schema.test.ts +1254 -0
- package/src/schema.ts +2296 -0
- package/src/tests.ts +725 -0
- package/src/types.ts +1177 -0
- package/test/README.md +153 -0
- package/test/edge-cases.test.ts +646 -0
- package/test/provider-resolution.test.ts +402 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +19 -0
- package/dist/index.d.mts +0 -195
- package/dist/index.mjs +0 -430
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,899 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-first Database Definition
|
|
3
|
+
*
|
|
4
|
+
* Declarative schema with automatic bi-directional relationships.
|
|
5
|
+
* Uses mdxld conventions for entity structure.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const { db } = DB({
|
|
10
|
+
* Post: {
|
|
11
|
+
* title: 'string',
|
|
12
|
+
* author: 'Author.posts', // one-to-many: Post.author -> Author, Author.posts -> Post[]
|
|
13
|
+
* tags: ['Tag.posts'], // many-to-many: Post.tags -> Tag[], Tag.posts -> Post[]
|
|
14
|
+
* },
|
|
15
|
+
* Author: {
|
|
16
|
+
* name: 'string',
|
|
17
|
+
* // posts: Post[] auto-created from backref
|
|
18
|
+
* },
|
|
19
|
+
* Tag: {
|
|
20
|
+
* name: 'string',
|
|
21
|
+
* // posts: Post[] auto-created from backref
|
|
22
|
+
* }
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* // Typed access
|
|
26
|
+
* const post = await db.Post.get('123')
|
|
27
|
+
* post.author // Author (single)
|
|
28
|
+
* post.tags // Tag[] (array)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import { DBPromise, type ForEachOptions, type ForEachResult } from './ai-promise-db.js';
|
|
32
|
+
export type { ThingFlat, ThingExpanded, PrimitiveType, FieldDefinition, EntitySchema, DatabaseSchema, ParsedField, ParsedEntity, ParsedSchema, Verb, Noun, NounProperty, NounRelationship, TypeMeta, EntityId, Thing, Relationship, QueryOptions, ThingSearchOptions, CreateOptions, UpdateOptions, RelateOptions, Event, ActionStatus, Action, ArtifactType, Artifact, StoreArtifactOptions, EventQueryOptions, ActionQueryOptions, DBClient, DBClientExtended, CreateEventOptions as GraphCreateEventOptions, CreateActionOptions as GraphCreateActionOptions, } from './types.js';
|
|
33
|
+
export { toExpanded, toFlat, Verbs, resolveUrl, resolveShortUrl, parseUrl } from './types.js';
|
|
34
|
+
export { conjugate, pluralize, singularize, inferNoun, createTypeMeta, getTypeMeta, Type, getVerbFields, } from './linguistic.js';
|
|
35
|
+
import type { EntitySchema, DatabaseSchema, ParsedEntity, ParsedSchema, Verb, Noun } from './types.js';
|
|
36
|
+
/**
|
|
37
|
+
* Create a Noun definition with type inference
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const Post = defineNoun({
|
|
42
|
+
* singular: 'post',
|
|
43
|
+
* plural: 'posts',
|
|
44
|
+
* description: 'A blog post',
|
|
45
|
+
* properties: {
|
|
46
|
+
* title: { type: 'string', description: 'Post title' },
|
|
47
|
+
* content: { type: 'markdown' },
|
|
48
|
+
* },
|
|
49
|
+
* relationships: {
|
|
50
|
+
* author: { type: 'Author', backref: 'posts' },
|
|
51
|
+
* },
|
|
52
|
+
* })
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function defineNoun<T extends Noun>(noun: T): T;
|
|
56
|
+
/**
|
|
57
|
+
* Create a Verb definition with type inference
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const publish = defineVerb({
|
|
62
|
+
* action: 'publish',
|
|
63
|
+
* actor: 'publisher',
|
|
64
|
+
* act: 'publishes',
|
|
65
|
+
* activity: 'publishing',
|
|
66
|
+
* result: 'publication',
|
|
67
|
+
* reverse: { at: 'publishedAt', by: 'publishedBy' },
|
|
68
|
+
* inverse: 'unpublish',
|
|
69
|
+
* })
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function defineVerb<T extends Verb>(verb: T): T;
|
|
73
|
+
/**
|
|
74
|
+
* Convert a Noun to an EntitySchema for use with DB()
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const postNoun = defineNoun({
|
|
79
|
+
* singular: 'post',
|
|
80
|
+
* plural: 'posts',
|
|
81
|
+
* properties: { title: { type: 'string' } },
|
|
82
|
+
* relationships: { author: { type: 'Author', backref: 'posts' } },
|
|
83
|
+
* })
|
|
84
|
+
*
|
|
85
|
+
* const db = DB({
|
|
86
|
+
* Post: nounToSchema(postNoun),
|
|
87
|
+
* })
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function nounToSchema(noun: Noun): EntitySchema;
|
|
91
|
+
/**
|
|
92
|
+
* Built-in Thing schema - base type for all entities
|
|
93
|
+
*
|
|
94
|
+
* Every entity instance is a Thing with a relationship to its Noun.
|
|
95
|
+
* This creates a complete graph: Thing.type -> Noun.things
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* // Every post instance:
|
|
100
|
+
* post.$type // 'Post' (string)
|
|
101
|
+
* post.type // -> Noun('Post') (relationship)
|
|
102
|
+
*
|
|
103
|
+
* // From Noun, get all instances:
|
|
104
|
+
* const postNoun = await db.Noun.get('Post')
|
|
105
|
+
* const allPosts = await postNoun.things // -> Post[]
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare const ThingSchema: EntitySchema;
|
|
109
|
+
/**
|
|
110
|
+
* Built-in Noun schema for storing type definitions
|
|
111
|
+
*
|
|
112
|
+
* Every Type/Collection automatically gets a Noun record stored in the database.
|
|
113
|
+
* This enables introspection and self-describing schemas.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* // When you define:
|
|
118
|
+
* const db = DB({ Post: { title: 'string' } })
|
|
119
|
+
*
|
|
120
|
+
* // The database auto-creates:
|
|
121
|
+
* // db.Noun.get('Post') => { singular: 'post', plural: 'posts', ... }
|
|
122
|
+
*
|
|
123
|
+
* // Query all types:
|
|
124
|
+
* const types = await db.Noun.list()
|
|
125
|
+
*
|
|
126
|
+
* // Get all instances of a type:
|
|
127
|
+
* const postNoun = await db.Noun.get('Post')
|
|
128
|
+
* const allPosts = await postNoun.things
|
|
129
|
+
*
|
|
130
|
+
* // Listen for new types:
|
|
131
|
+
* on.Noun.created(noun => console.log(`New type: ${noun.name}`))
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare const NounSchema: EntitySchema;
|
|
135
|
+
/**
|
|
136
|
+
* Built-in Verb schema for storing action definitions
|
|
137
|
+
*/
|
|
138
|
+
export declare const VerbSchema: EntitySchema;
|
|
139
|
+
/**
|
|
140
|
+
* Built-in Edge schema for relationships between types
|
|
141
|
+
*
|
|
142
|
+
* Every relationship in a schema creates an Edge record.
|
|
143
|
+
* This enables graph queries across the type system.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* // Post.author -> Author creates:
|
|
148
|
+
* // Edge { from: 'Post', name: 'author', to: 'Author', backref: 'posts', cardinality: 'many-to-one' }
|
|
149
|
+
*
|
|
150
|
+
* // Query the graph:
|
|
151
|
+
* const edges = await db.Edge.find({ to: 'Author' })
|
|
152
|
+
* // => [{ from: 'Post', name: 'author' }, { from: 'Comment', name: 'author' }]
|
|
153
|
+
*
|
|
154
|
+
* // What types reference Author?
|
|
155
|
+
* const referencing = edges.map(e => e.from) // ['Post', 'Comment']
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export declare const EdgeSchema: EntitySchema;
|
|
159
|
+
/**
|
|
160
|
+
* System types that are auto-created in every database
|
|
161
|
+
*
|
|
162
|
+
* The graph structure:
|
|
163
|
+
* - Thing.type -> Noun (every instance links to its type)
|
|
164
|
+
* - Noun.things -> Thing[] (every type has its instances)
|
|
165
|
+
* - Edge connects Nouns (relationships between types)
|
|
166
|
+
* - Verb describes actions on Nouns
|
|
167
|
+
*/
|
|
168
|
+
export declare const SystemSchema: DatabaseSchema;
|
|
169
|
+
/**
|
|
170
|
+
* Create Edge records from schema relationships
|
|
171
|
+
*
|
|
172
|
+
* @internal Used by DB() to auto-populate Edge records
|
|
173
|
+
*/
|
|
174
|
+
export declare function createEdgeRecords(typeName: string, schema: EntitySchema, parsedEntity: ParsedEntity): Array<Record<string, unknown>>;
|
|
175
|
+
/**
|
|
176
|
+
* Create a Noun record from a type name and optional schema
|
|
177
|
+
*
|
|
178
|
+
* @internal Used by DB() to auto-populate Noun records
|
|
179
|
+
*/
|
|
180
|
+
export declare function createNounRecord(typeName: string, schema?: EntitySchema, nounDef?: Partial<Noun>): Record<string, unknown>;
|
|
181
|
+
/**
|
|
182
|
+
* Parse a database schema and resolve bi-directional relationships
|
|
183
|
+
*/
|
|
184
|
+
export declare function parseSchema(schema: DatabaseSchema): ParsedSchema;
|
|
185
|
+
/**
|
|
186
|
+
* Map field type to TypeScript type
|
|
187
|
+
*/
|
|
188
|
+
type FieldToTS<T extends string> = T extends 'string' ? string : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'date' | 'datetime' ? Date : T extends 'json' ? Record<string, unknown> : T extends 'markdown' ? string : T extends 'url' ? string : unknown;
|
|
189
|
+
/**
|
|
190
|
+
* Infer entity type from schema definition
|
|
191
|
+
*/
|
|
192
|
+
export type InferEntity<TSchema extends DatabaseSchema, TEntity extends keyof TSchema> = {
|
|
193
|
+
$id: string;
|
|
194
|
+
$type: TEntity;
|
|
195
|
+
} & {
|
|
196
|
+
[K in keyof TSchema[TEntity]]: TSchema[TEntity][K] extends `${infer Type}.${string}` ? Type extends keyof TSchema ? InferEntity<TSchema, Type> : unknown : TSchema[TEntity][K] extends `${infer Type}[]` ? Type extends keyof TSchema ? InferEntity<TSchema, Type>[] : FieldToTS<Type>[] : TSchema[TEntity][K] extends `${infer Type}?` ? FieldToTS<Type> | undefined : FieldToTS<TSchema[TEntity][K] & string>;
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* Operations available on each entity type
|
|
200
|
+
*/
|
|
201
|
+
export interface EntityOperations<T> {
|
|
202
|
+
/** Get an entity by ID */
|
|
203
|
+
get(id: string): Promise<T | null>;
|
|
204
|
+
/** List all entities */
|
|
205
|
+
list(options?: ListOptions): Promise<T[]>;
|
|
206
|
+
/** Find entities matching criteria */
|
|
207
|
+
find(where: Partial<T>): Promise<T[]>;
|
|
208
|
+
/** Search entities */
|
|
209
|
+
search(query: string, options?: SearchOptions): Promise<T[]>;
|
|
210
|
+
/** Create a new entity */
|
|
211
|
+
create(data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
212
|
+
create(id: string, data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
213
|
+
/** Update an entity */
|
|
214
|
+
update(id: string, data: Partial<Omit<T, '$id' | '$type'>>): Promise<T>;
|
|
215
|
+
/** Upsert an entity */
|
|
216
|
+
upsert(id: string, data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
217
|
+
/** Delete an entity */
|
|
218
|
+
delete(id: string): Promise<boolean>;
|
|
219
|
+
/** Iterate over entities */
|
|
220
|
+
forEach(callback: (entity: T) => void | Promise<void>): Promise<void>;
|
|
221
|
+
forEach(options: ListOptions, callback: (entity: T) => void | Promise<void>): Promise<void>;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Operations with promise pipelining support
|
|
225
|
+
*
|
|
226
|
+
* Query methods return DBPromise for chainable operations:
|
|
227
|
+
* - `.map()` with batch optimization
|
|
228
|
+
* - `.filter()`, `.sort()`, `.limit()`
|
|
229
|
+
* - Property access tracking for projections
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* // Chain without await
|
|
234
|
+
* const leads = db.Lead.list()
|
|
235
|
+
* const qualified = await leads
|
|
236
|
+
* .filter(l => l.score > 80)
|
|
237
|
+
* .map(l => ({ name: l.name, company: l.company }))
|
|
238
|
+
*
|
|
239
|
+
* // Batch relationship loading
|
|
240
|
+
* const orders = await db.Order.list().map(o => ({
|
|
241
|
+
* order: o,
|
|
242
|
+
* customer: o.customer, // Batch loaded!
|
|
243
|
+
* }))
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export interface PipelineEntityOperations<T> {
|
|
247
|
+
/** Get an entity by ID */
|
|
248
|
+
get(id: string): DBPromise<T | null>;
|
|
249
|
+
/** List all entities */
|
|
250
|
+
list(options?: ListOptions): DBPromise<T[]>;
|
|
251
|
+
/** Find entities matching criteria */
|
|
252
|
+
find(where: Partial<T>): DBPromise<T[]>;
|
|
253
|
+
/** Search entities */
|
|
254
|
+
search(query: string, options?: SearchOptions): DBPromise<T[]>;
|
|
255
|
+
/** Get first matching entity */
|
|
256
|
+
first(): DBPromise<T | null>;
|
|
257
|
+
/** Create a new entity */
|
|
258
|
+
create(data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
259
|
+
create(id: string, data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
260
|
+
/** Update an entity */
|
|
261
|
+
update(id: string, data: Partial<Omit<T, '$id' | '$type'>>): Promise<T>;
|
|
262
|
+
/** Upsert an entity */
|
|
263
|
+
upsert(id: string, data: Omit<T, '$id' | '$type'>): Promise<T>;
|
|
264
|
+
/** Delete an entity */
|
|
265
|
+
delete(id: string): Promise<boolean>;
|
|
266
|
+
/**
|
|
267
|
+
* Process each entity with concurrency control, progress tracking, and error handling
|
|
268
|
+
*
|
|
269
|
+
* Designed for large-scale operations like AI generations or workflows.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* // Simple iteration
|
|
274
|
+
* await db.Lead.forEach(lead => console.log(lead.name))
|
|
275
|
+
*
|
|
276
|
+
* // With AI and concurrency
|
|
277
|
+
* const result = await db.Lead.forEach(async lead => {
|
|
278
|
+
* const analysis = await ai`analyze ${lead}`
|
|
279
|
+
* await db.Lead.update(lead.$id, { analysis })
|
|
280
|
+
* }, {
|
|
281
|
+
* concurrency: 10,
|
|
282
|
+
* onProgress: p => console.log(`${p.completed}/${p.total}`),
|
|
283
|
+
* })
|
|
284
|
+
*
|
|
285
|
+
* // With error handling
|
|
286
|
+
* await db.Order.forEach(async order => {
|
|
287
|
+
* await sendInvoice(order)
|
|
288
|
+
* }, {
|
|
289
|
+
* maxRetries: 3,
|
|
290
|
+
* onError: (err, order) => err.code === 'RATE_LIMIT' ? 'retry' : 'continue',
|
|
291
|
+
* })
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
forEach<U>(callback: (entity: T, index: number) => U | Promise<U>, options?: ForEachOptions<T>): Promise<ForEachResult>;
|
|
295
|
+
}
|
|
296
|
+
export interface ListOptions {
|
|
297
|
+
where?: Record<string, unknown>;
|
|
298
|
+
orderBy?: string;
|
|
299
|
+
order?: 'asc' | 'desc';
|
|
300
|
+
limit?: number;
|
|
301
|
+
offset?: number;
|
|
302
|
+
}
|
|
303
|
+
export interface SearchOptions extends ListOptions {
|
|
304
|
+
fields?: string[];
|
|
305
|
+
minScore?: number;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Natural language query result
|
|
309
|
+
*/
|
|
310
|
+
export interface NLQueryResult<T = unknown> {
|
|
311
|
+
/** The interpreted query */
|
|
312
|
+
interpretation: string;
|
|
313
|
+
/** Confidence in the interpretation (0-1) */
|
|
314
|
+
confidence: number;
|
|
315
|
+
/** The results */
|
|
316
|
+
results: T[];
|
|
317
|
+
/** SQL/filter equivalent (for debugging) */
|
|
318
|
+
query?: string;
|
|
319
|
+
/** Explanation of what was found */
|
|
320
|
+
explanation?: string;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Tagged template for natural language queries
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* // Query across all types
|
|
328
|
+
* const results = await db`what is happening with joe in ca?`
|
|
329
|
+
*
|
|
330
|
+
* // Query specific type
|
|
331
|
+
* const orders = await db.Orders`what pending orders are delayed?`
|
|
332
|
+
*
|
|
333
|
+
* // With interpolation
|
|
334
|
+
* const name = 'joe'
|
|
335
|
+
* const results = await db`find all orders for ${name}`
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
export type NLQueryFn<T = unknown> = (strings: TemplateStringsArray, ...values: unknown[]) => Promise<NLQueryResult<T>>;
|
|
339
|
+
/**
|
|
340
|
+
* Typed database client based on schema
|
|
341
|
+
*
|
|
342
|
+
* Entity operations return DBPromise for chainable queries:
|
|
343
|
+
* ```ts
|
|
344
|
+
* const { db } = DB({ Lead: { name: 'string', company: 'Company.leads' } })
|
|
345
|
+
*
|
|
346
|
+
* // Chain without await
|
|
347
|
+
* const leads = db.Lead.list()
|
|
348
|
+
* const qualified = await leads.filter(l => l.score > 80)
|
|
349
|
+
*
|
|
350
|
+
* // Batch relationship loading
|
|
351
|
+
* const withCompanies = await leads.map(l => ({
|
|
352
|
+
* lead: l,
|
|
353
|
+
* company: l.company, // Batch loaded!
|
|
354
|
+
* }))
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
export type TypedDB<TSchema extends DatabaseSchema> = {
|
|
358
|
+
[K in keyof TSchema]: PipelineEntityOperations<InferEntity<TSchema, K>> & NLQueryFn<InferEntity<TSchema, K>>;
|
|
359
|
+
} & {
|
|
360
|
+
/** The parsed schema */
|
|
361
|
+
readonly $schema: ParsedSchema;
|
|
362
|
+
/** Get any entity by URL */
|
|
363
|
+
get(url: string): Promise<unknown>;
|
|
364
|
+
/** Search across all entities */
|
|
365
|
+
search(query: string, options?: SearchOptions): Promise<unknown[]>;
|
|
366
|
+
/** Count entities of a type */
|
|
367
|
+
count(type: string, where?: Record<string, unknown>): Promise<number>;
|
|
368
|
+
/** Iterate over entities with a callback */
|
|
369
|
+
forEach(options: {
|
|
370
|
+
type: string;
|
|
371
|
+
where?: Record<string, unknown>;
|
|
372
|
+
concurrency?: number;
|
|
373
|
+
}, callback: (entity: unknown) => void | Promise<void>): Promise<void>;
|
|
374
|
+
/** Set entity data by ID (creates or replaces) */
|
|
375
|
+
set(type: string, id: string, data: Record<string, unknown>): Promise<unknown>;
|
|
376
|
+
/** Generate entities using AI */
|
|
377
|
+
generate(options: GenerateOptions): Promise<unknown | {
|
|
378
|
+
id: string;
|
|
379
|
+
}>;
|
|
380
|
+
/**
|
|
381
|
+
* Natural language query across all types
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```ts
|
|
385
|
+
* const results = await db`what orders are pending for customers in california?`
|
|
386
|
+
* const results = await db`show me joe's recent activity`
|
|
387
|
+
* const results = await db`what changed in the last hour?`
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
ask: NLQueryFn;
|
|
391
|
+
};
|
|
392
|
+
/**
|
|
393
|
+
* Options for AI-powered entity generation
|
|
394
|
+
*/
|
|
395
|
+
export interface GenerateOptions {
|
|
396
|
+
type: string;
|
|
397
|
+
count?: number;
|
|
398
|
+
data?: Record<string, unknown>;
|
|
399
|
+
mode?: 'sync' | 'background';
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Actor data - who performed the action
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* ```ts
|
|
406
|
+
* const actorData: ActorData = {
|
|
407
|
+
* name: 'John Doe',
|
|
408
|
+
* email: 'john@example.com',
|
|
409
|
+
* org: 'Acme Corp',
|
|
410
|
+
* role: 'admin',
|
|
411
|
+
* }
|
|
412
|
+
* ```
|
|
413
|
+
*/
|
|
414
|
+
export interface ActorData {
|
|
415
|
+
/** Actor's display name */
|
|
416
|
+
name?: string;
|
|
417
|
+
/** Actor's email */
|
|
418
|
+
email?: string;
|
|
419
|
+
/** Actor's organization */
|
|
420
|
+
org?: string;
|
|
421
|
+
/** Actor's role or access level */
|
|
422
|
+
role?: string;
|
|
423
|
+
/** Additional actor metadata */
|
|
424
|
+
[key: string]: unknown;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Event data structure - Actor-Event-Object-Result pattern
|
|
428
|
+
*
|
|
429
|
+
* Following ActivityStreams semantics:
|
|
430
|
+
* - Actor: Who did it (user, system, agent)
|
|
431
|
+
* - Event: What happened (created, updated, published)
|
|
432
|
+
* - Object: What it was done to (the entity)
|
|
433
|
+
* - Result: What was the outcome (optional)
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```ts
|
|
437
|
+
* const event: DBEvent = {
|
|
438
|
+
* id: '01HGXYZ...',
|
|
439
|
+
* actor: 'user:john',
|
|
440
|
+
* actorData: { name: 'John Doe', email: 'john@example.com' },
|
|
441
|
+
* event: 'Post.published',
|
|
442
|
+
* object: 'https://example.com/Post/hello-world',
|
|
443
|
+
* objectData: { title: 'Hello World' },
|
|
444
|
+
* result: 'https://example.com/Publication/123',
|
|
445
|
+
* resultData: { url: 'https://blog.example.com/hello-world' },
|
|
446
|
+
* timestamp: new Date(),
|
|
447
|
+
* }
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
export interface DBEvent {
|
|
451
|
+
/** Unique event ID (ULID recommended) */
|
|
452
|
+
id: string;
|
|
453
|
+
/** Actor identifier (user:id, system, agent:name) */
|
|
454
|
+
actor: string;
|
|
455
|
+
/** Actor metadata */
|
|
456
|
+
actorData?: ActorData;
|
|
457
|
+
/** Event type (Entity.action format, e.g., Post.created) */
|
|
458
|
+
event: string;
|
|
459
|
+
/** Object URL/identifier that was acted upon */
|
|
460
|
+
object?: string;
|
|
461
|
+
/** Object data snapshot at time of event */
|
|
462
|
+
objectData?: Record<string, unknown>;
|
|
463
|
+
/** Result URL/identifier (outcome of the action) */
|
|
464
|
+
result?: string;
|
|
465
|
+
/** Result data */
|
|
466
|
+
resultData?: Record<string, unknown>;
|
|
467
|
+
/** Additional metadata */
|
|
468
|
+
meta?: Record<string, unknown>;
|
|
469
|
+
/** When the event occurred */
|
|
470
|
+
timestamp: Date;
|
|
471
|
+
/** @deprecated Use 'event' instead */
|
|
472
|
+
type?: string;
|
|
473
|
+
/** @deprecated Use 'objectData' instead */
|
|
474
|
+
data?: unknown;
|
|
475
|
+
/** @deprecated Use 'object' instead */
|
|
476
|
+
url?: string;
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Options for creating an event
|
|
480
|
+
*/
|
|
481
|
+
export interface CreateEventOptions {
|
|
482
|
+
/** Actor identifier */
|
|
483
|
+
actor: string;
|
|
484
|
+
/** Actor metadata */
|
|
485
|
+
actorData?: ActorData;
|
|
486
|
+
/** Event type */
|
|
487
|
+
event: string;
|
|
488
|
+
/** Object URL/identifier */
|
|
489
|
+
object?: string;
|
|
490
|
+
/** Object data */
|
|
491
|
+
objectData?: Record<string, unknown>;
|
|
492
|
+
/** Result URL/identifier */
|
|
493
|
+
result?: string;
|
|
494
|
+
/** Result data */
|
|
495
|
+
resultData?: Record<string, unknown>;
|
|
496
|
+
/** Additional metadata */
|
|
497
|
+
meta?: Record<string, unknown>;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Events API for subscribing to and emitting events
|
|
501
|
+
*/
|
|
502
|
+
export interface EventsAPI {
|
|
503
|
+
/** Subscribe to events matching a pattern */
|
|
504
|
+
on(pattern: string, handler: (event: DBEvent) => void | Promise<void>): () => void;
|
|
505
|
+
/** Emit an event using Actor-Event-Object-Result pattern */
|
|
506
|
+
emit(options: CreateEventOptions): Promise<DBEvent>;
|
|
507
|
+
/** Emit a simple event (legacy compatibility) */
|
|
508
|
+
emit(type: string, data: unknown): Promise<DBEvent>;
|
|
509
|
+
/** List events with optional filters */
|
|
510
|
+
list(options?: {
|
|
511
|
+
event?: string;
|
|
512
|
+
actor?: string;
|
|
513
|
+
object?: string;
|
|
514
|
+
since?: Date;
|
|
515
|
+
until?: Date;
|
|
516
|
+
limit?: number;
|
|
517
|
+
/** @deprecated Use 'event' instead */
|
|
518
|
+
type?: string;
|
|
519
|
+
}): Promise<DBEvent[]>;
|
|
520
|
+
/** Replay events through a handler */
|
|
521
|
+
replay(options: {
|
|
522
|
+
event?: string;
|
|
523
|
+
actor?: string;
|
|
524
|
+
since?: Date;
|
|
525
|
+
handler: (event: DBEvent) => void | Promise<void>;
|
|
526
|
+
/** @deprecated Use 'event' instead */
|
|
527
|
+
type?: string;
|
|
528
|
+
}): Promise<void>;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Action data structure for durable execution
|
|
532
|
+
*
|
|
533
|
+
* Uses linguistic verb conjugations for semantic clarity:
|
|
534
|
+
* - act: Present tense 3rd person (creates, publishes)
|
|
535
|
+
* - action: Base verb form (create, publish)
|
|
536
|
+
* - activity: Gerund/progressive (creating, publishing)
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* const action: DBAction = {
|
|
541
|
+
* id: '01HGXYZ...',
|
|
542
|
+
* actor: 'user:john',
|
|
543
|
+
* actorData: { name: 'John Doe' },
|
|
544
|
+
* // Verb conjugations
|
|
545
|
+
* act: 'generates', // Present tense: "system generates posts"
|
|
546
|
+
* action: 'generate', // Base form for lookups
|
|
547
|
+
* activity: 'generating', // Progressive: "currently generating posts"
|
|
548
|
+
* // Target
|
|
549
|
+
* object: 'Post',
|
|
550
|
+
* objectData: { count: 100 },
|
|
551
|
+
* // Status
|
|
552
|
+
* status: 'active',
|
|
553
|
+
* progress: 50,
|
|
554
|
+
* total: 100,
|
|
555
|
+
* // Result
|
|
556
|
+
* result: { created: 50 },
|
|
557
|
+
* timestamp: new Date(),
|
|
558
|
+
* }
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
export interface DBAction {
|
|
562
|
+
/** Unique action ID (ULID recommended) */
|
|
563
|
+
id: string;
|
|
564
|
+
/** Actor identifier (user:id, system, agent:name) */
|
|
565
|
+
actor: string;
|
|
566
|
+
/** Actor metadata */
|
|
567
|
+
actorData?: ActorData;
|
|
568
|
+
/** Present tense 3rd person verb (creates, publishes, generates) */
|
|
569
|
+
act: string;
|
|
570
|
+
/** Base verb form - imperative (create, publish, generate) */
|
|
571
|
+
action: string;
|
|
572
|
+
/** Gerund/progressive form (creating, publishing, generating) */
|
|
573
|
+
activity: string;
|
|
574
|
+
/** Object being acted upon (type name or URL) */
|
|
575
|
+
object?: string;
|
|
576
|
+
/** Object data/parameters for the action */
|
|
577
|
+
objectData?: Record<string, unknown>;
|
|
578
|
+
/** Action status */
|
|
579
|
+
status: 'pending' | 'active' | 'completed' | 'failed' | 'cancelled';
|
|
580
|
+
/** Current progress count */
|
|
581
|
+
progress?: number;
|
|
582
|
+
/** Total items to process */
|
|
583
|
+
total?: number;
|
|
584
|
+
/** Result data on completion */
|
|
585
|
+
result?: Record<string, unknown>;
|
|
586
|
+
/** Error message on failure */
|
|
587
|
+
error?: string;
|
|
588
|
+
/** Additional metadata */
|
|
589
|
+
meta?: Record<string, unknown>;
|
|
590
|
+
/** When the action was created */
|
|
591
|
+
createdAt: Date;
|
|
592
|
+
/** When the action started executing */
|
|
593
|
+
startedAt?: Date;
|
|
594
|
+
/** When the action completed/failed */
|
|
595
|
+
completedAt?: Date;
|
|
596
|
+
/** @deprecated Use 'action' instead */
|
|
597
|
+
type?: string;
|
|
598
|
+
/** @deprecated Use 'objectData' instead */
|
|
599
|
+
data?: unknown;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Options for creating an action
|
|
603
|
+
*/
|
|
604
|
+
export interface CreateActionOptions {
|
|
605
|
+
/** Actor identifier */
|
|
606
|
+
actor: string;
|
|
607
|
+
/** Actor metadata */
|
|
608
|
+
actorData?: ActorData;
|
|
609
|
+
/** Base verb (will auto-conjugate to act/activity) */
|
|
610
|
+
action: string;
|
|
611
|
+
/** Object being acted upon */
|
|
612
|
+
object?: string;
|
|
613
|
+
/** Object data/parameters */
|
|
614
|
+
objectData?: Record<string, unknown>;
|
|
615
|
+
/** Total items for progress tracking */
|
|
616
|
+
total?: number;
|
|
617
|
+
/** Additional metadata */
|
|
618
|
+
meta?: Record<string, unknown>;
|
|
619
|
+
/** @deprecated Use 'action' instead */
|
|
620
|
+
type?: string;
|
|
621
|
+
/** @deprecated Use 'objectData' instead */
|
|
622
|
+
data?: unknown;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Actions API for durable execution tracking
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* ```ts
|
|
629
|
+
* // Create an action with verb conjugation
|
|
630
|
+
* const action = await actions.create({
|
|
631
|
+
* actor: 'system',
|
|
632
|
+
* action: 'generate', // auto-conjugates to act='generates', activity='generating'
|
|
633
|
+
* object: 'Post',
|
|
634
|
+
* objectData: { count: 100 },
|
|
635
|
+
* total: 100,
|
|
636
|
+
* })
|
|
637
|
+
*
|
|
638
|
+
* // Update progress
|
|
639
|
+
* await actions.update(action.id, { progress: 50 })
|
|
640
|
+
*
|
|
641
|
+
* // Complete with result
|
|
642
|
+
* await actions.update(action.id, {
|
|
643
|
+
* status: 'completed',
|
|
644
|
+
* result: { created: 100 },
|
|
645
|
+
* })
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
export interface ActionsAPI {
|
|
649
|
+
/** Create a new action (auto-conjugates verb forms) */
|
|
650
|
+
create(options: CreateActionOptions): Promise<DBAction>;
|
|
651
|
+
/** Create with legacy format (deprecated) */
|
|
652
|
+
create(data: {
|
|
653
|
+
type: string;
|
|
654
|
+
data: unknown;
|
|
655
|
+
total?: number;
|
|
656
|
+
}): Promise<DBAction>;
|
|
657
|
+
/** Get an action by ID */
|
|
658
|
+
get(id: string): Promise<DBAction | null>;
|
|
659
|
+
/** Update action progress/status */
|
|
660
|
+
update(id: string, updates: Partial<Pick<DBAction, 'status' | 'progress' | 'result' | 'error'>>): Promise<DBAction>;
|
|
661
|
+
/** List actions with optional filters */
|
|
662
|
+
list(options?: {
|
|
663
|
+
status?: DBAction['status'];
|
|
664
|
+
action?: string;
|
|
665
|
+
actor?: string;
|
|
666
|
+
object?: string;
|
|
667
|
+
since?: Date;
|
|
668
|
+
until?: Date;
|
|
669
|
+
limit?: number;
|
|
670
|
+
/** @deprecated Use 'action' instead */
|
|
671
|
+
type?: string;
|
|
672
|
+
}): Promise<DBAction[]>;
|
|
673
|
+
/** Retry a failed action */
|
|
674
|
+
retry(id: string): Promise<DBAction>;
|
|
675
|
+
/** Cancel a pending/active action */
|
|
676
|
+
cancel(id: string): Promise<void>;
|
|
677
|
+
/** Conjugate a verb to get all forms */
|
|
678
|
+
conjugate(action: string): Verb;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Artifact data structure for cached content
|
|
682
|
+
*/
|
|
683
|
+
export interface DBArtifact {
|
|
684
|
+
url: string;
|
|
685
|
+
type: string;
|
|
686
|
+
sourceHash: string;
|
|
687
|
+
content: unknown;
|
|
688
|
+
metadata?: Record<string, unknown>;
|
|
689
|
+
createdAt: Date;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Artifacts API for cached embeddings and computed content
|
|
693
|
+
*/
|
|
694
|
+
export interface ArtifactsAPI {
|
|
695
|
+
/** Get an artifact by URL and type */
|
|
696
|
+
get(url: string, type: string): Promise<DBArtifact | null>;
|
|
697
|
+
/** Set an artifact */
|
|
698
|
+
set(url: string, type: string, data: {
|
|
699
|
+
content: unknown;
|
|
700
|
+
sourceHash: string;
|
|
701
|
+
metadata?: Record<string, unknown>;
|
|
702
|
+
}): Promise<void>;
|
|
703
|
+
/** Delete an artifact */
|
|
704
|
+
delete(url: string, type?: string): Promise<void>;
|
|
705
|
+
/** List artifacts for a URL */
|
|
706
|
+
list(url: string): Promise<DBArtifact[]>;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Nouns API for type introspection
|
|
710
|
+
*/
|
|
711
|
+
export interface NounsAPI {
|
|
712
|
+
/** Get a noun definition by type name */
|
|
713
|
+
get(name: string): Promise<Noun | null>;
|
|
714
|
+
/** List all noun definitions */
|
|
715
|
+
list(): Promise<Noun[]>;
|
|
716
|
+
/** Define a new noun */
|
|
717
|
+
define(noun: Noun): Promise<void>;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Verbs API for action introspection
|
|
721
|
+
*/
|
|
722
|
+
export interface VerbsAPI {
|
|
723
|
+
/** Get a verb definition by action name */
|
|
724
|
+
get(action: string): Verb | null;
|
|
725
|
+
/** List all verb definitions */
|
|
726
|
+
list(): Verb[];
|
|
727
|
+
/** Define a new verb */
|
|
728
|
+
define(verb: Verb): void;
|
|
729
|
+
/** Conjugate a verb from base form */
|
|
730
|
+
conjugate(action: string): Verb;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Result of DB() factory - supports both direct and destructured usage
|
|
734
|
+
*
|
|
735
|
+
* @example
|
|
736
|
+
* ```ts
|
|
737
|
+
* // Direct usage - everything on one object
|
|
738
|
+
* const db = DB(schema)
|
|
739
|
+
* db.User.create(...) // entity operations
|
|
740
|
+
* db.events.on(...) // events API
|
|
741
|
+
* db.actions.create(...) // actions API
|
|
742
|
+
*
|
|
743
|
+
* // Destructured usage - cleaner separation
|
|
744
|
+
* const { db, events, actions } = DB(schema)
|
|
745
|
+
* db.User.create(...) // just entity ops
|
|
746
|
+
* events.on(...) // separate events
|
|
747
|
+
* ```
|
|
748
|
+
*/
|
|
749
|
+
export type DBResult<TSchema extends DatabaseSchema> = TypedDB<TSchema> & {
|
|
750
|
+
/** Self-reference for destructuring - same as the parent object but cleaner semantically */
|
|
751
|
+
db: TypedDB<TSchema>;
|
|
752
|
+
/** Event subscription and emission */
|
|
753
|
+
events: EventsAPI;
|
|
754
|
+
/** Durable action execution */
|
|
755
|
+
actions: ActionsAPI;
|
|
756
|
+
/** Cached embeddings and computed content */
|
|
757
|
+
artifacts: ArtifactsAPI;
|
|
758
|
+
/** Type introspection */
|
|
759
|
+
nouns: NounsAPI;
|
|
760
|
+
/** Action introspection */
|
|
761
|
+
verbs: VerbsAPI;
|
|
762
|
+
};
|
|
763
|
+
/**
|
|
764
|
+
* AI generator function type for NL queries
|
|
765
|
+
* This is injected by the user or resolved from environment
|
|
766
|
+
*/
|
|
767
|
+
export type NLQueryGenerator = (prompt: string, context: NLQueryContext) => Promise<NLQueryPlan>;
|
|
768
|
+
/**
|
|
769
|
+
* Context provided to the AI for query generation
|
|
770
|
+
*/
|
|
771
|
+
export interface NLQueryContext {
|
|
772
|
+
/** Available types with their schemas */
|
|
773
|
+
types: Array<{
|
|
774
|
+
name: string;
|
|
775
|
+
singular: string;
|
|
776
|
+
plural: string;
|
|
777
|
+
fields: string[];
|
|
778
|
+
relationships: Array<{
|
|
779
|
+
name: string;
|
|
780
|
+
to: string;
|
|
781
|
+
cardinality: string;
|
|
782
|
+
}>;
|
|
783
|
+
}>;
|
|
784
|
+
/** The specific type being queried (if any) */
|
|
785
|
+
targetType?: string;
|
|
786
|
+
/** Recent events for context */
|
|
787
|
+
recentEvents?: Array<{
|
|
788
|
+
type: string;
|
|
789
|
+
timestamp: Date;
|
|
790
|
+
}>;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Query plan generated by AI
|
|
794
|
+
*/
|
|
795
|
+
export interface NLQueryPlan {
|
|
796
|
+
/** Types to query */
|
|
797
|
+
types: string[];
|
|
798
|
+
/** Filters to apply */
|
|
799
|
+
filters?: Record<string, unknown>;
|
|
800
|
+
/** Search terms */
|
|
801
|
+
search?: string;
|
|
802
|
+
/** Time range */
|
|
803
|
+
timeRange?: {
|
|
804
|
+
since?: Date;
|
|
805
|
+
until?: Date;
|
|
806
|
+
};
|
|
807
|
+
/** Relationships to follow */
|
|
808
|
+
include?: string[];
|
|
809
|
+
/** How to interpret results */
|
|
810
|
+
interpretation: string;
|
|
811
|
+
/** Confidence score */
|
|
812
|
+
confidence: number;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Set the AI generator for natural language queries
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```ts
|
|
819
|
+
* import { generate } from 'ai-functions'
|
|
820
|
+
*
|
|
821
|
+
* setNLQueryGenerator(async (prompt, context) => {
|
|
822
|
+
* return generate({
|
|
823
|
+
* prompt: `Given this schema: ${JSON.stringify(context.types)}
|
|
824
|
+
* Answer this question: ${prompt}
|
|
825
|
+
* Return a query plan as JSON.`,
|
|
826
|
+
* schema: NLQueryPlanSchema
|
|
827
|
+
* })
|
|
828
|
+
* })
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
831
|
+
export declare function setNLQueryGenerator(generator: NLQueryGenerator): void;
|
|
832
|
+
/**
|
|
833
|
+
* Database provider interface that adapters must implement
|
|
834
|
+
*/
|
|
835
|
+
export interface DBProvider {
|
|
836
|
+
/** Get an entity */
|
|
837
|
+
get(type: string, id: string): Promise<Record<string, unknown> | null>;
|
|
838
|
+
/** List entities */
|
|
839
|
+
list(type: string, options?: ListOptions): Promise<Record<string, unknown>[]>;
|
|
840
|
+
/** Search entities */
|
|
841
|
+
search(type: string, query: string, options?: SearchOptions): Promise<Record<string, unknown>[]>;
|
|
842
|
+
/** Create an entity */
|
|
843
|
+
create(type: string, id: string | undefined, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
844
|
+
/** Update an entity */
|
|
845
|
+
update(type: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
846
|
+
/** Delete an entity */
|
|
847
|
+
delete(type: string, id: string): Promise<boolean>;
|
|
848
|
+
/** Get related entities */
|
|
849
|
+
related(type: string, id: string, relation: string): Promise<Record<string, unknown>[]>;
|
|
850
|
+
/** Create a relationship */
|
|
851
|
+
relate(fromType: string, fromId: string, relation: string, toType: string, toId: string): Promise<void>;
|
|
852
|
+
/** Remove a relationship */
|
|
853
|
+
unrelate(fromType: string, fromId: string, relation: string, toType: string, toId: string): Promise<void>;
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Set the global database provider
|
|
857
|
+
*/
|
|
858
|
+
export declare function setProvider(provider: DBProvider): void;
|
|
859
|
+
/**
|
|
860
|
+
* Create a typed database from a schema definition
|
|
861
|
+
*
|
|
862
|
+
* Supports both direct usage and destructuring for flexibility:
|
|
863
|
+
*
|
|
864
|
+
* @example Direct usage - everything on one object
|
|
865
|
+
* ```ts
|
|
866
|
+
* const db = DB({
|
|
867
|
+
* Post: { title: 'string', author: 'Author.posts' },
|
|
868
|
+
* Author: { name: 'string' },
|
|
869
|
+
* })
|
|
870
|
+
*
|
|
871
|
+
* // Entity operations
|
|
872
|
+
* const post = await db.Post.create({ title: 'Hello' })
|
|
873
|
+
*
|
|
874
|
+
* // Events, actions, etc. are also available directly
|
|
875
|
+
* db.events.on('Post.created', (event) => console.log(event))
|
|
876
|
+
* db.actions.create({ type: 'generate', data: {} })
|
|
877
|
+
* ```
|
|
878
|
+
*
|
|
879
|
+
* @example Destructured usage - cleaner separation
|
|
880
|
+
* ```ts
|
|
881
|
+
* const { db, events, actions, artifacts, nouns, verbs } = DB({
|
|
882
|
+
* Post: { title: 'string', author: 'Author.posts' },
|
|
883
|
+
* Author: { name: 'string' },
|
|
884
|
+
* })
|
|
885
|
+
*
|
|
886
|
+
* // CRUD operations on db
|
|
887
|
+
* const post = await db.Post.create({ title: 'Hello' })
|
|
888
|
+
* await db.Post.update(post.$id, { title: 'Updated' })
|
|
889
|
+
*
|
|
890
|
+
* // Separate events API
|
|
891
|
+
* events.on('Post.created', (event) => console.log(event))
|
|
892
|
+
*
|
|
893
|
+
* // Separate actions API
|
|
894
|
+
* const action = await actions.create({ type: 'generate', data: {} })
|
|
895
|
+
* ```
|
|
896
|
+
*/
|
|
897
|
+
export declare function DB<TSchema extends DatabaseSchema>(schema: TSchema): DBResult<TSchema>;
|
|
898
|
+
export { parseSchema as parse };
|
|
899
|
+
//# sourceMappingURL=schema.d.ts.map
|