@valon-technologies/gestalt 0.0.1-alpha.1 → 0.0.1-alpha.9

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/src/index.ts CHANGED
@@ -1,3 +1,33 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Authored TypeScript APIs for building Gestalt providers, helper CLIs, and
5
+ * runtime adapters.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { definePlugin, ok, operation, s } from "@valon-technologies/gestalt";
10
+ *
11
+ * export const plugin = definePlugin({
12
+ * displayName: "Example Provider",
13
+ * operations: [
14
+ * operation({
15
+ * id: "hello",
16
+ * input: s.object({ name: s.string({ default: "World" }) }),
17
+ * output: s.object({ message: s.string() }),
18
+ * async handler(input) {
19
+ * return ok({ message: `Hello, ${input.name}` });
20
+ * },
21
+ * }),
22
+ * ],
23
+ * });
24
+ * ```
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { parseRuntimeArgs, serve } from "@valon-technologies/gestalt/runtime";
29
+ * ```
30
+ */
1
31
  export {
2
32
  connectionParam,
3
33
  ok,
@@ -24,18 +54,34 @@ export {
24
54
  type CatalogSchema,
25
55
  } from "./catalog.ts";
26
56
  export {
27
- buildPluginBinary,
28
57
  buildProviderBinary,
29
58
  bunBuildCommand,
30
59
  bunTarget,
31
60
  parseBuildArgs,
32
61
  } from "./build.ts";
33
62
  export {
34
- defineAuthProvider,
35
- isAuthProvider,
63
+ ENV_PLUGIN_INVOKER_SOCKET,
64
+ PluginInvoker,
65
+ type PluginInvokeOptions,
66
+ } from "./invoker.ts";
67
+ export {
68
+ ENV_WORKFLOW_MANAGER_SOCKET,
69
+ WorkflowManager,
70
+ type ManagedWorkflowScheduleMessage,
71
+ type WorkflowManagerCreateScheduleInput,
72
+ type WorkflowManagerDeleteScheduleInput,
73
+ type WorkflowManagerGetScheduleInput,
74
+ type WorkflowManagerPauseScheduleInput,
75
+ type WorkflowManagerResumeScheduleInput,
76
+ type WorkflowManagerUpdateScheduleInput,
77
+ } from "./workflow-manager.ts";
78
+ export {
79
+ AuthenticationProvider,
80
+ defineAuthenticationProvider,
81
+ isAuthenticationProvider,
36
82
  type AuthenticatedUser,
37
- type AuthProviderOptions,
38
- type AuthSessionSettings,
83
+ type AuthenticationProviderOptions,
84
+ type AuthenticationSessionSettings,
39
85
  type BeginLoginRequest,
40
86
  type BeginLoginResponse,
41
87
  type CompleteLoginRequest,
@@ -56,16 +102,14 @@ export {
56
102
  type SecretsProviderOptions,
57
103
  } from "./secrets.ts";
58
104
  export {
59
- Plugin,
105
+ PluginProvider,
60
106
  connectionModeToProtoValue,
61
107
  connectionParamToProto,
62
- defineIntegrationProvider,
63
108
  definePlugin,
64
- isIntegrationProvider,
109
+ isPluginProvider,
65
110
  operation,
66
111
  type ConnectionMode,
67
112
  type ConnectionParamDefinition,
68
- type IntegrationProviderOptions,
69
113
  type OperationDefinition,
70
114
  type OperationOptions,
71
115
  type PluginDefinitionOptions,
@@ -102,34 +146,26 @@ export {
102
146
  ENV_PROVIDER_PARENT_PID,
103
147
  ENV_PROVIDER_SOCKET,
104
148
  ENV_WRITE_CATALOG,
105
- createAuthService,
149
+ createAuthenticationService,
106
150
  createCacheService,
107
151
  createSecretsService,
108
152
  createProviderService,
109
153
  createRuntimeService,
110
- loadPluginFromTarget,
111
154
  loadProviderFromTarget,
112
155
  main as runtimeMain,
113
156
  parseRuntimeArgs,
114
- pluginCatalogYaml,
115
- runBundledPlugin,
116
157
  runBundledProvider,
117
- runLoadedPlugin,
118
158
  runLoadedProvider,
119
159
  serve,
120
160
  } from "./runtime.ts";
121
161
  export {
122
- defaultPluginName,
123
162
  defaultProviderName,
124
163
  formatModuleTarget,
125
164
  formatProviderTarget,
126
165
  parseModuleTarget,
127
166
  parseProviderTarget,
128
167
  readPackageConfig,
129
- readPackagePluginTarget,
130
168
  readPackageProviderTarget,
131
- resolvePluginImportUrl,
132
- resolvePluginModulePath,
133
169
  resolveProviderImportUrl,
134
170
  resolveProviderModulePath,
135
171
  type ModuleTarget,
@@ -180,3 +216,36 @@ export {
180
216
  type S3ProviderOptions,
181
217
  type WriteOptions,
182
218
  } from "./s3.ts";
219
+ export {
220
+ ENV_WORKFLOW_HOST_SOCKET,
221
+ WorkflowHost,
222
+ WorkflowProvider,
223
+ WorkflowRunStatus,
224
+ createWorkflowProviderService,
225
+ defineWorkflowProvider,
226
+ isWorkflowProvider,
227
+ type BoundWorkflowEventTrigger,
228
+ type BoundWorkflowRun,
229
+ type BoundWorkflowSchedule,
230
+ type CancelWorkflowProviderRunRequest,
231
+ type DeleteWorkflowProviderEventTriggerRequest,
232
+ type DeleteWorkflowProviderScheduleRequest,
233
+ type GetWorkflowProviderEventTriggerRequest,
234
+ type GetWorkflowProviderRunRequest,
235
+ type GetWorkflowProviderScheduleRequest,
236
+ type InvokeWorkflowOperationRequest,
237
+ type InvokeWorkflowOperationResponse,
238
+ type ListWorkflowProviderEventTriggersRequest,
239
+ type ListWorkflowProviderRunsRequest,
240
+ type ListWorkflowProviderSchedulesRequest,
241
+ type PauseWorkflowProviderEventTriggerRequest,
242
+ type PauseWorkflowProviderScheduleRequest,
243
+ type PublishWorkflowProviderEventRequest,
244
+ type ResumeWorkflowProviderEventTriggerRequest,
245
+ type ResumeWorkflowProviderScheduleRequest,
246
+ type StartWorkflowProviderRunRequest,
247
+ type UpsertWorkflowProviderEventTriggerRequest,
248
+ type UpsertWorkflowProviderScheduleRequest,
249
+ type WorkflowEvent,
250
+ type WorkflowProviderOptions,
251
+ } from "./workflow.ts";
package/src/indexeddb.ts CHANGED
@@ -7,6 +7,9 @@ import {
7
7
 
8
8
  const ENV_INDEXEDDB_SOCKET = "GESTALT_INDEXEDDB_SOCKET";
9
9
 
10
+ /**
11
+ * Returns the environment variable name used to discover an IndexedDB socket.
12
+ */
10
13
  export function indexedDBSocketEnv(name?: string): string {
11
14
  const trimmed = name?.trim() ?? "";
12
15
  if (!trimmed) return ENV_INDEXEDDB_SOCKET;
@@ -64,6 +67,9 @@ class AsyncQueue<T> implements AsyncIterable<T> {
64
67
  }
65
68
  }
66
69
 
70
+ /**
71
+ * Cursor iteration direction.
72
+ */
67
73
  export enum CursorDirection {
68
74
  Next = 0,
69
75
  NextUnique = 1,
@@ -78,11 +84,17 @@ const CURSOR_DIRECTION_TO_PROTO: { [K in CursorDirection]: ProtoCursorDirection
78
84
  [CursorDirection.PrevUnique]: ProtoCursorDirection.CURSOR_PREV_UNIQUE,
79
85
  };
80
86
 
87
+ /**
88
+ * Options for opening a cursor over an object store or index.
89
+ */
81
90
  export interface OpenCursorOptions {
82
91
  range?: KeyRange;
83
92
  direction?: CursorDirection;
84
93
  }
85
94
 
95
+ /**
96
+ * Streaming cursor over an object store or secondary index.
97
+ */
86
98
  export class Cursor {
87
99
  private sendQueue: AsyncQueue<any>;
88
100
  private responseIterator: AsyncIterator<any>;
@@ -103,6 +115,11 @@ export class Cursor {
103
115
  this._indexCursor = indexCursor;
104
116
  }
105
117
 
118
+ /**
119
+ * Opens a low-level cursor stream for object-store and index helpers.
120
+ *
121
+ * @internal
122
+ */
106
123
  static async open(
107
124
  client: Client<typeof IndexedDBService>,
108
125
  store: string,
@@ -135,22 +152,37 @@ export class Cursor {
135
152
  return cursor;
136
153
  }
137
154
 
155
+ /**
156
+ * Current cursor key.
157
+ */
138
158
  get key(): unknown {
139
159
  return this._key;
140
160
  }
141
161
 
162
+ /**
163
+ * Current primary key for the pointed record.
164
+ */
142
165
  get primaryKey(): string {
143
166
  return this._primaryKey;
144
167
  }
145
168
 
169
+ /**
170
+ * Current record value.
171
+ */
146
172
  get value(): Record | undefined {
147
173
  return this._value;
148
174
  }
149
175
 
176
+ /**
177
+ * Whether the cursor has reached the end of the stream.
178
+ */
150
179
  get done(): boolean {
151
180
  return this._done;
152
181
  }
153
182
 
183
+ /**
184
+ * Advances the cursor to the next entry.
185
+ */
154
186
  async continue(): Promise<boolean> {
155
187
  this.sendQueue.push({
156
188
  msg: { case: "command" as const, value: { command: { case: "next" as const, value: true } } },
@@ -158,6 +190,9 @@ export class Cursor {
158
190
  return this.pull();
159
191
  }
160
192
 
193
+ /**
194
+ * Advances the cursor to a specific key.
195
+ */
161
196
  async continueToKey(key: unknown): Promise<boolean> {
162
197
  this.sendQueue.push({
163
198
  msg: {
@@ -173,6 +208,9 @@ export class Cursor {
173
208
  return this.pull();
174
209
  }
175
210
 
211
+ /**
212
+ * Advances the cursor by `count` entries.
213
+ */
176
214
  async advance(count: number): Promise<boolean> {
177
215
  this.sendQueue.push({
178
216
  msg: {
@@ -183,6 +221,9 @@ export class Cursor {
183
221
  return this.pull();
184
222
  }
185
223
 
224
+ /**
225
+ * Deletes the current entry.
226
+ */
186
227
  async delete(): Promise<void> {
187
228
  if (this._done) throw new NotFoundError("cursor is exhausted");
188
229
  this.sendQueue.push({
@@ -194,6 +235,9 @@ export class Cursor {
194
235
  await this.recvMutationAck();
195
236
  }
196
237
 
238
+ /**
239
+ * Updates the current entry with a replacement record.
240
+ */
197
241
  async update(record: Record): Promise<void> {
198
242
  if (this._done) throw new NotFoundError("cursor is exhausted");
199
243
  this.sendQueue.push({
@@ -205,6 +249,9 @@ export class Cursor {
205
249
  await this.recvMutationAck();
206
250
  }
207
251
 
252
+ /**
253
+ * Closes the cursor stream.
254
+ */
208
255
  close(): void {
209
256
  this.sendQueue.push({
210
257
  msg: {
@@ -310,6 +357,9 @@ export class Cursor {
310
357
  }
311
358
  }
312
359
 
360
+ /**
361
+ * Error returned when an IndexedDB record cannot be found.
362
+ */
313
363
  export class NotFoundError extends Error {
314
364
  constructor(message?: string) {
315
365
  super(message ?? "not found");
@@ -317,6 +367,9 @@ export class NotFoundError extends Error {
317
367
  }
318
368
  }
319
369
 
370
+ /**
371
+ * Error returned when a write conflicts with an existing unique value.
372
+ */
320
373
  export class AlreadyExistsError extends Error {
321
374
  constructor(message?: string) {
322
375
  super(message ?? "already exists");
@@ -324,8 +377,14 @@ export class AlreadyExistsError extends Error {
324
377
  }
325
378
  }
326
379
 
380
+ /**
381
+ * Plain object record stored in IndexedDB.
382
+ */
327
383
  export type Record = { [key: string]: unknown };
328
384
 
385
+ /**
386
+ * Key range used to filter object store and index operations.
387
+ */
329
388
  export interface KeyRange {
330
389
  lower?: unknown;
331
390
  upper?: unknown;
@@ -333,12 +392,18 @@ export interface KeyRange {
333
392
  upperOpen?: boolean;
334
393
  }
335
394
 
395
+ /**
396
+ * Secondary index definition for an object store.
397
+ */
336
398
  export interface IndexSchema {
337
399
  name: string;
338
400
  keyPath: string[];
339
401
  unique?: boolean;
340
402
  }
341
403
 
404
+ /**
405
+ * Column type metadata used by the datastore schema.
406
+ */
342
407
  export enum ColumnType {
343
408
  String = 0,
344
409
  Int = 1,
@@ -349,6 +414,9 @@ export enum ColumnType {
349
414
  JSON = 6,
350
415
  }
351
416
 
417
+ /**
418
+ * Column definition for an object store schema.
419
+ */
352
420
  export interface ColumnSchema {
353
421
  name: string;
354
422
  type?: ColumnType;
@@ -357,11 +425,25 @@ export interface ColumnSchema {
357
425
  unique?: boolean;
358
426
  }
359
427
 
428
+ /**
429
+ * Object store schema used during store creation.
430
+ */
360
431
  export interface ObjectStoreSchema {
361
432
  indexes?: IndexSchema[];
362
433
  columns?: ColumnSchema[];
363
434
  }
364
435
 
436
+ /**
437
+ * Client for invoking a host-provided IndexedDB service over the Gestalt transport.
438
+ *
439
+ * @example
440
+ * ```ts
441
+ * import { IndexedDB } from "@valon-technologies/gestalt";
442
+ *
443
+ * const db = new IndexedDB();
444
+ * const todos = db.objectStore("todos");
445
+ * ```
446
+ */
365
447
  export class IndexedDB {
366
448
  private client: Client<typeof IndexedDBService>;
367
449
 
@@ -378,6 +460,9 @@ export class IndexedDB {
378
460
  this.client = createClient(IndexedDBService, transport);
379
461
  }
380
462
 
463
+ /**
464
+ * Creates an object store.
465
+ */
381
466
  async createObjectStore(name: string, schema?: ObjectStoreSchema): Promise<void> {
382
467
  await this.client.createObjectStore({
383
468
  name,
@@ -398,47 +483,80 @@ export class IndexedDB {
398
483
  });
399
484
  }
400
485
 
486
+ /**
487
+ * Deletes an object store.
488
+ */
401
489
  async deleteObjectStore(name: string): Promise<void> {
402
490
  await this.client.deleteObjectStore({ name });
403
491
  }
404
492
 
493
+ /**
494
+ * Returns a client bound to a single object store.
495
+ */
405
496
  objectStore(name: string): ObjectStore {
406
497
  return new ObjectStore(this.client, name);
407
498
  }
408
499
  }
409
500
 
501
+ /**
502
+ * Object store client used for primary-key operations.
503
+ */
410
504
  export class ObjectStore {
505
+ /**
506
+ * @internal
507
+ */
411
508
  constructor(
412
509
  private client: Client<typeof IndexedDBService>,
413
510
  private store: string,
414
511
  ) {}
415
512
 
513
+ /**
514
+ * Reads a record by primary key.
515
+ */
416
516
  async get(id: string): Promise<Record> {
417
517
  const resp = await rpc(() => this.client.get({ store: this.store, id }));
418
518
  return fromProtoRecord(resp.record);
419
519
  }
420
520
 
521
+ /**
522
+ * Reads the generated primary key for a record.
523
+ */
421
524
  async getKey(id: string): Promise<string> {
422
525
  const resp = await rpc(() => this.client.getKey({ store: this.store, id }));
423
526
  return resp.key;
424
527
  }
425
528
 
529
+ /**
530
+ * Inserts a new record and fails if it already exists.
531
+ */
426
532
  async add(record: Record): Promise<void> {
427
533
  await rpc(() => this.client.add({ store: this.store, record: toProtoRecord(record) }));
428
534
  }
429
535
 
536
+ /**
537
+ * Inserts or replaces a record.
538
+ */
430
539
  async put(record: Record): Promise<void> {
431
540
  await rpc(() => this.client.put({ store: this.store, record: toProtoRecord(record) }));
432
541
  }
433
542
 
543
+ /**
544
+ * Deletes a record by primary key.
545
+ */
434
546
  async delete(id: string): Promise<void> {
435
547
  await rpc(() => this.client.delete({ store: this.store, id }));
436
548
  }
437
549
 
550
+ /**
551
+ * Removes all records from the object store.
552
+ */
438
553
  async clear(): Promise<void> {
439
554
  await this.client.clear({ store: this.store });
440
555
  }
441
556
 
557
+ /**
558
+ * Reads all records in the object store or within a key range.
559
+ */
442
560
  async getAll(keyRange?: KeyRange): Promise<Record[]> {
443
561
  const resp = await this.client.getAll({
444
562
  store: this.store,
@@ -447,6 +565,9 @@ export class ObjectStore {
447
565
  return resp.records.map((r) => fromProtoRecord(r));
448
566
  }
449
567
 
568
+ /**
569
+ * Reads all primary keys in the object store or within a key range.
570
+ */
450
571
  async getAllKeys(keyRange?: KeyRange): Promise<string[]> {
451
572
  const resp = await this.client.getAllKeys({
452
573
  store: this.store,
@@ -455,6 +576,9 @@ export class ObjectStore {
455
576
  return resp.keys;
456
577
  }
457
578
 
579
+ /**
580
+ * Counts records in the object store or within a key range.
581
+ */
458
582
  async count(keyRange?: KeyRange): Promise<number> {
459
583
  const resp = await this.client.count({
460
584
  store: this.store,
@@ -463,6 +587,9 @@ export class ObjectStore {
463
587
  return Number(resp.count);
464
588
  }
465
589
 
590
+ /**
591
+ * Deletes records within a key range.
592
+ */
466
593
  async deleteRange(keyRange: KeyRange): Promise<number> {
467
594
  const resp = await this.client.deleteRange({
468
595
  store: this.store,
@@ -471,26 +598,44 @@ export class ObjectStore {
471
598
  return Number(resp.deleted);
472
599
  }
473
600
 
601
+ /**
602
+ * Opens a cursor over the object store.
603
+ */
474
604
  async openCursor(options?: OpenCursorOptions): Promise<Cursor | null> {
475
605
  return Cursor.open(this.client, this.store, options);
476
606
  }
477
607
 
608
+ /**
609
+ * Opens a key-only cursor over the object store.
610
+ */
478
611
  async openKeyCursor(options?: OpenCursorOptions): Promise<Cursor | null> {
479
612
  return Cursor.open(this.client, this.store, { ...options, keysOnly: true });
480
613
  }
481
614
 
615
+ /**
616
+ * Returns a client bound to a secondary index.
617
+ */
482
618
  index(name: string): Index {
483
619
  return new Index(this.client, this.store, name);
484
620
  }
485
621
  }
486
622
 
623
+ /**
624
+ * Secondary-index client used for lookup and cursor operations.
625
+ */
487
626
  export class Index {
627
+ /**
628
+ * @internal
629
+ */
488
630
  constructor(
489
631
  private client: Client<typeof IndexedDBService>,
490
632
  private store: string,
491
633
  private indexName: string,
492
634
  ) {}
493
635
 
636
+ /**
637
+ * Reads the first record matching the supplied index values.
638
+ */
494
639
  async get(...values: unknown[]): Promise<Record> {
495
640
  const resp = await rpc(() =>
496
641
  this.client.indexGet({
@@ -502,6 +647,9 @@ export class Index {
502
647
  return fromProtoRecord(resp.record);
503
648
  }
504
649
 
650
+ /**
651
+ * Reads the primary key for the first matching index entry.
652
+ */
505
653
  async getKey(...values: unknown[]): Promise<string> {
506
654
  const resp = await rpc(() =>
507
655
  this.client.indexGetKey({
@@ -513,6 +661,9 @@ export class Index {
513
661
  return resp.key;
514
662
  }
515
663
 
664
+ /**
665
+ * Reads all records matching the supplied index values and optional range.
666
+ */
516
667
  async getAll(keyRange?: KeyRange, ...values: unknown[]): Promise<Record[]> {
517
668
  const resp = await this.client.indexGetAll({
518
669
  store: this.store,
@@ -523,6 +674,9 @@ export class Index {
523
674
  return resp.records.map((r) => fromProtoRecord(r));
524
675
  }
525
676
 
677
+ /**
678
+ * Reads all primary keys matching the supplied index values and optional range.
679
+ */
526
680
  async getAllKeys(keyRange?: KeyRange, ...values: unknown[]): Promise<string[]> {
527
681
  const resp = await this.client.indexGetAllKeys({
528
682
  store: this.store,
@@ -533,6 +687,9 @@ export class Index {
533
687
  return resp.keys;
534
688
  }
535
689
 
690
+ /**
691
+ * Counts records matching the supplied index values and optional range.
692
+ */
536
693
  async count(keyRange?: KeyRange, ...values: unknown[]): Promise<number> {
537
694
  const resp = await this.client.indexCount({
538
695
  store: this.store,
@@ -543,6 +700,9 @@ export class Index {
543
700
  return Number(resp.count);
544
701
  }
545
702
 
703
+ /**
704
+ * Deletes records matching the supplied index values.
705
+ */
546
706
  async delete(...values: unknown[]): Promise<number> {
547
707
  const resp = await this.client.indexDelete({
548
708
  store: this.store,
@@ -552,6 +712,9 @@ export class Index {
552
712
  return Number(resp.deleted);
553
713
  }
554
714
 
715
+ /**
716
+ * Opens a cursor over the index.
717
+ */
555
718
  async openCursor(options?: OpenCursorOptions, ...values: unknown[]): Promise<Cursor | null> {
556
719
  return Cursor.open(this.client, this.store, {
557
720
  ...options,
@@ -560,6 +723,9 @@ export class Index {
560
723
  });
561
724
  }
562
725
 
726
+ /**
727
+ * Opens a key-only cursor over the index.
728
+ */
563
729
  async openKeyCursor(options?: OpenCursorOptions, ...values: unknown[]): Promise<Cursor | null> {
564
730
  return Cursor.open(this.client, this.store, {
565
731
  ...options,