@dexto/storage 1.7.2 → 1.8.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 (87) hide show
  1. package/README.md +51 -38
  2. package/dist/blob/index.cjs +2 -7
  3. package/dist/blob/index.d.ts +3 -14
  4. package/dist/blob/index.d.ts.map +1 -1
  5. package/dist/blob/index.js +1 -4
  6. package/dist/cache/index.cjs +3 -5
  7. package/dist/cache/index.d.ts +4 -14
  8. package/dist/cache/index.d.ts.map +1 -1
  9. package/dist/cache/index.js +2 -3
  10. package/dist/cache/schemas.cjs +5 -5
  11. package/dist/cache/schemas.js +1 -1
  12. package/dist/database/index.cjs +8 -9
  13. package/dist/database/index.d.ts +5 -15
  14. package/dist/database/index.d.ts.map +1 -1
  15. package/dist/database/index.js +5 -9
  16. package/dist/database/memory-database-store.cjs +16 -0
  17. package/dist/database/memory-database-store.d.ts +4 -0
  18. package/dist/database/memory-database-store.d.ts.map +1 -1
  19. package/dist/database/memory-database-store.js +16 -0
  20. package/dist/database/postgres-store.cjs +25 -0
  21. package/dist/database/postgres-store.d.ts +4 -0
  22. package/dist/database/postgres-store.d.ts.map +1 -1
  23. package/dist/database/postgres-store.js +25 -0
  24. package/dist/database/schemas.cjs +6 -6
  25. package/dist/database/schemas.js +1 -1
  26. package/dist/database/sqlite-store.cjs +18 -0
  27. package/dist/database/sqlite-store.d.ts +4 -0
  28. package/dist/database/sqlite-store.d.ts.map +1 -1
  29. package/dist/database/sqlite-store.js +18 -0
  30. package/dist/index.cjs +12 -19
  31. package/dist/index.d.cts +17 -225
  32. package/dist/index.d.ts +4 -10
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +11 -15
  35. package/package.json +3 -3
  36. package/dist/blob/factories/index.cjs +0 -31
  37. package/dist/blob/factories/index.d.ts +0 -6
  38. package/dist/blob/factories/index.d.ts.map +0 -1
  39. package/dist/blob/factories/index.js +0 -6
  40. package/dist/blob/factories/local.cjs +0 -38
  41. package/dist/blob/factories/local.d.ts +0 -17
  42. package/dist/blob/factories/local.d.ts.map +0 -1
  43. package/dist/blob/factories/local.js +0 -14
  44. package/dist/blob/factories/memory.cjs +0 -44
  45. package/dist/blob/factories/memory.d.ts +0 -17
  46. package/dist/blob/factories/memory.d.ts.map +0 -1
  47. package/dist/blob/factories/memory.js +0 -20
  48. package/dist/blob/factory.cjs +0 -16
  49. package/dist/blob/factory.d.ts +0 -35
  50. package/dist/blob/factory.d.ts.map +0 -1
  51. package/dist/blob/factory.js +0 -0
  52. package/dist/cache/factories/index.cjs +0 -31
  53. package/dist/cache/factories/index.d.ts +0 -6
  54. package/dist/cache/factories/index.d.ts.map +0 -1
  55. package/dist/cache/factories/index.js +0 -6
  56. package/dist/cache/factories/memory.cjs +0 -39
  57. package/dist/cache/factories/memory.d.ts +0 -17
  58. package/dist/cache/factories/memory.d.ts.map +0 -1
  59. package/dist/cache/factories/memory.js +0 -15
  60. package/dist/cache/factories/redis.cjs +0 -65
  61. package/dist/cache/factories/redis.d.ts +0 -20
  62. package/dist/cache/factories/redis.d.ts.map +0 -1
  63. package/dist/cache/factories/redis.js +0 -31
  64. package/dist/cache/factory.cjs +0 -16
  65. package/dist/cache/factory.d.ts +0 -41
  66. package/dist/cache/factory.d.ts.map +0 -1
  67. package/dist/cache/factory.js +0 -0
  68. package/dist/database/factories/index.cjs +0 -34
  69. package/dist/database/factories/index.d.ts +0 -7
  70. package/dist/database/factories/index.d.ts.map +0 -1
  71. package/dist/database/factories/index.js +0 -8
  72. package/dist/database/factories/memory.cjs +0 -39
  73. package/dist/database/factories/memory.d.ts +0 -16
  74. package/dist/database/factories/memory.d.ts.map +0 -1
  75. package/dist/database/factories/memory.js +0 -15
  76. package/dist/database/factories/postgres.cjs +0 -61
  77. package/dist/database/factories/postgres.d.ts +0 -19
  78. package/dist/database/factories/postgres.d.ts.map +0 -1
  79. package/dist/database/factories/postgres.js +0 -27
  80. package/dist/database/factories/sqlite.cjs +0 -65
  81. package/dist/database/factories/sqlite.d.ts +0 -20
  82. package/dist/database/factories/sqlite.d.ts.map +0 -1
  83. package/dist/database/factories/sqlite.js +0 -31
  84. package/dist/database/factory.cjs +0 -16
  85. package/dist/database/factory.d.ts +0 -41
  86. package/dist/database/factory.d.ts.map +0 -1
  87. package/dist/database/factory.js +0 -0
