@workglow/storage 0.0.85 → 0.0.87

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 (108) hide show
  1. package/README.md +185 -53
  2. package/dist/browser.js +451 -188
  3. package/dist/browser.js.map +21 -18
  4. package/dist/bun.js +1069 -356
  5. package/dist/bun.js.map +29 -24
  6. package/dist/common-server.d.ts +17 -15
  7. package/dist/common-server.d.ts.map +1 -1
  8. package/dist/common.d.ts +13 -10
  9. package/dist/common.d.ts.map +1 -1
  10. package/dist/kv/{FsFolderJsonKvRepository.d.ts → FsFolderJsonKvStorage.d.ts} +8 -8
  11. package/dist/kv/FsFolderJsonKvStorage.d.ts.map +1 -0
  12. package/dist/kv/{FsFolderKvRepository.d.ts → FsFolderKvStorage.d.ts} +7 -7
  13. package/dist/kv/FsFolderKvStorage.d.ts.map +1 -0
  14. package/dist/kv/{IKvRepository.d.ts → IKvStorage.d.ts} +3 -3
  15. package/dist/kv/IKvStorage.d.ts.map +1 -0
  16. package/dist/kv/{InMemoryKvRepository.d.ts → InMemoryKvStorage.d.ts} +8 -8
  17. package/dist/kv/InMemoryKvStorage.d.ts.map +1 -0
  18. package/dist/kv/{IndexedDbKvRepository.d.ts → IndexedDbKvStorage.d.ts} +8 -8
  19. package/dist/kv/IndexedDbKvStorage.d.ts.map +1 -0
  20. package/dist/kv/{KvRepository.d.ts → KvStorage.d.ts} +7 -7
  21. package/dist/kv/KvStorage.d.ts.map +1 -0
  22. package/dist/kv/{KvViaTabularRepository.d.ts → KvViaTabularStorage.d.ts} +7 -7
  23. package/dist/kv/KvViaTabularStorage.d.ts.map +1 -0
  24. package/dist/kv/{PostgresKvRepository.d.ts → PostgresKvStorage.d.ts} +8 -8
  25. package/dist/kv/PostgresKvStorage.d.ts.map +1 -0
  26. package/dist/kv/{SqliteKvRepository.d.ts → SqliteKvStorage.d.ts} +8 -8
  27. package/dist/kv/SqliteKvStorage.d.ts.map +1 -0
  28. package/dist/kv/{SupabaseKvRepository.d.ts → SupabaseKvStorage.d.ts} +9 -9
  29. package/dist/kv/SupabaseKvStorage.d.ts.map +1 -0
  30. package/dist/node.js +1069 -356
  31. package/dist/node.js.map +29 -24
  32. package/dist/queue-limiter/IRateLimiterStorage.d.ts.map +1 -0
  33. package/dist/queue-limiter/InMemoryRateLimiterStorage.d.ts.map +1 -0
  34. package/dist/queue-limiter/IndexedDbRateLimiterStorage.d.ts.map +1 -0
  35. package/dist/queue-limiter/PostgresRateLimiterStorage.d.ts.map +1 -0
  36. package/dist/queue-limiter/SqliteRateLimiterStorage.d.ts.map +1 -0
  37. package/dist/queue-limiter/SupabaseRateLimiterStorage.d.ts.map +1 -0
  38. package/dist/tabular/{BaseSqlTabularRepository.d.ts → BaseSqlTabularStorage.d.ts} +8 -7
  39. package/dist/tabular/BaseSqlTabularStorage.d.ts.map +1 -0
  40. package/dist/tabular/{TabularRepository.d.ts → BaseTabularStorage.d.ts} +52 -10
  41. package/dist/tabular/BaseTabularStorage.d.ts.map +1 -0
  42. package/dist/tabular/{CachedTabularRepository.d.ts → CachedTabularStorage.d.ts} +15 -14
  43. package/dist/tabular/CachedTabularStorage.d.ts.map +1 -0
  44. package/dist/tabular/{FsFolderTabularRepository.d.ts → FsFolderTabularStorage.d.ts} +22 -12
  45. package/dist/tabular/FsFolderTabularStorage.d.ts.map +1 -0
  46. package/dist/tabular/{ITabularRepository.d.ts → ITabularStorage.d.ts} +29 -6
  47. package/dist/tabular/ITabularStorage.d.ts.map +1 -0
  48. package/dist/tabular/{InMemoryTabularRepository.d.ts → InMemoryTabularStorage.d.ts} +24 -14
  49. package/dist/tabular/InMemoryTabularStorage.d.ts.map +1 -0
  50. package/dist/tabular/{IndexedDbTabularRepository.d.ts → IndexedDbTabularStorage.d.ts} +20 -11
  51. package/dist/tabular/IndexedDbTabularStorage.d.ts.map +1 -0
  52. package/dist/tabular/{PostgresTabularRepository.d.ts → PostgresTabularStorage.d.ts} +37 -15
  53. package/dist/tabular/PostgresTabularStorage.d.ts.map +1 -0
  54. package/dist/tabular/{SharedInMemoryTabularRepository.d.ts → SharedInMemoryTabularStorage.d.ts} +14 -13
  55. package/dist/tabular/SharedInMemoryTabularStorage.d.ts.map +1 -0
  56. package/dist/tabular/{SqliteTabularRepository.d.ts → SqliteTabularStorage.d.ts} +25 -11
  57. package/dist/tabular/SqliteTabularStorage.d.ts.map +1 -0
  58. package/dist/tabular/{SupabaseTabularRepository.d.ts → SupabaseTabularStorage.d.ts} +17 -15
  59. package/dist/tabular/SupabaseTabularStorage.d.ts.map +1 -0
  60. package/dist/tabular/TabularStorageRegistry.d.ts +29 -0
  61. package/dist/tabular/TabularStorageRegistry.d.ts.map +1 -0
  62. package/dist/util/IndexedDbTable.d.ts +1 -1
  63. package/dist/util/IndexedDbTable.d.ts.map +1 -1
  64. package/dist/vector/IVectorStorage.d.ts +83 -0
  65. package/dist/vector/IVectorStorage.d.ts.map +1 -0
  66. package/dist/vector/InMemoryVectorStorage.d.ts +41 -0
  67. package/dist/vector/InMemoryVectorStorage.d.ts.map +1 -0
  68. package/dist/vector/PostgresVectorStorage.d.ts +57 -0
  69. package/dist/vector/PostgresVectorStorage.d.ts.map +1 -0
  70. package/dist/vector/SqliteVectorStorage.d.ts +45 -0
  71. package/dist/vector/SqliteVectorStorage.d.ts.map +1 -0
  72. package/package.json +7 -7
  73. package/src/kv/README.md +3 -3
  74. package/src/tabular/README.md +186 -23
  75. package/src/vector/README.md +393 -0
  76. package/dist/kv/FsFolderJsonKvRepository.d.ts.map +0 -1
  77. package/dist/kv/FsFolderKvRepository.d.ts.map +0 -1
  78. package/dist/kv/IKvRepository.d.ts.map +0 -1
  79. package/dist/kv/InMemoryKvRepository.d.ts.map +0 -1
  80. package/dist/kv/IndexedDbKvRepository.d.ts.map +0 -1
  81. package/dist/kv/KvRepository.d.ts.map +0 -1
  82. package/dist/kv/KvViaTabularRepository.d.ts.map +0 -1
  83. package/dist/kv/PostgresKvRepository.d.ts.map +0 -1
  84. package/dist/kv/SqliteKvRepository.d.ts.map +0 -1
  85. package/dist/kv/SupabaseKvRepository.d.ts.map +0 -1
  86. package/dist/limiter/IRateLimiterStorage.d.ts.map +0 -1
  87. package/dist/limiter/InMemoryRateLimiterStorage.d.ts.map +0 -1
  88. package/dist/limiter/IndexedDbRateLimiterStorage.d.ts.map +0 -1
  89. package/dist/limiter/PostgresRateLimiterStorage.d.ts.map +0 -1
  90. package/dist/limiter/SqliteRateLimiterStorage.d.ts.map +0 -1
  91. package/dist/limiter/SupabaseRateLimiterStorage.d.ts.map +0 -1
  92. package/dist/tabular/BaseSqlTabularRepository.d.ts.map +0 -1
  93. package/dist/tabular/CachedTabularRepository.d.ts.map +0 -1
  94. package/dist/tabular/FsFolderTabularRepository.d.ts.map +0 -1
  95. package/dist/tabular/ITabularRepository.d.ts.map +0 -1
  96. package/dist/tabular/InMemoryTabularRepository.d.ts.map +0 -1
  97. package/dist/tabular/IndexedDbTabularRepository.d.ts.map +0 -1
  98. package/dist/tabular/PostgresTabularRepository.d.ts.map +0 -1
  99. package/dist/tabular/SharedInMemoryTabularRepository.d.ts.map +0 -1
  100. package/dist/tabular/SqliteTabularRepository.d.ts.map +0 -1
  101. package/dist/tabular/SupabaseTabularRepository.d.ts.map +0 -1
  102. package/dist/tabular/TabularRepository.d.ts.map +0 -1
  103. /package/dist/{limiter → queue-limiter}/IRateLimiterStorage.d.ts +0 -0
  104. /package/dist/{limiter → queue-limiter}/InMemoryRateLimiterStorage.d.ts +0 -0
  105. /package/dist/{limiter → queue-limiter}/IndexedDbRateLimiterStorage.d.ts +0 -0
  106. /package/dist/{limiter → queue-limiter}/PostgresRateLimiterStorage.d.ts +0 -0
  107. /package/dist/{limiter → queue-limiter}/SqliteRateLimiterStorage.d.ts +0 -0
  108. /package/dist/{limiter → queue-limiter}/SupabaseRateLimiterStorage.d.ts +0 -0
