@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.
- package/README.md +51 -38
- package/dist/blob/index.cjs +2 -7
- package/dist/blob/index.d.ts +3 -14
- package/dist/blob/index.d.ts.map +1 -1
- package/dist/blob/index.js +1 -4
- package/dist/cache/index.cjs +3 -5
- package/dist/cache/index.d.ts +4 -14
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +2 -3
- package/dist/cache/schemas.cjs +5 -5
- package/dist/cache/schemas.js +1 -1
- package/dist/database/index.cjs +8 -9
- package/dist/database/index.d.ts +5 -15
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +5 -9
- package/dist/database/memory-database-store.cjs +16 -0
- package/dist/database/memory-database-store.d.ts +4 -0
- package/dist/database/memory-database-store.d.ts.map +1 -1
- package/dist/database/memory-database-store.js +16 -0
- package/dist/database/postgres-store.cjs +25 -0
- package/dist/database/postgres-store.d.ts +4 -0
- package/dist/database/postgres-store.d.ts.map +1 -1
- package/dist/database/postgres-store.js +25 -0
- package/dist/database/schemas.cjs +6 -6
- package/dist/database/schemas.js +1 -1
- package/dist/database/sqlite-store.cjs +18 -0
- package/dist/database/sqlite-store.d.ts +4 -0
- package/dist/database/sqlite-store.d.ts.map +1 -1
- package/dist/database/sqlite-store.js +18 -0
- package/dist/index.cjs +12 -19
- package/dist/index.d.cts +17 -225
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -15
- package/package.json +3 -3
- package/dist/blob/factories/index.cjs +0 -31
- package/dist/blob/factories/index.d.ts +0 -6
- package/dist/blob/factories/index.d.ts.map +0 -1
- package/dist/blob/factories/index.js +0 -6
- package/dist/blob/factories/local.cjs +0 -38
- package/dist/blob/factories/local.d.ts +0 -17
- package/dist/blob/factories/local.d.ts.map +0 -1
- package/dist/blob/factories/local.js +0 -14
- package/dist/blob/factories/memory.cjs +0 -44
- package/dist/blob/factories/memory.d.ts +0 -17
- package/dist/blob/factories/memory.d.ts.map +0 -1
- package/dist/blob/factories/memory.js +0 -20
- package/dist/blob/factory.cjs +0 -16
- package/dist/blob/factory.d.ts +0 -35
- package/dist/blob/factory.d.ts.map +0 -1
- package/dist/blob/factory.js +0 -0
- package/dist/cache/factories/index.cjs +0 -31
- package/dist/cache/factories/index.d.ts +0 -6
- package/dist/cache/factories/index.d.ts.map +0 -1
- package/dist/cache/factories/index.js +0 -6
- package/dist/cache/factories/memory.cjs +0 -39
- package/dist/cache/factories/memory.d.ts +0 -17
- package/dist/cache/factories/memory.d.ts.map +0 -1
- package/dist/cache/factories/memory.js +0 -15
- package/dist/cache/factories/redis.cjs +0 -65
- package/dist/cache/factories/redis.d.ts +0 -20
- package/dist/cache/factories/redis.d.ts.map +0 -1
- package/dist/cache/factories/redis.js +0 -31
- package/dist/cache/factory.cjs +0 -16
- package/dist/cache/factory.d.ts +0 -41
- package/dist/cache/factory.d.ts.map +0 -1
- package/dist/cache/factory.js +0 -0
- package/dist/database/factories/index.cjs +0 -34
- package/dist/database/factories/index.d.ts +0 -7
- package/dist/database/factories/index.d.ts.map +0 -1
- package/dist/database/factories/index.js +0 -8
- package/dist/database/factories/memory.cjs +0 -39
- package/dist/database/factories/memory.d.ts +0 -16
- package/dist/database/factories/memory.d.ts.map +0 -1
- package/dist/database/factories/memory.js +0 -15
- package/dist/database/factories/postgres.cjs +0 -61
- package/dist/database/factories/postgres.d.ts +0 -19
- package/dist/database/factories/postgres.d.ts.map +0 -1
- package/dist/database/factories/postgres.js +0 -27
- package/dist/database/factories/sqlite.cjs +0 -65
- package/dist/database/factories/sqlite.d.ts +0 -20
- package/dist/database/factories/sqlite.d.ts.map +0 -1
- package/dist/database/factories/sqlite.js +0 -31
- package/dist/database/factory.cjs +0 -16
- package/dist/database/factory.d.ts +0 -41
- package/dist/database/factory.d.ts.map +0 -1
- package/dist/database/factory.js +0 -0
package/README.md
CHANGED
|
@@ -1,38 +1,73 @@
|
|
|
1
1
|
# `@dexto/storage`
|
|
2
2
|
|
|
3
|
-
Concrete storage
|
|
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
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
22
|
+
## Using helpers in an image
|
|
21
23
|
|
|
22
24
|
```ts
|
|
23
25
|
import type { DextoImage } from '@dexto/agent-config';
|
|
24
26
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
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.
|
package/dist/blob/index.cjs
CHANGED
|
@@ -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
|
});
|
package/dist/blob/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
17
|
-
*
|
|
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';
|
package/dist/blob/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blob/index.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/blob/index.js
CHANGED
|
@@ -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
|
};
|
package/dist/cache/index.cjs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
41
|
-
redisCacheFactory
|
|
39
|
+
RedisStore
|
|
42
40
|
});
|
package/dist/cache/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
17
|
-
*
|
|
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
|
|
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"}
|
package/dist/cache/index.js
CHANGED
|
@@ -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
|
-
|
|
16
|
-
redisCacheFactory
|
|
15
|
+
RedisStore
|
|
17
16
|
};
|
package/dist/cache/schemas.cjs
CHANGED
|
@@ -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
|
|
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,
|
|
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:
|
|
55
|
-
scope:
|
|
56
|
-
type:
|
|
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
|
}
|
package/dist/cache/schemas.js
CHANGED
|
@@ -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"),
|
package/dist/database/index.cjs
CHANGED
|
@@ -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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
sqliteDatabaseFactory
|
|
42
|
+
PostgresStore,
|
|
43
|
+
SQLiteStore,
|
|
44
|
+
SqliteDatabaseSchema
|
|
46
45
|
});
|
package/dist/database/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
18
|
-
*
|
|
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
|
|
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"}
|
package/dist/database/index.js
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
|
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,
|
|
50
|
-
connectionString: (0,
|
|
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:
|
|
66
|
-
scope:
|
|
67
|
-
type:
|
|
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
|
}
|
package/dist/database/schemas.js
CHANGED
|
@@ -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>;
|