@maravilla-labs/types 0.2.4 → 0.3.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 (3) hide show
  1. package/index.d.ts +280 -51
  2. package/index.ts +77 -0
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -69,6 +69,75 @@ export interface KvStore {
69
69
  */
70
70
  list(namespace: string, options?: KvListRequest): Promise<KvListResponse>;
71
71
  }
72
+ /** MongoDB-style key direction: `1` ascending, `-1` descending. */
73
+ export type IndexDirection = 1 | -1;
74
+ /** Whether an index is a regular document index or a vector index. */
75
+ export type IndexKind = 'document' | 'vector';
76
+ export interface IndexSpec {
77
+ name?: string;
78
+ keys: Array<[string, IndexDirection]> | Record<string, IndexDirection>;
79
+ unique?: boolean;
80
+ sparse?: boolean;
81
+ partial?: Record<string, unknown>;
82
+ expireAfterSeconds?: number;
83
+ }
84
+ export interface IndexDescriptor {
85
+ collection: string;
86
+ name: string;
87
+ keys: Array<[string, IndexDirection]>;
88
+ unique: boolean;
89
+ sparse: boolean;
90
+ partial?: Record<string, unknown>;
91
+ expireAfterSeconds?: number;
92
+ kind: IndexKind;
93
+ }
94
+ /** Distance metric used to compare vectors. */
95
+ export type VectorMetric = 'cosine' | 'l2' | 'hamming';
96
+ /**
97
+ * On-disk storage precision for vectors.
98
+ * - `float32` (default): 4 bytes per dim
99
+ * - `int8`: 1 byte per dim, 4× smaller, typically <2% accuracy loss
100
+ * - `bit`: 1 bit per dim, 32× smaller; requires metric='hamming'
101
+ */
102
+ export type VectorStorage = 'float32' | 'int8' | 'bit';
103
+ /** Query shape: single vector or an array of vectors (ColBERT-style). */
104
+ export type VectorQueryMode = 'single' | 'late-interaction';
105
+ /** How multi-vector distances are aggregated per document. */
106
+ export type VectorAggregation = 'max-sim' | 'sum';
107
+ /** Spec used to declare a vector index on a collection field. */
108
+ export interface VectorIndexSpec {
109
+ field: string;
110
+ dimensions: number;
111
+ metric?: VectorMetric;
112
+ storage?: VectorStorage;
113
+ matryoshka?: boolean;
114
+ multiVector?: boolean;
115
+ }
116
+ /** Metadata for a registered vector index. */
117
+ export interface VectorIndexDescriptor {
118
+ collection: string;
119
+ field: string;
120
+ dimensions: number;
121
+ metric: VectorMetric;
122
+ storage: VectorStorage;
123
+ matryoshka: boolean;
124
+ multiVector: boolean;
125
+ }
126
+ /** Vector search clause riding inside DbFindOptions. */
127
+ export interface VectorQuery {
128
+ field: string;
129
+ value: number[] | number[][];
130
+ k: number;
131
+ metric?: VectorMetric;
132
+ minScore?: number;
133
+ queryMode?: VectorQueryMode;
134
+ aggregation?: VectorAggregation;
135
+ }
136
+ /** Document returned by a vector search with similarity metadata attached. */
137
+ export type VectorSearchHit = Record<string, any> & {
138
+ _score: number;
139
+ _distance: number;
140
+ };
72
141
  /**
73
142
  * Database find options
74
143
  */
@@ -77,6 +146,8 @@ export interface DbFindOptions {
77
146
  skip?: number;
78
147
  sort?: Record<string, 1 | -1>;
79
148
  projection?: Record<string, 1 | 0>;
149
+ /** Hybrid metadata + vector search clause. */
150
+ vector?: VectorQuery;
80
151
  }
81
152
  /**
82
153
  * Database collection interface
@@ -203,64 +274,180 @@ export interface Storage {
203
274
  */
204
275
  getMetadata(key: string): Promise<StorageMetadata>;
205
276
  }