package/README.md CHANGED
@@ -1,38 +1,73 @@
1
1
  # `@dexto/storage`
2
2
 
3
- Concrete storage backends (blob store, database, cache) and their config schemas/factories.
3
+ Concrete Node storage helpers and config schemas for images that choose to build `DextoStores`
4
+ from local backends.
4
5
 
5
- Core (`@dexto/core`) owns the **interfaces** (`BlobStore`, `Database`, `Cache`) and `StorageManager`.
6
- Product layers (CLI/server/apps) choose which concrete backends are available by including factories
7
- in an image (`DextoImage.storage.*`) and resolving config via `@dexto/agent-config`.
6
+ Core (`@dexto/core`) owns typed domain store contracts such as `ConversationStore`,
7
+ `SessionStore`, `MemoryStore`, `ArtifactStore`, and `ToolStateStore`. This package provides Node
8
+ backend implementations that image implementations can use internally to compose a `DextoStores`
9
+ implementation.
10
+
11
+ Product layers (CLI/server/apps) can either use these helpers inside an image or provide a
12
+ native `DextoStores` implementation directly. Core code should depend on typed stores, not these
13
+ backend helper classes.
8
14
 
9
15
  ## What this package exports
10
16
 
11
- - **Factories** (for image modules):
12
- - Blob: `localBlobStoreFactory`, `inMemoryBlobStoreFactory`
13
- - Database: `sqliteDatabaseFactory`, `postgresDatabaseFactory`, `inMemoryDatabaseFactory`
14
- - Cache: `inMemoryCacheFactory`, `redisCacheFactory`
15
17
  - **Schemas** (for config parsing + UI):
16
18
  - Import from `@dexto/storage/schemas` for browser-safe schema-only exports.
17
19
  - **Concrete implementations** (Node runtime):
18
20
  - `LocalBlobStore`, `MemoryBlobStore`, `SQLiteStore`, `PostgresStore`, `RedisStore`, etc.
19
21
 
20
- ## Using factories in an image
22
+ ## Using helpers in an image
21
23
 
22
24
  ```ts
23
25
  import type { DextoImage } from '@dexto/agent-config';
24
26
  import {
25
- localBlobStoreFactory,
26
- sqliteDatabaseFactory,
27
- inMemoryCacheFactory,
27
+ BackendDextoStores,
28
+ DatabaseBackedArtifactStore,
29
+ DatabaseBackedSessionStore,
30
+ // ...other typed store adapters
31
+ } from '@dexto/core/storage';
32
+ import {
33
+ StorageSchema,
34
+ LocalBlobStore,
35
+ LocalBlobStoreSchema,
36
+ SQLiteStore,
37
+ SqliteDatabaseSchema,
38
+ MemoryCacheStore,
28
39
  } from '@dexto/storage';
29
40
 
30
41
  export const myImage: DextoImage = {
31
42
  /* metadata/defaults/tools/hooks/compaction/logger ... */
32
43
  storage: {
33
- blob: { local: localBlobStoreFactory },
34
- database: { sqlite: sqliteDatabaseFactory },
35
- cache: { 'in-memory': inMemoryCacheFactory },
44
+ configSchema: StorageSchema,
45
+ async createStores(config, logger) {
46
+ const blobStore = new LocalBlobStore(LocalBlobStoreSchema.parse(config.blob), logger);
47
+ const database = new SQLiteStore(SqliteDatabaseSchema.parse(config.database), logger);
48
+ const cache = new MemoryCacheStore();
49
+
50
+ return new BackendDextoStores(
51
+ {
52
+ sessions: new DatabaseBackedSessionStore(database, cache),
53
+ artifacts: new DatabaseBackedArtifactStore(blobStore),
54
+ // ...provide every DextoStoreMap domain
55
+ },
56
+ {
57
+ async connect() {
58
+ await cache.connect();
59
+ await database.connect();
60
+ await blobStore.connect();
61
+ },
62
+ async disconnect() {
63
+ await Promise.all([cache.disconnect(), database.disconnect(), blobStore.disconnect()]);
64
+ },
65
+ isConnected() {
66
+ return cache.isConnected() && database.isConnected() && blobStore.isConnected();
67
+ },
68
+ },
69
+ );
70
+ },
36
71
  },
37
72
  };
38
73
  ```