package/README.md CHANGED
@@ -28,12 +28,13 @@ Modular storage solutions for Workglow.AI platform with multiple backend impleme
28
28
  - [Node.js Environment](#nodejs-environment)
29
29
  - [Bun Environment](#bun-environment)
30
30
  - [Advanced Features](#advanced-features)
31
+ - [Repository Registry](#repository-registry)
31
32
  - [Event-Driven Architecture](#event-driven-architecture)
32
33
  - [Compound Primary Keys](#compound-primary-keys)
33
34
  - [Custom File Layout (KV on filesystem)](#custom-file-layout-kv-on-filesystem)
34
35
  - [API Reference](#api-reference)
35
- - [IKvRepository\<Key, Value\>](#ikvrepositorykey-value)
36
- - [ITabularRepository\<Schema, PrimaryKeyNames\>](#itabularrepositoryschema-primarykeynames)
36
+ - [IKvStorage\<Key, Value\>](#ikvrepositorykey-value)
37
+ - [ITabularStorage\<Schema, PrimaryKeyNames\>](#itabularrepositoryschema-primarykeynames)
37
38
  - [IQueueStorage\<Input, Output\>](#iqueuestorageinput-output)
38
39
  - [Examples](#examples)
39
40
  - [User Management System](#user-management-system)
@@ -46,16 +47,16 @@ Modular storage solutions for Workglow.AI platform with multiple backend impleme
46
47
 
47
48
  ```typescript
48
49
  // Key-Value Storage (simple data)
49
- import { InMemoryKvRepository } from "@workglow/storage";
50
+ import { InMemoryKvStorage } from "@workglow/storage";
50
51
 
51
- const kvStore = new InMemoryKvRepository<string, { name: string; age: number }>();
52
+ const kvStore = new InMemoryKvStorage<string, { name: string; age: number }>();
52
53
  await kvStore.put("user:123", { name: "Alice", age: 30 });
53
54
  const kvUser = await kvStore.get("user:123"); // { name: "Alice", age: 30 }
54
55
  ```
55
56
 
56
57
  ```typescript
57
58
  // Tabular Storage (structured data with schemas)
58
- import { InMemoryTabularRepository } from "@workglow/storage";
59
+ import { InMemoryTabularStorage } from "@workglow/storage";
59
60
  import { JsonSchema } from "@workglow/util";
60
61
 
61
62
  const userSchema = {
@@ -70,7 +71,7 @@ const userSchema = {
70
71
  additionalProperties: false,
71
72
  } as const satisfies JsonSchema;
72
73
 
73
- const userRepo = new InMemoryTabularRepository<typeof userSchema, ["id"]>(
74
+ const userRepo = new InMemoryTabularStorage<typeof userSchema, ["id"]>(
74
75
  userSchema,
75
76
  ["id"], // primary key
76
77
  ["email"] // additional indexes
@@ -138,7 +139,7 @@ The package uses conditional exports, so importing from `@workglow/storage` auto
138
139
 
139
140
  ```typescript
140
141
  // Import from the top-level package; it resolves to the correct target per environment
141
- import { InMemoryKvRepository, SqliteTabularRepository } from "@workglow/storage";
142
+ import { InMemoryKvStorage, SqliteTabularStorage } from "@workglow/storage";
142
143
  ```
143
144
 
144
145
  ## Storage Types
@@ -150,10 +151,10 @@ Simple key-value storage for unstructured or semi-structured data.
150
151
  #### Basic Usage
151
152
 
152
153
  ```typescript
153
- import { InMemoryKvRepository, FsFolderJsonKvRepository } from "@workglow/storage";
154
+ import { InMemoryKvStorage, FsFolderJsonKvRepository } from "@workglow/storage";
154
155
 
155
156
  // In-memory (for testing/caching)
156
- const cache = new InMemoryKvRepository<string, any>();
157
+ const cache = new InMemoryKvStorage<string, any>();
157
158
  await cache.put("config", { theme: "dark", language: "en" });
158
159
 
159
160
  // File-based JSON (persistent)
@@ -189,7 +190,7 @@ const supabaseStore = new SupabaseKvRepository(supabase, "settings");
189
190
  #### Bulk Operations
190
191
 
191
192
  ```typescript
192
- const store = new InMemoryKvRepository<string, { name: string; score: number }>();
193
+ const store = new InMemoryKvStorage<string, { name: string; score: number }>();
193
194
 
194
195
  // Bulk insert
195
196
  await store.putBulk([
@@ -208,7 +209,7 @@ const count = await store.size(); // 2
208
209
  #### Event Handling
209
210
 
210
211
  ```typescript
211
- const store = new InMemoryKvRepository<string, any>();
212
+ const store = new InMemoryKvStorage<string, any>();
212
213
 
213
214
  // Listen to storage events
214
215
  store.on("put", (key, value) => {
@@ -231,7 +232,7 @@ Structured storage with schemas, primary keys, and indexing for complex data rel
231
232
 
232
233
  ```typescript
233
234
  import { JsonSchema } from "@workglow/util";
234
- import { InMemoryTabularRepository } from "@workglow/storage";
235
+ import { InMemoryTabularStorage } from "@workglow/storage";
235
236
 
236
237
  // Define your entity schema
237
238
  const UserSchema = {
@@ -249,13 +250,59 @@ const UserSchema = {
249
250
  } as const satisfies JsonSchema;
250
251
 
251
252
  // Create repository with primary key and indexes
252
- const userRepo = new InMemoryTabularRepository<typeof UserSchema, ["id"]>(
253
+ const userRepo = new InMemoryTabularStorage<typeof UserSchema, ["id"]>(
253
254
  UserSchema,
254
255
  ["id"], // Primary key (can be compound: ["dept", "id"])
255
256
  ["email", "department", ["department", "age"]] // Indexes for fast lookups
256
257
  );
257
258
  ```
258
259
 
260
+ #### Auto-Generated Primary Keys
261
+
262
+ TabularStorage supports automatic ID generation by marking schema properties with `x-auto-generated: true`:
263
+
264
+ ```typescript
265
+ const UserSchema = {
266
+ type: "object",
267
+ properties: {
268
+ id: { type: "integer", "x-auto-generated": true }, // Auto-increment
269
+ name: { type: "string" },
270
+ email: { type: "string" },
271
+ },
272
+ required: ["id", "name", "email"],
273
+ } as const;
274
+
275
+ const storage = new PostgresTabularStorage(db, "users", UserSchema, ["id"] as const);
276
+
277
+ // Insert without providing ID - database generates it
278
+ const user = await storage.put({ name: "Alice", email: "alice@example.com" });
279
+ console.log(user.id); // 1 (auto-generated)
280
+ ```
281
+
282
+ **Generation Strategy** (inferred from type):
283
+
284
+ - `type: "integer"` → Auto-increment (SERIAL, INTEGER PRIMARY KEY, counter)
285
+ - `type: "string"` → UUID via `uuid4()` from `@workglow/util`
286
+
287
+ **Configuration Options:**
288
+
289
+ ```typescript
290
+ new PostgresTabularStorage(
291
+ db,
292
+ "users",
293
+ UserSchema,
294
+ ["id"],
295
+ [],
296
+ { clientProvidedKeys: "if-missing" } // "never" | "if-missing" | "always"
297
+ );
298
+ ```
299
+
300
+ - `"if-missing"` (default): Use client value if provided, generate otherwise
301
+ - `"never"`: Always generate (most secure)
302
+ - `"always"`: Require client value (for testing)
303
+
304
+ See [Tabular Storage README](./src/tabular/README.md) for detailed documentation.
305
+
259
306
  #### CRUD Operations
260
307
 
261
308
  ```typescript
@@ -342,9 +389,9 @@ await userRepo.deleteSearch({
342
389
 
343
390
  ```typescript
344
391
  // SQLite (Node.js/Bun)
345
- import { SqliteTabularRepository } from "@workglow/storage";
392
+ import { SqliteTabularStorage } from "@workglow/storage";
346
393
 
347
- const sqliteUsers = new SqliteTabularRepository<typeof UserSchema, ["id"]>(
394
+ const sqliteUsers = new SqliteTabularStorage<typeof UserSchema, ["id"]>(
348
395
  "./users.db",
349
396
  "users",
350
397
  UserSchema,
@@ -353,11 +400,11 @@ const sqliteUsers = new SqliteTabularRepository<typeof UserSchema, ["id"]>(
353
400
  );
354
401
 
355
402
  // PostgreSQL (Node.js/Bun)
356
- import { PostgresTabularRepository } from "@workglow/storage";
403
+ import { PostgresTabularStorage } from "@workglow/storage";
357
404
  import { Pool } from "pg";
358
405
 
359
406
  const pool = new Pool({ connectionString: "postgresql://..." });
360
- const pgUsers = new PostgresTabularRepository<typeof UserSchema, ["id"]>(
407
+ const pgUsers = new PostgresTabularStorage<typeof UserSchema, ["id"]>(
361
408
  pool,
362
409
  "users",
363
410
  UserSchema,
@@ -366,11 +413,11 @@ const pgUsers = new PostgresTabularRepository<typeof UserSchema, ["id"]>(
366
413
  );
367
414
 
368
415
  // Supabase (Node.js/Bun)
369
- import { SupabaseTabularRepository } from "@workglow/storage";
416
+ import { SupabaseTabularStorage } from "@workglow/storage";
370
417
  import { createClient } from "@supabase/supabase-js";
371
418
 
372
419
  const supabase = createClient("https://your-project.supabase.co", "your-anon-key");
373
- const supabaseUsers = new SupabaseTabularRepository<typeof UserSchema, ["id"]>(
420
+ const supabaseUsers = new SupabaseTabularStorage<typeof UserSchema, ["id"]>(
374
421
  supabase,
375
422
  "users",
376
423
  UserSchema,
@@ -379,8 +426,8 @@ const supabaseUsers = new SupabaseTabularRepository<typeof UserSchema, ["id"]>(
379
426
  );
380
427
 
381
428
  // IndexedDB (Browser)
382
- import { IndexedDbTabularRepository } from "@workglow/storage";
383
- const browserUsers = new IndexedDbTabularRepository<typeof UserSchema, ["id"]>(
429
+ import { IndexedDbTabularStorage } from "@workglow/storage";
430
+ const browserUsers = new IndexedDbTabularStorage<typeof UserSchema, ["id"]>(
384
431
  "users",
385
432
  UserSchema,
386
433
  ["id"],
@@ -388,8 +435,8 @@ const browserUsers = new IndexedDbTabularRepository<typeof UserSchema, ["id"]>(
388
435
  );
389
436
 
390
437
  // File-based (Node.js/Bun)
391
- import { FsFolderTabularRepository } from "@workglow/storage";
392
- const fileUsers = new FsFolderTabularRepository<typeof UserSchema, ["id"]>(
438
+ import { FsFolderTabularStorage } from "@workglow/storage";
439
+ const fileUsers = new FsFolderTabularStorage<typeof UserSchema, ["id"]>(
393
440
  "./data/users",
394
441
  UserSchema,
395
442
  ["id"],
@@ -463,23 +510,23 @@ await jobQueue.deleteJobsByStatusAndAge(JobStatus.COMPLETED, 24 * 60 * 60 * 1000
463
510
  ```typescript
464
511
  import {
465
512
  IndexedDbKvRepository,
466
- IndexedDbTabularRepository,
513
+ IndexedDbTabularStorage,
467
514
  IndexedDbQueueStorage,
468
515
  SupabaseKvRepository,
469
- SupabaseTabularRepository,
516
+ SupabaseTabularStorage,
470
517
  SupabaseQueueStorage,
471
518
  } from "@workglow/storage";
472
519
  import { createClient } from "@supabase/supabase-js";
473
520
 
474
521
  // Local browser storage with IndexedDB
475
522
  const settings = new IndexedDbKvRepository("app-settings");
476
- const userData = new IndexedDbTabularRepository("users", UserSchema, ["id"]);
523
+ const userData = new IndexedDbTabularStorage("users", UserSchema, ["id"]);
477
524
  const jobQueue = new IndexedDbQueueStorage<any, any>("background-jobs");
478
525
 
479
526
  // Or use Supabase for cloud storage from the browser
480
527
  const supabase = createClient("https://your-project.supabase.co", "your-anon-key");
481
528
  const cloudSettings = new SupabaseKvRepository(supabase, "app-settings");
482
- const cloudUserData = new SupabaseTabularRepository(supabase, "users", UserSchema, ["id"]);
529
+ const cloudUserData = new SupabaseTabularStorage(supabase, "users", UserSchema, ["id"]);
483
530
  const cloudJobQueue = new SupabaseQueueStorage(supabase, "background-jobs");
484
531
  ```
485
532
 
@@ -488,13 +535,13 @@ const cloudJobQueue = new SupabaseQueueStorage(supabase, "background-jobs");
488
535
  ```typescript
489
536
  import {
490
537
  SqliteKvRepository,
491
- PostgresTabularRepository,
538
+ PostgresTabularStorage,
492
539
  FsFolderJsonKvRepository,
493
540
  } from "@workglow/storage";
494
541
 
495
542
  // Mix and match storage backends
496
543
  const cache = new FsFolderJsonKvRepository("./cache");
497
- const users = new PostgresTabularRepository(pool, "users", UserSchema, ["id"]);
544
+ const users = new PostgresTabularStorage(pool, "users", UserSchema, ["id"]);
498
545
  ```
499
546
 
500
547
  ### Bun Environment
@@ -502,31 +549,120 @@ const users = new PostgresTabularRepository(pool, "users", UserSchema, ["id"]);
502
549
  ```typescript
503
550
  // Bun has access to all implementations
504
551
  import {
505
- SqliteTabularRepository,
552
+ SqliteTabularStorage,
506
553
  FsFolderJsonKvRepository,
507
554
  PostgresQueueStorage,
508
- SupabaseTabularRepository,
555
+ SupabaseTabularStorage,
509
556
  } from "@workglow/storage";
510
557
 
511
558
  import { Database } from "bun:sqlite";
512
559
  import { createClient } from "@supabase/supabase-js";
513
560
 
514
561
  const db = new Database("./app.db");
515
- const data = new SqliteTabularRepository(db, "items", ItemSchema, ["id"]);
562
+ const data = new SqliteTabularStorage(db, "items", ItemSchema, ["id"]);
516
563
 
517
564
  // Or use Supabase for cloud storage
518
565
  const supabase = createClient("https://your-project.supabase.co", "your-anon-key");
519
- const cloudData = new SupabaseTabularRepository(supabase, "items", ItemSchema, ["id"]);
566
+ const cloudData = new SupabaseTabularStorage(supabase, "items", ItemSchema, ["id"]);
520
567
  ```
521
568
 
522
569
  ## Advanced Features
523
570
 
571
+ ### Repository Registry
572
+
573
+ Repositories can be registered globally by ID, allowing tasks to reference them by name rather than passing direct instances. This is useful for configuring repositories once at application startup and referencing them throughout your task graphs.
574
+
575
+ #### Registering Repositories
576
+
577
+ ```typescript
578
+ import {
579
+ registerTabularStorage,
580
+ getTabularStorage,
581
+ InMemoryTabularStorage,
582
+ } from "@workglow/storage";
583
+
584
+ // Define your schema
585
+ const userSchema = {
586
+ type: "object",
587
+ properties: {
588
+ id: { type: "string" },
589
+ name: { type: "string" },
590
+ email: { type: "string" },
591
+ },
592
+ required: ["id", "name", "email"],
593
+ additionalProperties: false,
594
+ } as const;
595
+
596
+ // Create and register a repository
597
+ const userRepo = new InMemoryTabularStorage(userSchema, ["id"] as const);
598
+ registerTabularStorage("users", userRepo);
599
+
600
+ // Later, retrieve the repository by ID
601
+ const repo = getTabularStorage("users");
602
+ ```
603
+
604
+ #### Using Repositories in Tasks
605
+
606
+ When using repositories with tasks, you can pass either the repository ID or a direct instance. The TaskRunner automatically resolves string IDs using the registry.
607
+
608
+ ```typescript
609
+ import { TypeTabularStorage } from "@workglow/storage";
610
+
611
+ // In your task's input schema, use TypeTabularStorage
612
+ static inputSchema() {
613
+ return {
614
+ type: "object",
615
+ properties: {
616
+ dataSource: TypeTabularStorage({
617
+ title: "User Repository",
618
+ description: "Repository containing user records",
619
+ }),
620
+ },
621
+ required: ["dataSource"],
622
+ };
623
+ }
624
+
625
+ // Both approaches work:
626
+ await task.run({ dataSource: "users" }); // Resolved from registry
627
+ await task.run({ dataSource: userRepoInstance }); // Direct instance
628
+ ```
629
+
630
+ #### Schema Helper Functions
631
+
632
+ The package provides schema helper functions for defining repository inputs with proper format annotations:
633
+
634
+ ```typescript
635
+ import {
636
+ TypeTabularStorage,
637
+ TypeVectorRepository,
638
+ TypeDocumentRepository,
639
+ } from "@workglow/storage";
640
+
641
+ // Tabular repository (format: "storage:tabular")
642
+ const tabularSchema = TypeTabularStorage({
643
+ title: "Data Source",
644
+ description: "Tabular data repository",
645
+ });
646
+
647
+ // Vector repository (format: "repository:document-node-vector")
648
+ const vectorSchema = TypeVectorRepository({
649
+ title: "Embeddings Store",
650
+ description: "Vector embeddings repository",
651
+ });
652
+
653
+ // Document repository (format: "repository:document")
654
+ const docSchema = TypeDocumentRepository({
655
+ title: "Document Store",
656
+ description: "Document storage repository",
657
+ });
658
+ ```
659
+
524
660
  ### Event-Driven Architecture
525
661
 
526
662
  All storage implementations support event emission for monitoring and reactive programming:
527
663
 
528
664
  ```typescript
529
- const store = new InMemoryTabularRepository(UserSchema, ["id"]);
665
+ const store = new InMemoryTabularStorage(UserSchema, ["id"]);
530
666
 
531
667
  // Monitor all operations
532
668
  store.on("put", (entity) => console.log("User created/updated:", entity));
@@ -555,7 +691,7 @@ const OrderLineSchema = {
555
691
  additionalProperties: false,
556
692
  } as const satisfies JsonSchema;
557
693
 
558
- const orderLines = new InMemoryTabularRepository<typeof OrderLineSchema, ["orderId", "lineNumber"]>(
694
+ const orderLines = new InMemoryTabularStorage<typeof OrderLineSchema, ["orderId", "lineNumber"]>(
559
695
  OrderLineSchema,
560
696
  ["orderId", "lineNumber"], // Compound primary key
561
697
  ["productId"] // Additional index
@@ -594,12 +730,12 @@ await files.put("note-1", "Hello world");
594
730
 
595
731
  ## API Reference
596
732
 
597
- ### IKvRepository<Key, Value>
733
+ ### IKvStorage<Key, Value>
598
734
 
599
735
  Core interface for key-value storage:
600
736
 
601
737
  ```typescript
602
- interface IKvRepository<Key, Value> {
738
+ interface IKvStorage<Key, Value> {
603
739
  // Core operations
604
740
  put(key: Key, value: Value): Promise<void>;
605
741
  putBulk(items: Array<{ key: Key; value: Value }>): Promise<void>;
@@ -618,12 +754,12 @@ interface IKvRepository<Key, Value> {
618
754
  }
619
755
  ```
620
756
 
621
- ### ITabularRepository<Schema, PrimaryKeyNames>
757
+ ### ITabularStorage<Schema, PrimaryKeyNames>
622
758
 
623
759
  Core interface for tabular storage:
624
760
 
625
761
  ```typescript
626
- interface ITabularRepository<Schema, PrimaryKeyNames, Entity, PrimaryKey, Value> {
762
+ interface ITabularStorage<Schema, PrimaryKeyNames, Entity, PrimaryKey, Value> {
627
763
  // Core operations
628
764
  put(entity: Entity): Promise<void>;
629
765
  putBulk(entities: Entity[]): Promise<void>;
@@ -705,7 +841,7 @@ interface IQueueStorage<Input, Output> {
705
841
 
706
842
  ```typescript
707
843
  import { JsonSchema, FromSchema } from "@workglow/util";
708
- import { InMemoryTabularRepository, InMemoryKvRepository } from "@workglow/storage";
844
+ import { InMemoryTabularStorage, InMemoryKvStorage } from "@workglow/storage";
709
845
 
710
846
  // User profile with tabular storage
711
847
  const UserSchema = {
@@ -727,14 +863,14 @@ const UserSchema = {
727
863
  additionalProperties: false,
728
864
  } as const satisfies JsonSchema;
729
865
 
730
- const userRepo = new InMemoryTabularRepository<typeof UserSchema, ["id"]>(
866
+ const userRepo = new InMemoryTabularStorage<typeof UserSchema, ["id"]>(
731
867
  UserSchema,
732
868
  ["id"],
733
869
  ["email", "username"]
734
870
  );
735
871
 
736
872
  // User sessions with KV storage
737
- const sessionStore = new InMemoryKvRepository<string, { userId: string; expiresAt: string }>();
873
+ const sessionStore = new InMemoryKvStorage<string, { userId: string; expiresAt: string }>();
738
874
 
739
875
  // User management class
740
876
  class UserManager {
@@ -841,7 +977,7 @@ class ConfigManager {
841
977
  import { createClient } from "@supabase/supabase-js";
842
978
  import { JsonSchema } from "@workglow/util";
843
979
  import {
844
- SupabaseTabularRepository,
980
+ SupabaseTabularStorage,
845
981
  SupabaseKvRepository,
846
982
  SupabaseQueueStorage,
847
983
  } from "@workglow/storage";
@@ -882,7 +1018,7 @@ const OrderSchema = {
882
1018
  } as const satisfies JsonSchema;
883
1019
 
884
1020
  // Create repositories
885
- const products = new SupabaseTabularRepository<typeof ProductSchema, ["id"]>(
1021
+ const products = new SupabaseTabularStorage<typeof ProductSchema, ["id"]>(
886
1022
  supabase,
887
1023
  "products",
888
1024
  ProductSchema,
@@ -890,7 +1026,7 @@ const products = new SupabaseTabularRepository<typeof ProductSchema, ["id"]>(
890
1026
  ["category", "name"] // Indexed columns for fast searching
891
1027
  );
892
1028
 
893
- const orders = new SupabaseTabularRepository<typeof OrderSchema, ["id"]>(
1029
+ const orders = new SupabaseTabularStorage<typeof OrderSchema, ["id"]>(
894
1030
  supabase,
895
1031
  "orders",
896
1032
  OrderSchema,
@@ -972,7 +1108,7 @@ bun test
972
1108
 
973
1109
  # Run specific test suites
974
1110
  bun test --grep "KvRepository"
975
- bun test --grep "TabularRepository"
1111
+ bun test --grep "TabularStorage"
976
1112
  bun test --grep "QueueStorage"
977
1113
 
978
1114
  # Test specific environments
@@ -985,17 +1121,13 @@ bun test --grep "Sqlite" # Native tests
985
1121
 
986
1122
  ```typescript
987
1123
  import { describe, test, expect, beforeEach } from "vitest";
988
- import { InMemoryTabularRepository } from "@workglow/storage";
1124
+ import { InMemoryTabularStorage } from "@workglow/storage";
989
1125
 
990
1126
  describe("UserRepository", () => {
991
- let userRepo: InMemoryTabularRepository<typeof UserSchema, ["id"]>;
1127
+ let userRepo: InMemoryTabularStorage<typeof UserSchema, ["id"]>;
992
1128
 
993
1129
  beforeEach(() => {
994
- userRepo = new InMemoryTabularRepository<typeof UserSchema, ["id"]>(
995
- UserSchema,
996
- ["id"],
997
- ["email"]
998
- );
1130
+ userRepo = new InMemoryTabularStorage<typeof UserSchema, ["id"]>(UserSchema, ["id"], ["email"]);
999
1131
  });
1000
1132
 
1001
1133
  test("should create and retrieve user", async () => {