206
- /**
207
- * Authenticated user record
208
- */
209
- export interface AuthUser {
277
+ /** Delegation mode for stewardship overrides */
278
+ export type DelegationMode = 'full' | 'scoped';
279
+ /** Status of a stewardship override */
280
+ export type StewardshipStatus = 'active' | 'suspended' | 'revoked' | 'expired';
281
+ /** A scoped permission entry */
282
+ export interface ScopedPermission {
283
+ /** Resource name */
284
+ resource: string;
285
+ /** Allowed actions on the resource */
286
+ actions: string[];
287
+ }
288
+ /** A stewardship override record */
289
+ export interface StewardshipOverride {
290
+ id: string;
291
+ steward_id: string;
292
+ ward_id: string;
293
+ delegation_mode: DelegationMode;
294
+ scoped_permissions: ScopedPermission[];
295
+ valid_from?: number;
296
+ valid_until?: number;
297
+ status: StewardshipStatus;
298
+ reason?: string;
299
+ source: string;
300
+ source_circle_id?: string;
301
+ source_relation_type_id?: string;
302
+ created_at: number;
303
+ updated_at: number;
304
+ }
305
+ /** Options for creating a stewardship override */
306
+ export interface CreateStewardshipOverrideRequest {
307
+ steward_id: string;
308
+ ward_id: string;
309
+ delegation_mode?: DelegationMode;
310
+ scoped_permissions?: ScopedPermission[];
311
+ valid_from?: number;
312
+ valid_until?: number;
313
+ reason?: string;
314
+ }
315
+ /** Result of resolving stewardship for a user */
316
+ export interface StewardshipResolution {
317
+ /** Users who are stewards of this user */
318
+ stewards: StewardshipOverride[];
319
+ /** Users this user is a steward of */
320
+ wards: StewardshipOverride[];
321
+ }
322
+ /** Context for acting as another user */
323
+ export interface ActAsContext {
324
+ steward_id: string;
325
+ ward_id: string;
326
+ delegation_mode: DelegationMode;
327
+ scoped_permissions: ScopedPermission[];
328
+ session_token: string;
329
+ expires_at: number;
330
+ }
331
+ /** An entry in the stewardship audit log */
332
+ export interface StewardshipAuditEntry {
333
+ id: string;
334
+ performed_by: string;
335
+ on_behalf_of: string;
336
+ action: string;
337
+ resource?: string;
338
+ details?: Record<string, any>;
339
+ created_at: number;
340
+ }
341
+ /** Options for listing audit log entries */
342
+ export interface AuditListOptions {
343
+ limit?: number;
344
+ offset?: number;
345
+ }
346
+ /** Stewardship service interface */
347
+ export interface Stewardship {
348
+ resolve(userId: string): Promise<StewardshipResolution>;
349
+ createOverride(options: CreateStewardshipOverrideRequest): Promise<StewardshipOverride>;
350
+ revoke(id: string): Promise<void>;
351
+ checkPermission(stewardId: string, wardId: string, resource: string, action: string): Promise<boolean>;
352
+ createActAs(stewardId: string, wardId: string): Promise<ActAsContext>;
353
+ listAudit(userId: string, options?: AuditListOptions): Promise<StewardshipAuditEntry[]>;
354
+ }
355
+ /** A platform resource definition */
356
+ export interface Resource {
210
357
  id: string;
358
+ resource_name: string;
359
+ title: string;
360
+ description?: string;
361
+ actions: string[];
362
+ created_at: number;
363
+ updated_at: number;
364
+ }
365
+ /** Options for creating a resource */
366
+ export interface CreateResourceRequest {
367
+ resource_name: string;
368
+ title: string;
369
+ description?: string;
370
+ actions?: string[];
371
+ }
372
+ /** Circle membership entry */
373
+ export interface CircleMembership {
374
+ user_id: string;
211
375
  email: string;
212
- email_verified: boolean;
213
- status: 'active' | 'suspended' | 'deactivated';
214
- provider: string;
215
- groups: string[];
376
+ relationship: string;
377
+ is_primary_contact: boolean;
378
+ joined_at: number;
379
+ }
380
+ /** A circle */
381
+ export interface Circle {
382
+ id: string;
383
+ name: string;
384
+ metadata?: Record<string, any>;
385
+ member_count: number;
216
386
  created_at: number;
217
387
  updated_at: number;
218
- last_login_at?: number;
219
388
  }
220
-
221
- /**
222
- * Session returned after login or refresh
223
- */
224
- export interface AuthSession {
225
- access_token: string;
226
- refresh_token: string;
227
- expires_in: number;
228
- user: AuthUser;
389
+ /** State of a workflow run. */
390
+ export type WorkflowRunStatus = 'queued' | 'running' | 'sleeping' | 'waiting_event' | 'completed' | 'failed' | 'cancelled';
391
+ /** Kind of a recorded step. */
392
+ export type WorkflowStepKind = 'run' | 'sleep' | 'wait_event' | 'ai' | 'mcp' | 'invoke';
393
+ export interface WorkflowRun {
394
+ runId: string;
395
+ workflowId: string;
396
+ projectId?: string;
397
+ deploymentId: string;
398
+ input: unknown;
399
+ status: WorkflowRunStatus;
400
+ attempt: number;
401
+ createdAt: number;
402
+ updatedAt: number;
403
+ completedAt?: number;
404
+ output?: unknown;
405
+ error?: unknown;
229
406
  }
230
-
231
- /**
232
- * Custom registration field
233
- */
234
- export interface AuthField {
235
- key: string;
236
- label: string;
237
- field_type: string;
238
- required: boolean;
239
- show_on_register: boolean;
407
+ export interface WorkflowStepRecord {
408
+ name: string;
409
+ kind: WorkflowStepKind;
410
+ status: 'pending' | 'completed' | 'failed';
411
+ output?: unknown;
412
+ error?: unknown;
413
+ startedAt: number;
414
+ completedAt?: number;
415
+ wakeAt?: number;
240
416
  }
241
-
242
417
  /**
243
- * Auth service for end-user authentication
418
+ * Handle returned by `platform.workflows.start()` — lets callers poll
419
+ * status, await the final result, cancel, or signal an event.
244
420
  */
245
- export interface AuthService {
246
- register(options: { email: string; password: string; profile?: Record<string, any> }): Promise<AuthUser>;
247
- login(options: { email: string; password: string }): Promise<AuthSession>;
248
- validate(accessToken: string): Promise<AuthUser>;
249
- refresh(refreshToken: string): Promise<AuthSession>;
250
- logout(sessionId: string): Promise<void>;
251
- getUser(userId: string): Promise<AuthUser | null>;
252
- listUsers(filter?: { limit?: number; offset?: number; status?: string; email_contains?: string }): Promise<{ users: AuthUser[]; total: number; limit: number; offset: number }>;
253
- updateUser(userId: string, update: { email?: string; status?: string; profile?: Record<string, any> }): Promise<AuthUser>;
254
- deleteUser(userId: string): Promise<void>;
255
- sendVerification(userId: string): Promise<{ token: string }>;
256
- verifyEmail(token: string): Promise<void>;
257
- sendPasswordReset(email: string): Promise<{ token: string }>;
258
- resetPassword(token: string, newPassword: string): Promise<void>;
259
- changePassword(userId: string, oldPassword: string, newPassword: string): Promise<void>;
260
- getFieldConfig(): Promise<{ fields: AuthField[] }>;
261
- withAuth<T extends (request: Request & { user: AuthUser }) => Promise<Response>>(handler: T): (request: Request) => Promise<Response>;
262
- }
263
-
421
+ export interface WorkflowHandle {
422
+ /** The run's unique id. */
423
+ readonly runId: string;
424
+ /** Current run record, or null if the run doesn't exist. */
425
+ status(): Promise<WorkflowRun | null>;
426
+ /** Full step history — useful for debugging. */
427
+ history(): Promise<WorkflowStepRecord[]>;
428
+ /**
429
+ * Wait for the run to reach a terminal state and return its output.
430
+ * Throws if the run ended in `failed` or `cancelled`.
431
+ */
432
+ result(options?: {
433
+ timeoutMs?: number;
434
+ }): Promise<unknown>;
435
+ /** Best-effort cancellation. Returns `true` if it transitioned. */
436
+ cancel(): Promise<boolean>;
437
+ }
438
+ export interface Workflows {
439
+ /** Start a new run of the workflow with the given input. */
440
+ start(workflowId: string, input?: unknown): Promise<WorkflowHandle>;
441
+ /** Get a handle to an existing run without starting one. */
442
+ handle(runId: string): WorkflowHandle;
443
+ /**
444
+ * Signal an event to any runs paused on `step.waitForEvent`. Returns
445
+ * the number of runs resolved. Matching rules: `eventType` must equal
446
+ * the filter's `type` (if set); each key in the filter's `match`
447
+ * must be present in `payload` with an equal value.
448
+ */
449
+ sendEvent(eventType: string, payload?: unknown): Promise<number>;
450
+ }
264
451
  /**
265
452
  * Main platform interface available in runtime
266
453
  */
@@ -271,8 +458,50 @@ export interface Platform {
271
458
  db: Database;
272
459
  /** Storage service instance */
273
460
  storage: Storage;
274
- /** Auth service for end-user authentication */
275
- auth: AuthService;
461
+ /** Durable multi-step workflows */
462
+ workflows: Workflows;
463
+ /** Auth service with stewardship, resources, and circle helpers */
464
+ auth: {
465
+ register(options: {
466
+ email: string;
467
+ password: string;
468
+ profile?: Record<string, any>;
469
+ }): Promise<any>;
470
+ login(options: {
471
+ email: string;
472
+ password: string;
473
+ }): Promise<any>;
474
+ validate(accessToken: string): Promise<any>;
475
+ refresh(refreshToken: string): Promise<any>;
476
+ logout(sessionId: string): Promise<void>;
477
+ getUser(userId: string): Promise<any>;
478
+ listUsers(filter?: Record<string, any>): Promise<any>;
479
+ updateUser(userId: string, update: Record<string, any>): Promise<any>;
480
+ deleteUser(userId: string): Promise<void>;
481
+ sendVerification(userId: string): Promise<any>;
482
+ verifyEmail(token: string): Promise<void>;
483
+ sendPasswordReset(email: string): Promise<any>;
484
+ resetPassword(token: string, newPassword: string): Promise<void>;
485
+ changePassword(userId: string, oldPassword: string, newPassword: string): Promise<void>;
486
+ getFieldConfig(): Promise<any>;
487
+ getOAuthUrl(provider: string, options?: {
488
+ redirectUri?: string;
489
+ }): Promise<any>;
490
+ handleOAuthCallback(provider: string, params: {
491
+ code: string;
492
+ state: string;
493
+ }): Promise<any>;
494
+ /** Stewardship (guardian/ward delegation) */
495
+ stewardship: Stewardship;
496
+ /** List available resources */
497
+ listResources(): Promise<Resource[]>;
498
+ /** Create a resource definition */
499
+ createResource(options: CreateResourceRequest): Promise<Resource>;
500
+ /** Get circle members */
501
+ getCircleMembers(circleId: string): Promise<CircleMembership[]>;
502
+ /** Get circles a user belongs to */
503
+ getUserCircles(userId: string): Promise<Circle[]>;
504
+ };
276
505
  /** Legacy aliases for compatibility */
277
506
  env: {
278
507
  KV: KvStore;
package/index.ts CHANGED
@@ -451,6 +451,81 @@ export interface Circle {
451
451
 
452
452
  // Platform Types
453
453
 
454
+ // --- Workflows ---
455
+
456
+ /** State of a workflow run. */
457
+ export type WorkflowRunStatus =
458
+ | 'queued'
459
+ | 'running'
460
+ | 'sleeping'
461
+ | 'waiting_event'
462
+ | 'completed'
463
+ | 'failed'
464
+ | 'cancelled';
465
+
466
+ /** Kind of a recorded step. */
467
+ export type WorkflowStepKind = 'run' | 'sleep' | 'wait_event' | 'ai' | 'mcp' | 'invoke';
468
+
469
+ export interface WorkflowRun {
470
+ runId: string;
471
+ workflowId: string;
472
+ projectId?: string;
473
+ deploymentId: string;
474
+ input: unknown;
475
+ status: WorkflowRunStatus;
476
+ attempt: number;
477
+ createdAt: number;
478
+ updatedAt: number;
479
+ completedAt?: number;
480
+ output?: unknown;
481
+ error?: unknown;
482
+ }
483
+
484
+ export interface WorkflowStepRecord {
485
+ name: string;
486
+ kind: WorkflowStepKind;
487
+ status: 'pending' | 'completed' | 'failed';
488
+ output?: unknown;
489
+ error?: unknown;
490
+ startedAt: number;
491
+ completedAt?: number;
492
+ wakeAt?: number;
493
+ }
494
+
495
+ /**
496
+ * Handle returned by `platform.workflows.start()` — lets callers poll
497
+ * status, await the final result, cancel, or signal an event.
498
+ */
499
+ export interface WorkflowHandle {
500
+ /** The run's unique id. */
501
+ readonly runId: string;
502
+ /** Current run record, or null if the run doesn't exist. */
503
+ status(): Promise<WorkflowRun | null>;
504
+ /** Full step history — useful for debugging. */
505
+ history(): Promise<WorkflowStepRecord[]>;
506
+ /**
507
+ * Wait for the run to reach a terminal state and return its output.
508
+ * Throws if the run ended in `failed` or `cancelled`.
509
+ */
510
+ result(options?: { timeoutMs?: number }): Promise<unknown>;
511
+ /** Best-effort cancellation. Returns `true` if it transitioned. */
512
+ cancel(): Promise<boolean>;
513
+ }
514
+
515
+ export interface Workflows {
516
+ /** Start a new run of the workflow with the given input. */
517
+ start(workflowId: string, input?: unknown): Promise<WorkflowHandle>;
518
+ /** Get a handle to an existing run without starting one. */
519
+ handle(runId: string): WorkflowHandle;
520
+ /**
521
+ * Signal an event to any runs paused on `step.waitForEvent`. Returns
522
+ * the number of runs resolved. Matching rules: `eventType` must equal
523
+ * the filter's `type` (if set); each key in the filter's `match`
524
+ * must be present in `payload` with an equal value.
525
+ */
526
+ sendEvent(eventType: string, payload?: unknown): Promise<number>;
527
+ }
528
+
454
529
  /**
455
530
  * Main platform interface available in runtime
456
531
  */
@@ -461,6 +536,8 @@ export interface Platform {
461
536
  db: Database;
462
537
  /** Storage service instance */
463
538
  storage: Storage;
539
+ /** Durable multi-step workflows */
540
+ workflows: Workflows;
464
541
  /** Auth service with stewardship, resources, and circle helpers */
465
542
  auth: {
466
543
  register(options: { email: string; password: string; profile?: Record<string, any> }): Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maravilla-labs/types",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript definitions for Maravilla Runtime platform APIs",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",