@@ -55,26 +90,4 @@ storage:
55
90
  ```
56
91
 
57
92
  Those envelope schemas use `.passthrough()` so extra fields survive initial parsing. Detailed
58
- validation happens later in `@dexto/agent-config` by selecting the right factory from the loaded
59
- image and validating against that factory’s `configSchema`.
60
-
61
- ## Optional dependencies
62
-
63
- Some backends rely on optional peer dependencies:
64
-
65
- - SQLite: `better-sqlite3`
66
- - Postgres: `pg`
67
- - Redis: `ioredis`
68
-
69
- Factories load these lazily and throw an actionable error if the dependency is missing.
70
-
71
- ## Browser safety
72
-
73
- If you only need schemas/types (e.g., WebUI), import from:
74
-
75
- ```ts
76
- import { StorageSchema } from '@dexto/storage/schemas';
77
- ```
78
-
79
- Do not import from `@dexto/storage` in browser bundles, since the root entry also exports Node
80
- implementations.
93
+ validation happens later inside the loaded image's `storage.createStores(...)` implementation.
@@ -23,12 +23,9 @@ __export(blob_exports, {
23
23
  InMemoryBlobStoreSchema: () => import_schemas.InMemoryBlobStoreSchema,
24
24
  LocalBlobStore: () => import_local_blob_store.LocalBlobStore,
25
25
  LocalBlobStoreSchema: () => import_schemas.LocalBlobStoreSchema,
26
- MemoryBlobStore: () => import_memory_blob_store.MemoryBlobStore,
27
- inMemoryBlobStoreFactory: () => import_factories.inMemoryBlobStoreFactory,
28
- localBlobStoreFactory: () => import_factories.localBlobStoreFactory
26
+ MemoryBlobStore: () => import_memory_blob_store.MemoryBlobStore
29
27
  });
30
28
  module.exports = __toCommonJS(blob_exports);
31
- var import_factories = require("./factories/index.js");
32
29
  var import_schemas = require("./schemas.js");
33
30
  var import_local_blob_store = require("./local-blob-store.js");
34
31
  var import_memory_blob_store = require("./memory-blob-store.js");
@@ -39,7 +36,5 @@ var import_memory_blob_store = require("./memory-blob-store.js");
39
36
  InMemoryBlobStoreSchema,
40
37
  LocalBlobStore,
41
38
  LocalBlobStoreSchema,
42
- MemoryBlobStore,
43
- inMemoryBlobStoreFactory,
44
- localBlobStoreFactory
39
+ MemoryBlobStore
45
40
  });
@@ -2,24 +2,13 @@
2
2
  * Blob Storage Module
3
3
  *
4
4
  * This module provides a flexible blob storage system with support for
5
- * multiple backends through a factory pattern.
6
- *
7
- * ## Built-in Factories
8
- * - `local`: Store blobs on the local filesystem
9
- * - `in-memory`: Store blobs in RAM (for testing/development)
10
- *
11
- * ## Custom Factories
12
- * Product layers (CLI/server/platform) decide which factories are available by including them
13
- * in images (`DextoImage.storage.blob`).
5
+ * multiple concrete backends.
14
6
  *
15
7
  * ## Usage
16
- * Blob stores are typically constructed by the product-layer resolver (`@dexto/agent-config`)
17
- * via image-provided factory maps. For direct usage, call a factory's `create()` after validating
18
- * config with its `configSchema`.
8
+ * Blob stores are typically constructed by an image's storage implementation after validating
9
+ * config with the matching schema.
19
10
  */
20
- export type { BlobStoreFactory } from './factory.js';
21
11
  export type { BlobStore, BlobInput, BlobMetadata, BlobReference, BlobData, BlobStats, StoredBlobMetadata, } from './types.js';
22
- export { localBlobStoreFactory, inMemoryBlobStoreFactory } from './factories/index.js';
23
12
  export { BLOB_STORE_TYPES, BlobStoreConfigSchema, InMemoryBlobStoreSchema, LocalBlobStoreSchema, type BlobStoreType, type BlobStoreConfig, type InMemoryBlobStoreConfigInput, type InMemoryBlobStoreConfig, type LocalBlobStoreConfigInput, type LocalBlobStoreConfig, } from './schemas.js';
24
13
  export { LocalBlobStore } from './local-blob-store.js';
25
14
  export { MemoryBlobStore } from './memory-blob-store.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blob/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,YAAY,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,SAAS,EACT,kBAAkB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGvF,OAAO,EACH,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blob/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,SAAS,EACT,kBAAkB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,4 +1,3 @@
1
- import { localBlobStoreFactory, inMemoryBlobStoreFactory } from "./factories/index.js";
2
1
  import {
3
2
  BLOB_STORE_TYPES,
4
3
  BlobStoreConfigSchema,
@@ -13,7 +12,5 @@ export {
13
12
  InMemoryBlobStoreSchema,
14
13
  LocalBlobStore,
15
14
  LocalBlobStoreSchema,
16
- MemoryBlobStore,
17
- inMemoryBlobStoreFactory,
18
- localBlobStoreFactory
15
+ MemoryBlobStore
19
16
  };
@@ -23,13 +23,12 @@ __export(cache_exports, {
23
23
  InMemoryCacheSchema: () => import_schemas.InMemoryCacheSchema,
24
24
  MemoryCacheStore: () => import_memory_cache_store.MemoryCacheStore,
25
25
  RedisCacheSchema: () => import_schemas.RedisCacheSchema,
26
- inMemoryCacheFactory: () => import_factories.inMemoryCacheFactory,
27
- redisCacheFactory: () => import_factories.redisCacheFactory
26
+ RedisStore: () => import_redis_store.RedisStore
28
27
  });
29
28
  module.exports = __toCommonJS(cache_exports);
30
- var import_factories = require("./factories/index.js");
31
29
  var import_schemas = require("./schemas.js");
32
30
  var import_memory_cache_store = require("./memory-cache-store.js");
31
+ var import_redis_store = require("./redis-store.js");
33
32
  // Annotate the CommonJS export names for ESM import in node:
34
33
  0 && (module.exports = {
35
34
  CACHE_TYPES,
@@ -37,6 +36,5 @@ var import_memory_cache_store = require("./memory-cache-store.js");
37
36
  InMemoryCacheSchema,
38
37
  MemoryCacheStore,
39
38
  RedisCacheSchema,
40
- inMemoryCacheFactory,
41
- redisCacheFactory
39
+ RedisStore
42
40
  });
@@ -2,24 +2,14 @@
2
2
  * Cache Module
3
3
  *
4
4
  * This module provides a flexible caching system with support for
5
- * multiple backends through a factory pattern.
6
- *
7
- * ## Built-in Factories
8
- * - `in-memory`: Store data in RAM (for testing/development)
9
- * - `redis`: Store data in Redis server
10
- *
11
- * ## Custom Factories
12
- * Product layers (CLI/server/platform) decide which factories are available by including them
13
- * in images (`DextoImage.storage.cache`).
5
+ * multiple concrete backends.
14
6
  *
15
7
  * ## Usage
16
- * Cache backends are typically constructed by the product-layer resolver (`@dexto/agent-config`)
17
- * via image-provided factory maps. For direct usage, call a factory's `create()` after validating
18
- * config with its `configSchema`.
8
+ * Cache backends are typically constructed by an image's storage implementation after validating
9
+ * config with the matching schema.
19
10
  */
20
- export type { CacheFactory } from './factory.js';
21
11
  export type { Cache } from './types.js';
22
- export { inMemoryCacheFactory, redisCacheFactory } from './factories/index.js';
23
12
  export { CACHE_TYPES, CacheConfigSchema, InMemoryCacheSchema, RedisCacheSchema, type CacheType, type CacheConfig, type InMemoryCacheConfig, type RedisCacheConfig, } from './schemas.js';
24
13
  export { MemoryCacheStore } from './memory-cache-store.js';
14
+ export { RedisStore } from './redis-store.js';
25
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG/E,OAAO,EACH,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,OAAO,EACH,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,3 @@
1
- import { inMemoryCacheFactory, redisCacheFactory } from "./factories/index.js";
2
1
  import {
3
2
  CACHE_TYPES,
4
3
  CacheConfigSchema,
@@ -6,12 +5,12 @@ import {
6
5
  RedisCacheSchema
7
6
  } from "./schemas.js";
8
7
  import { MemoryCacheStore } from "./memory-cache-store.js";
8
+ import { RedisStore } from "./redis-store.js";
9
9
  export {
10
10
  CACHE_TYPES,
11
11
  CacheConfigSchema,
12
12
  InMemoryCacheSchema,
13
13
  MemoryCacheStore,
14
14
  RedisCacheSchema,
15
- inMemoryCacheFactory,
16
- redisCacheFactory
15
+ RedisStore
17
16
  };
@@ -25,7 +25,7 @@ __export(schemas_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(schemas_exports);
27
27
  var import_zod = require("zod");
28
- var import_core = require("@dexto/core");
28
+ var import_config = require("@dexto/core/config");
29
29
  const CACHE_TYPES = ["in-memory", "redis"];
30
30
  const BaseCacheSchema = import_zod.z.object({
31
31
  maxConnections: import_zod.z.number().int().positive().optional().describe("Maximum connections"),
@@ -39,7 +39,7 @@ const InMemoryCacheSchema = BaseCacheSchema.extend({
39
39
  }).strict();
40
40
  const RedisCacheSchema = BaseCacheSchema.extend({
41
41
  type: import_zod.z.literal("redis"),
42
- url: (0, import_core.EnvExpandedString)().optional().describe("Redis connection URL (redis://...)"),
42
+ url: (0, import_config.EnvExpandedString)().optional().describe("Redis connection URL (redis://...)"),
43
43
  host: import_zod.z.string().optional().describe("Redis host"),
44
44
  port: import_zod.z.number().int().positive().optional().describe("Redis port"),
45
45
  password: import_zod.z.string().optional().describe("Redis password"),
@@ -51,9 +51,9 @@ const RedisCacheSchema = BaseCacheSchema.extend({
51
51
  message: "Redis cache requires either 'url' or 'host' to be specified",
52
52
  path: ["url"],
53
53
  params: {
54
- code: import_core.StorageErrorCode.CONNECTION_CONFIG_MISSING,
55
- scope: import_core.ErrorScope.STORAGE,
56
- type: import_core.ErrorType.USER
54
+ code: import_config.StorageErrorCode.CONNECTION_CONFIG_MISSING,
55
+ scope: import_config.ErrorScope.STORAGE,
56
+ type: import_config.ErrorType.USER
57
57
  }
58
58
  });
59
59
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { EnvExpandedString, ErrorScope, ErrorType, StorageErrorCode } from "@dexto/core";
2
+ import { EnvExpandedString, ErrorScope, ErrorType, StorageErrorCode } from "@dexto/core/config";
3
3
  const CACHE_TYPES = ["in-memory", "redis"];
4
4
  const BaseCacheSchema = z.object({
5
5
  maxConnections: z.number().int().positive().optional().describe("Maximum connections"),
@@ -23,15 +23,15 @@ __export(database_exports, {
23
23
  InMemoryDatabaseSchema: () => import_schemas.InMemoryDatabaseSchema,
24
24
  MemoryDatabaseStore: () => import_memory_database_store.MemoryDatabaseStore,
25
25
  PostgresDatabaseSchema: () => import_schemas.PostgresDatabaseSchema,
26
- SqliteDatabaseSchema: () => import_schemas.SqliteDatabaseSchema,
27
- inMemoryDatabaseFactory: () => import_factories.inMemoryDatabaseFactory,
28
- postgresDatabaseFactory: () => import_factories.postgresDatabaseFactory,
29
- sqliteDatabaseFactory: () => import_factories.sqliteDatabaseFactory
26
+ PostgresStore: () => import_postgres_store.PostgresStore,
27
+ SQLiteStore: () => import_sqlite_store.SQLiteStore,
28
+ SqliteDatabaseSchema: () => import_schemas.SqliteDatabaseSchema
30
29
  });
31
30
  module.exports = __toCommonJS(database_exports);
32
- var import_factories = require("./factories/index.js");
33
31
  var import_schemas = require("./schemas.js");
34
32
  var import_memory_database_store = require("./memory-database-store.js");
33
+ var import_sqlite_store = require("./sqlite-store.js");
34
+ var import_postgres_store = require("./postgres-store.js");
35
35
  // Annotate the CommonJS export names for ESM import in node:
36
36
  0 && (module.exports = {
37
37
  DATABASE_TYPES,
@@ -39,8 +39,7 @@ var import_memory_database_store = require("./memory-database-store.js");
39
39
  InMemoryDatabaseSchema,
40
40
  MemoryDatabaseStore,
41
41
  PostgresDatabaseSchema,
42
- SqliteDatabaseSchema,
43
- inMemoryDatabaseFactory,
44
- postgresDatabaseFactory,
45
- sqliteDatabaseFactory
42
+ PostgresStore,
43
+ SQLiteStore,
44
+ SqliteDatabaseSchema
46
45
  });
@@ -2,25 +2,15 @@
2
2
  * Database Module
3
3
  *
4
4
  * This module provides a flexible database system with support for
5
- * multiple backends through a factory pattern.
6
- *
7
- * ## Built-in Factories
8
- * - `in-memory`: Store data in RAM (for testing/development)
9
- * - `sqlite`: Store data in a local SQLite file
10
- * - `postgres`: Store data in PostgreSQL server
11
- *
12
- * ## Custom Factories
13
- * Product layers (CLI/server/platform) decide which factories are available by including them
14
- * in images (`DextoImage.storage.database`).
5
+ * multiple concrete backends.
15
6
  *
16
7
  * ## Usage
17
- * Database backends are typically constructed by the product-layer resolver (`@dexto/agent-config`)
18
- * via image-provided factory maps. For direct usage, call a factory's `create()` after validating
19
- * config with its `configSchema`.
8
+ * Database backends are typically constructed by an image's storage implementation after
9
+ * validating config with the matching schema.
20
10
  */
21
- export type { DatabaseFactory } from './factory.js';
22
11
  export type { Database } from './types.js';
23
- export { inMemoryDatabaseFactory, sqliteDatabaseFactory, postgresDatabaseFactory, } from './factories/index.js';
24
12
  export { DATABASE_TYPES, DatabaseConfigSchema, InMemoryDatabaseSchema, SqliteDatabaseSchema, PostgresDatabaseSchema, type DatabaseType, type DatabaseConfig, type InMemoryDatabaseConfig, type SqliteDatabaseConfig, type PostgresDatabaseConfig, } from './schemas.js';
25
13
  export { MemoryDatabaseStore } from './memory-database-store.js';
14
+ export { SQLiteStore } from './sqlite-store.js';
15
+ export { PostgresStore } from './postgres-store.js';
26
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EACH,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,GAC1B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACH,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC9B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EACH,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC9B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,8 +1,3 @@
1
- import {
2
- inMemoryDatabaseFactory,
3
- sqliteDatabaseFactory,
4
- postgresDatabaseFactory
5
- } from "./factories/index.js";
6
1
  import {
7
2
  DATABASE_TYPES,
8
3
  DatabaseConfigSchema,
@@ -11,14 +6,15 @@ import {
11
6
  PostgresDatabaseSchema
12
7
  } from "./schemas.js";
13
8
  import { MemoryDatabaseStore } from "./memory-database-store.js";
9
+ import { SQLiteStore } from "./sqlite-store.js";
10
+ import { PostgresStore } from "./postgres-store.js";
14
11
  export {
15
12
  DATABASE_TYPES,
16
13
  DatabaseConfigSchema,
17
14
  InMemoryDatabaseSchema,
18
15
  MemoryDatabaseStore,
19
16
  PostgresDatabaseSchema,
20
- SqliteDatabaseSchema,
21
- inMemoryDatabaseFactory,
22
- postgresDatabaseFactory,
23
- sqliteDatabaseFactory
17
+ PostgresStore,
18
+ SQLiteStore,
19
+ SqliteDatabaseSchema
24
20
  };
@@ -65,6 +65,22 @@ class MemoryDatabaseStore {
65
65
  );
66
66
  }
67
67
  }
68
+ async setIfAbsent(key, value) {
69
+ this.checkConnection();
70
+ try {
71
+ if (this.data.has(key)) {
72
+ return { value: this.data.get(key), inserted: false };
73
+ }
74
+ this.data.set(key, value);
75
+ return { value, inserted: true };
76
+ } catch (error) {
77
+ throw import_core.StorageError.writeFailed(
78
+ "setIfAbsent",
79
+ error instanceof Error ? error.message : String(error),
80
+ { key }
81
+ );
82
+ }
83
+ }
68
84
  async delete(key) {
69
85
  this.checkConnection();
70
86
  this.data.delete(key);
@@ -14,6 +14,10 @@ export declare class MemoryDatabaseStore implements Database {
14
14
  getStoreType(): string;
15
15
  get<T>(key: string): Promise<T | undefined>;
16
16
  set<T>(key: string, value: T): Promise<void>;
17
+ setIfAbsent<T>(key: string, value: T): Promise<{
18
+ value: T;
19
+ inserted: boolean;
20
+ }>;
17
21
  delete(key: string): Promise<void>;
18
22
  list(prefix: string): Promise<string[]>;
19
23
  append<T>(key: string, item: T): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"memory-database-store.d.ts","sourceRoot":"","sources":["../../src/database/memory-database-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAChD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,SAAS,CAAS;IAEpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;IAIhB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAa3C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAsBvC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAO1E,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC;CAM7F"}
1
+ {"version":3,"file":"memory-database-store.d.ts","sourceRoot":"","sources":["../../src/database/memory-database-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAChD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,SAAS,CAAS;IAEpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;IAIhB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAa3C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5C,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAiB/E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAsBvC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAO1E,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC;CAM7F"}
@@ -42,6 +42,22 @@ class MemoryDatabaseStore {
42
42
  );
43
43
  }
44
44
  }
45
+ async setIfAbsent(key, value) {
46
+ this.checkConnection();
47
+ try {
48
+ if (this.data.has(key)) {
49
+ return { value: this.data.get(key), inserted: false };
50
+ }
51
+ this.data.set(key, value);
52
+ return { value, inserted: true };
53
+ } catch (error) {
54
+ throw StorageError.writeFailed(
55
+ "setIfAbsent",
56
+ error instanceof Error ? error.message : String(error),
57
+ { key }
58
+ );
59
+ }
60
+ }
45
61
  async delete(key) {
46
62
  this.checkConnection();
47
63
  this.data.delete(key);
@@ -163,6 +163,31 @@ class PostgresStore {
163
163
  );
164
164
  }
165
165
  }
166
+ async setIfAbsent(key, value) {
167
+ try {
168
+ return await this.withRetry("setIfAbsent", async (client) => {
169
+ const jsonValue = JSON.stringify(value);
170
+ const inserted = await client.query(
171
+ "INSERT INTO kv (key, value, updated_at) VALUES ($1, $2::jsonb, $3) ON CONFLICT (key) DO NOTHING RETURNING value",
172
+ [key, jsonValue, /* @__PURE__ */ new Date()]
173
+ );
174
+ if (inserted.rows[0]) {
175
+ return { value: inserted.rows[0].value, inserted: true };
176
+ }
177
+ const existing = await client.query("SELECT value FROM kv WHERE key = $1", [key]);
178
+ return {
179
+ value: existing.rows[0] ? existing.rows[0].value : value,
180
+ inserted: false
181
+ };
182
+ });
183
+ } catch (error) {
184
+ throw import_core.StorageError.writeFailed(
185
+ "setIfAbsent",
186
+ error instanceof Error ? error.message : String(error),
187
+ { key }
188
+ );
189
+ }
190
+ }
166
191
  async delete(key) {
167
192
  await this.withRetry("delete", async (client) => {
168
193
  await client.query("BEGIN");
@@ -23,6 +23,10 @@ export declare class PostgresStore implements Database {
23
23
  getStoreType(): string;
24
24
  get<T>(key: string): Promise<T | undefined>;
25
25
  set<T>(key: string, value: T): Promise<void>;
26
+ setIfAbsent<T>(key: string, value: T): Promise<{
27
+ value: T;
28
+ inserted: boolean;
29
+ }>;
26
30
  delete(key: string): Promise<void>;
27
31
  list(prefix: string): Promise<string[]>;
28
32
  append<T>(key: string, item: T): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/database/postgres-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,IAAI,CAAC;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C;;;;GAIG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAMtC,OAAO,CAAC,MAAM;IALlB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;gBAGX,MAAM,EAAE,sBAAsB,EACtC,MAAM,EAAE,MAAM;IAKZ,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+F9B;;OAEG;YACW,YAAY;IAmBpB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;IAKhB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAe3C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBvC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9C,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;YAW5D,YAAY;IA4B1B,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;OAGG;YACW,SAAS;IA8CvB;;;;OAIG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAcxE,QAAQ,IAAI,OAAO,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IAkBI,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAKhC"}
1
+ {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/database/postgres-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,IAAI,CAAC;AACtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C;;;;GAIG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAMtC,OAAO,CAAC,MAAM;IALlB,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;gBAGX,MAAM,EAAE,sBAAsB,EACtC,MAAM,EAAE,MAAM;IAKZ,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+F9B;;OAEG;YACW,YAAY;IAmBpB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,MAAM;IAKhB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAe3C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5C,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IA2B/E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBvC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9C,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;YAW5D,YAAY;IA4B1B,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;OAGG;YACW,SAAS;IA8CvB;;;;OAIG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAcxE,QAAQ,IAAI,OAAO,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IAkBI,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAKhC"}
@@ -140,6 +140,31 @@ class PostgresStore {
140
140
  );
141
141
  }
142
142
  }
143
+ async setIfAbsent(key, value) {
144
+ try {
145
+ return await this.withRetry("setIfAbsent", async (client) => {
146
+ const jsonValue = JSON.stringify(value);
147
+ const inserted = await client.query(
148
+ "INSERT INTO kv (key, value, updated_at) VALUES ($1, $2::jsonb, $3) ON CONFLICT (key) DO NOTHING RETURNING value",
149
+ [key, jsonValue, /* @__PURE__ */ new Date()]
150
+ );
151
+ if (inserted.rows[0]) {
152
+ return { value: inserted.rows[0].value, inserted: true };
153
+ }
154
+ const existing = await client.query("SELECT value FROM kv WHERE key = $1", [key]);
155
+ return {
156
+ value: existing.rows[0] ? existing.rows[0].value : value,
157
+ inserted: false
158
+ };
159
+ });
160
+ } catch (error) {
161
+ throw StorageError.writeFailed(
162
+ "setIfAbsent",
163
+ error instanceof Error ? error.message : String(error),
164
+ { key }
165
+ );
166
+ }
167
+ }
143
168
  async delete(key) {
144
169
  await this.withRetry("delete", async (client) => {
145
170
  await client.query("BEGIN");
@@ -26,7 +26,7 @@ __export(schemas_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(schemas_exports);
28
28
  var import_zod = require("zod");
29
- var import_core = require("@dexto/core");
29
+ var import_config = require("@dexto/core/config");
30
30
  const DATABASE_TYPES = ["in-memory", "sqlite", "postgres"];
31
31
  const BaseDatabaseSchema = import_zod.z.object({
32
32
  maxConnections: import_zod.z.number().int().positive().optional().describe("Maximum connections"),
@@ -46,8 +46,8 @@ const SqliteDatabaseSchema = BaseDatabaseSchema.extend({
46
46
  }).strict();
47
47
  const PostgresDatabaseSchema = BaseDatabaseSchema.extend({
48
48
  type: import_zod.z.literal("postgres"),
49
- url: (0, import_core.EnvExpandedString)().optional().describe("PostgreSQL connection URL (postgresql://...)"),
50
- connectionString: (0, import_core.EnvExpandedString)().optional().describe("PostgreSQL connection string"),
49
+ url: (0, import_config.EnvExpandedString)().optional().describe("PostgreSQL connection URL (postgresql://...)"),
50
+ connectionString: (0, import_config.EnvExpandedString)().optional().describe("PostgreSQL connection string"),
51
51
  host: import_zod.z.string().optional().describe("PostgreSQL host"),
52
52
  port: import_zod.z.number().int().positive().optional().describe("PostgreSQL port"),
53
53
  database: import_zod.z.string().optional().describe("PostgreSQL database name"),
@@ -62,9 +62,9 @@ const PostgresDatabaseSchema = BaseDatabaseSchema.extend({
62
62
  message: "PostgreSQL database requires one of 'url', 'connectionString', or 'host' to be specified",
63
63
  path: ["url"],
64
64
  params: {
65
- code: import_core.StorageErrorCode.CONNECTION_CONFIG_MISSING,
66
- scope: import_core.ErrorScope.STORAGE,
67
- type: import_core.ErrorType.USER
65
+ code: import_config.StorageErrorCode.CONNECTION_CONFIG_MISSING,
66
+ scope: import_config.ErrorScope.STORAGE,
67
+ type: import_config.ErrorType.USER
68
68
  }
69
69
  });
70
70
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { EnvExpandedString, ErrorScope, ErrorType, StorageErrorCode } from "@dexto/core";
2
+ import { EnvExpandedString, ErrorScope, ErrorType, StorageErrorCode } from "@dexto/core/config";
3
3
  const DATABASE_TYPES = ["in-memory", "sqlite", "postgres"];
4
4
  const BaseDatabaseSchema = z.object({
5
5
  maxConnections: z.number().int().positive().optional().describe("Maximum connections"),
@@ -177,6 +177,24 @@ class SQLiteStore {
177
177
  );
178
178
  }
179
179
  }
180
+ async setIfAbsent(key, value) {
181
+ this.checkConnection();
182
+ try {
183
+ const serialized = JSON.stringify(value);
184
+ const result = this.db.prepare("INSERT OR IGNORE INTO kv_store (key, value, updated_at) VALUES (?, ?, ?)").run(key, serialized, Date.now());
185
+ const row = this.db.prepare("SELECT value FROM kv_store WHERE key = ?").get(key);
186
+ return {
187
+ value: row ? JSON.parse(row.value) : value,
188
+ inserted: result.changes > 0
189
+ };
190
+ } catch (error) {
191
+ throw import_core.StorageError.writeFailed(
192
+ "setIfAbsent",
193
+ error instanceof Error ? error.message : String(error),
194
+ { key }
195
+ );
196
+ }
197
+ }
180
198
  async delete(key) {
181
199
  this.checkConnection();
182
200
  try {
@@ -18,6 +18,10 @@ export declare class SQLiteStore implements Database {
18
18
  getStoreType(): string;
19
19
  get<T>(key: string): Promise<T | undefined>;
20
20
  set<T>(key: string, value: T): Promise<void>;
21
+ setIfAbsent<T>(key: string, value: T): Promise<{
22
+ value: T;
23
+ inserted: boolean;
24
+ }>;
21
25
  delete(key: string): Promise<void>;
22
26
  list(prefix: string): Promise<string[]>;
23
27
  append<T>(key: string, item: T): Promise<void>;