@strands-agents/sdk 1.9.0 → 1.11.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 +1 -1
- package/dist/src/agent/agent.d.ts +22 -42
- package/dist/src/agent/agent.d.ts.map +1 -1
- package/dist/src/agent/agent.js +73 -426
- package/dist/src/agent/agent.js.map +1 -1
- package/dist/src/context-manager/modes/agentic/agentic-context.d.ts +2 -2
- package/dist/src/errors.d.ts +15 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +18 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/hooks/events.d.ts +5 -4
- package/dist/src/hooks/events.d.ts.map +1 -1
- package/dist/src/hooks/events.js +3 -3
- package/dist/src/hooks/events.js.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.node.d.ts.map +1 -1
- package/dist/src/index.node.js +2 -6
- package/dist/src/index.node.js.map +1 -1
- package/dist/src/middleware/interrupt.d.ts +18 -0
- package/dist/src/middleware/interrupt.d.ts.map +1 -0
- package/dist/src/middleware/interrupt.js +33 -0
- package/dist/src/middleware/interrupt.js.map +1 -0
- package/dist/src/models/bedrock.d.ts.map +1 -1
- package/dist/src/models/bedrock.js +23 -1
- package/dist/src/models/bedrock.js.map +1 -1
- package/dist/src/models/openai/errors.d.ts.map +1 -1
- package/dist/src/models/openai/errors.js +1 -0
- package/dist/src/models/openai/errors.js.map +1 -1
- package/dist/src/models/openai/mantle.d.ts +8 -3
- package/dist/src/models/openai/mantle.d.ts.map +1 -1
- package/dist/src/models/openai/mantle.js +41 -6
- package/dist/src/models/openai/mantle.js.map +1 -1
- package/dist/src/models/openai/model.d.ts.map +1 -1
- package/dist/src/models/openai/model.js +4 -3
- package/dist/src/models/openai/model.js.map +1 -1
- package/dist/src/models/openai/responses-adapter.d.ts.map +1 -1
- package/dist/src/models/openai/responses-adapter.js +41 -9
- package/dist/src/models/openai/responses-adapter.js.map +1 -1
- package/dist/src/models/vercel.d.ts.map +1 -1
- package/dist/src/models/vercel.js +28 -1
- package/dist/src/models/vercel.js.map +1 -1
- package/dist/src/multiagent/graph.d.ts.map +1 -1
- package/dist/src/multiagent/graph.js +1 -1
- package/dist/src/multiagent/graph.js.map +1 -1
- package/dist/src/{multiagent/queue.d.ts → queue.d.ts} +12 -27
- package/dist/src/queue.d.ts.map +1 -0
- package/dist/src/{multiagent/queue.js → queue.js} +4 -2
- package/dist/src/queue.js.map +1 -0
- package/dist/src/register-node-defaults.d.ts +3 -0
- package/dist/src/register-node-defaults.d.ts.map +1 -0
- package/dist/src/register-node-defaults.js +10 -0
- package/dist/src/register-node-defaults.js.map +1 -0
- package/dist/src/sandbox/register-node-defaults.d.ts +3 -0
- package/dist/src/sandbox/register-node-defaults.d.ts.map +1 -0
- package/dist/src/sandbox/register-node-defaults.js +8 -0
- package/dist/src/sandbox/register-node-defaults.js.map +1 -0
- package/dist/src/session/file-storage.d.ts +3 -0
- package/dist/src/session/file-storage.d.ts.map +1 -1
- package/dist/src/session/file-storage.js +3 -0
- package/dist/src/session/file-storage.js.map +1 -1
- package/dist/src/session/s3-storage.d.ts +3 -0
- package/dist/src/session/s3-storage.d.ts.map +1 -1
- package/dist/src/session/s3-storage.js +3 -0
- package/dist/src/session/s3-storage.js.map +1 -1
- package/dist/src/session/session-manager.d.ts +11 -2
- package/dist/src/session/session-manager.d.ts.map +1 -1
- package/dist/src/session/session-manager.js +19 -8
- package/dist/src/session/session-manager.js.map +1 -1
- package/dist/src/session/snapshot-storage-adapter.d.ts +93 -0
- package/dist/src/session/snapshot-storage-adapter.d.ts.map +1 -0
- package/dist/src/session/snapshot-storage-adapter.js +157 -0
- package/dist/src/session/snapshot-storage-adapter.js.map +1 -0
- package/dist/src/session/storage.d.ts +3 -6
- package/dist/src/session/storage.d.ts.map +1 -1
- package/dist/src/storage/in-memory-storage.d.ts +64 -0
- package/dist/src/storage/in-memory-storage.d.ts.map +1 -0
- package/dist/src/storage/in-memory-storage.js +85 -0
- package/dist/src/storage/in-memory-storage.js.map +1 -0
- package/dist/src/storage/index.d.ts +20 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +18 -0
- package/dist/src/storage/index.js.map +1 -0
- package/dist/src/storage/local-file-storage.d.ts +81 -0
- package/dist/src/storage/local-file-storage.d.ts.map +1 -0
- package/dist/src/storage/local-file-storage.js +244 -0
- package/dist/src/storage/local-file-storage.js.map +1 -0
- package/dist/src/storage/s3-storage.d.ts +73 -0
- package/dist/src/storage/s3-storage.d.ts.map +1 -0
- package/dist/src/storage/s3-storage.js +146 -0
- package/dist/src/storage/s3-storage.js.map +1 -0
- package/dist/src/storage/storage.d.ts +102 -0
- package/dist/src/storage/storage.d.ts.map +1 -0
- package/dist/src/storage/storage.js +68 -0
- package/dist/src/storage/storage.js.map +1 -0
- package/dist/src/telemetry/tracer.d.ts +18 -0
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +31 -11
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/tools/executors/concurrent.d.ts +32 -0
- package/dist/src/tools/executors/concurrent.d.ts.map +1 -0
- package/dist/src/tools/executors/concurrent.js +128 -0
- package/dist/src/tools/executors/concurrent.js.map +1 -0
- package/dist/src/tools/executors/executor.d.ts +61 -0
- package/dist/src/tools/executors/executor.d.ts.map +1 -0
- package/dist/src/tools/executors/executor.js +190 -0
- package/dist/src/tools/executors/executor.js.map +1 -0
- package/dist/src/tools/executors/sequential.d.ts +30 -0
- package/dist/src/tools/executors/sequential.d.ts.map +1 -0
- package/dist/src/tools/executors/sequential.js +67 -0
- package/dist/src/tools/executors/sequential.js.map +1 -0
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/types/agent.d.ts +5 -4
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/agent.js.map +1 -1
- package/dist/src/vended-memory-stores/test-memory-store/store.d.ts +32 -24
- package/dist/src/vended-memory-stores/test-memory-store/store.d.ts.map +1 -1
- package/dist/src/vended-memory-stores/test-memory-store/store.js +84 -91
- package/dist/src/vended-memory-stores/test-memory-store/store.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/plugin.d.ts +37 -5
- package/dist/src/vended-plugins/context-offloader/plugin.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/plugin.js +116 -17
- package/dist/src/vended-plugins/context-offloader/plugin.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.d.ts +23 -9
- package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.js +21 -6
- package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
- package/dist/src/vended-tools/index.d.ts +3 -1
- package/dist/src/vended-tools/index.d.ts.map +1 -1
- package/dist/src/vended-tools/index.js +3 -1
- package/dist/src/vended-tools/index.js.map +1 -1
- package/dist/src/vended-tools/notebook/notebook.d.ts +1 -1
- package/dist/src/vended-tools/sleep/index.d.ts +9 -0
- package/dist/src/vended-tools/sleep/index.d.ts.map +1 -0
- package/dist/src/vended-tools/sleep/index.js +7 -0
- package/dist/src/vended-tools/sleep/index.js.map +1 -0
- package/dist/src/vended-tools/sleep/make-sleep.d.ts +48 -0
- package/dist/src/vended-tools/sleep/make-sleep.d.ts.map +1 -0
- package/dist/src/vended-tools/sleep/make-sleep.js +81 -0
- package/dist/src/vended-tools/sleep/make-sleep.js.map +1 -0
- package/dist/src/vended-tools/sleep/sleep.d.ts +19 -0
- package/dist/src/vended-tools/sleep/sleep.d.ts.map +1 -0
- package/dist/src/vended-tools/sleep/sleep.js +20 -0
- package/dist/src/vended-tools/sleep/sleep.js.map +1 -0
- package/dist/src/vended-tools/sleep/types.d.ts +31 -0
- package/dist/src/vended-tools/sleep/types.d.ts.map +1 -0
- package/dist/src/vended-tools/sleep/types.js +22 -0
- package/dist/src/vended-tools/sleep/types.js.map +1 -0
- package/dist/src/vended-tools/stop/index.d.ts +8 -0
- package/dist/src/vended-tools/stop/index.d.ts.map +1 -0
- package/dist/src/vended-tools/stop/index.js +6 -0
- package/dist/src/vended-tools/stop/index.js.map +1 -0
- package/dist/src/vended-tools/stop/stop.d.ts +47 -0
- package/dist/src/vended-tools/stop/stop.d.ts.map +1 -0
- package/dist/src/vended-tools/stop/stop.js +85 -0
- package/dist/src/vended-tools/stop/stop.js.map +1 -0
- package/dist/src/vended-tools/stop/types.d.ts +54 -0
- package/dist/src/vended-tools/stop/types.d.ts.map +1 -0
- package/dist/src/vended-tools/stop/types.js +58 -0
- package/dist/src/vended-tools/stop/types.js.map +1 -0
- package/package.json +13 -2
- package/dist/src/conversation-manager/index.d.ts +0 -10
- package/dist/src/conversation-manager/index.d.ts.map +0 -1
- package/dist/src/conversation-manager/index.js +0 -10
- package/dist/src/conversation-manager/index.js.map +0 -1
- package/dist/src/multiagent/queue.d.ts.map +0 -1
- package/dist/src/multiagent/queue.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-storage.js","sourceRoot":"","sources":["../../../src/storage/in-memory-storage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEvE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,eAAe;IACT,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAA;IAEvD;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,IAAgB;QACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAClD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;QAChD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QACpC,OAAO,KAAK,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;IACvC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;QAC1C,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,6EAA6E;IAC7E,SAAS,CAAC,MAAc;QACtB,OAAO,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAChC,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified storage module.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link Storage} interface and shipped implementations for persisting
|
|
5
|
+
* raw bytes under string keys. All SDK subsystems that need persistence — sessions,
|
|
6
|
+
* memory, context offloading, transcripts — consume this interface.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { LocalFileStorage, InMemoryStorage } from '@strands-agents/sdk/storage'
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
export type { Storage } from './storage.js';
|
|
16
|
+
export { InMemoryStorage } from './in-memory-storage.js';
|
|
17
|
+
export { LocalFileStorage } from './local-file-storage.js';
|
|
18
|
+
export { S3Storage } from './s3-storage.js';
|
|
19
|
+
export type { S3StorageConfig } from './s3-storage.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified storage module.
|
|
3
|
+
*
|
|
4
|
+
* Provides the {@link Storage} interface and shipped implementations for persisting
|
|
5
|
+
* raw bytes under string keys. All SDK subsystems that need persistence — sessions,
|
|
6
|
+
* memory, context offloading, transcripts — consume this interface.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { LocalFileStorage, InMemoryStorage } from '@strands-agents/sdk/storage'
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
export { InMemoryStorage } from './in-memory-storage.js';
|
|
16
|
+
export { LocalFileStorage } from './local-file-storage.js';
|
|
17
|
+
export { S3Storage } from './s3-storage.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Sandbox } from '../sandbox/base.js';
|
|
2
|
+
import type { Storage } from './storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Local-filesystem {@link Storage} backend.
|
|
5
|
+
*
|
|
6
|
+
* Persists each key as a file under a base directory, mapping the key's `/` segments
|
|
7
|
+
* onto directory segments. On the host filesystem, writes are atomic (write to a
|
|
8
|
+
* scratch sibling, then rename) so a crash mid-write never leaves a partially written
|
|
9
|
+
* file. When bound to a {@link Sandbox} via {@link forSandbox}, all I/O is routed
|
|
10
|
+
* through that sandbox instead of the host's `node:fs` (atomicity depends on the
|
|
11
|
+
* sandbox implementation).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { LocalFileStorage } from '@strands-agents/sdk/storage'
|
|
16
|
+
*
|
|
17
|
+
* const storage = new LocalFileStorage('./.strands/')
|
|
18
|
+
* await storage.write('sessions/abc/snapshot.json', bytes)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class LocalFileStorage implements Storage {
|
|
22
|
+
private readonly _baseDir;
|
|
23
|
+
private readonly _sandbox;
|
|
24
|
+
/**
|
|
25
|
+
* @param baseDir - Root directory under which keys are stored. Defaults to `./.strands/`.
|
|
26
|
+
* @param sandbox - Optional sandbox to route I/O through. Usually set via {@link forSandbox}.
|
|
27
|
+
*/
|
|
28
|
+
constructor(baseDir?: string, sandbox?: Sandbox);
|
|
29
|
+
/**
|
|
30
|
+
* Returns a storage instance whose I/O is routed through `sandbox`.
|
|
31
|
+
*
|
|
32
|
+
* Instances already bound to a sandbox return themselves unchanged.
|
|
33
|
+
*
|
|
34
|
+
* @param sandbox - Sandbox to route the returned instance's I/O through
|
|
35
|
+
* @returns A new `LocalFileStorage` with the same base directory, routed through `sandbox`
|
|
36
|
+
*/
|
|
37
|
+
forSandbox(sandbox: Sandbox): LocalFileStorage;
|
|
38
|
+
/**
|
|
39
|
+
* Stores `data` under `key`, overwriting any existing value.
|
|
40
|
+
*
|
|
41
|
+
* @param key - Opaque, `/`-separated key identifying the value
|
|
42
|
+
* @param data - Raw bytes to persist
|
|
43
|
+
* @throws {@link StorageError} if the key is invalid or the write fails
|
|
44
|
+
*/
|
|
45
|
+
write(key: string, data: Uint8Array): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Retrieves the bytes previously stored under `key`.
|
|
48
|
+
*
|
|
49
|
+
* @param key - The key to read
|
|
50
|
+
* @returns The stored bytes, or `null` if no value exists for `key`
|
|
51
|
+
* @throws {@link StorageError} if the key is invalid or the read fails
|
|
52
|
+
*/
|
|
53
|
+
read(key: string): Promise<Uint8Array | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Deletes the value stored under `key`. A no-op if the key does not exist.
|
|
56
|
+
*
|
|
57
|
+
* @param key - The key to delete
|
|
58
|
+
* @throws {@link StorageError} if the key is invalid or the delete fails
|
|
59
|
+
*/
|
|
60
|
+
delete(key: string): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Lists the keys whose names begin with `prefix`, sorted lexicographically.
|
|
63
|
+
*
|
|
64
|
+
* @param prefix - Key prefix to match. An empty string matches all keys.
|
|
65
|
+
* @returns The matching keys, sorted ascending
|
|
66
|
+
* @throws {@link StorageError} if the prefix is invalid or the listing fails
|
|
67
|
+
*/
|
|
68
|
+
list(prefix: string): Promise<string[]>;
|
|
69
|
+
private _pathFor;
|
|
70
|
+
private _listKeysHost;
|
|
71
|
+
private _listKeysSandbox;
|
|
72
|
+
/**
|
|
73
|
+
* Returns a prefixed view of this storage without mutating the original.
|
|
74
|
+
* The returned view preserves `forSandbox` for single-level namespacing;
|
|
75
|
+
* nested `.namespace()` calls on the view do not carry sandbox routing.
|
|
76
|
+
*/
|
|
77
|
+
namespace(prefix: string): Storage & {
|
|
78
|
+
forSandbox(sandbox: Sandbox): Storage;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=local-file-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-file-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/local-file-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAgB3C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAE9C;;;OAGG;gBACS,OAAO,GAAE,MAAsB,EAAE,OAAO,CAAC,EAAE,OAAO;IAK9D;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB;IAK9C;;;;;;OAMG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BzD;;;;;;OAMG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAqBnD;;;;;OAKG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxC;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAa7C,OAAO,CAAC,QAAQ;YAKF,aAAa;YA2Bb,gBAAgB;IA2B9B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG;QAAE,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAA;KAAE;CAO/E"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { StorageError } from '../errors.js';
|
|
2
|
+
import { namespace, normalizeKey, normalizePrefix } from './storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if the error represents a missing or non-directory path (ENOENT or ENOTDIR).
|
|
5
|
+
*
|
|
6
|
+
* @param error - The caught error to inspect
|
|
7
|
+
* @returns Whether the error is a filesystem not-found error
|
|
8
|
+
*/
|
|
9
|
+
function isNotFoundError(error) {
|
|
10
|
+
if (error === null || typeof error !== 'object' || !('code' in error))
|
|
11
|
+
return false;
|
|
12
|
+
return error.code === 'ENOENT' || error.code === 'ENOTDIR';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Local-filesystem {@link Storage} backend.
|
|
16
|
+
*
|
|
17
|
+
* Persists each key as a file under a base directory, mapping the key's `/` segments
|
|
18
|
+
* onto directory segments. On the host filesystem, writes are atomic (write to a
|
|
19
|
+
* scratch sibling, then rename) so a crash mid-write never leaves a partially written
|
|
20
|
+
* file. When bound to a {@link Sandbox} via {@link forSandbox}, all I/O is routed
|
|
21
|
+
* through that sandbox instead of the host's `node:fs` (atomicity depends on the
|
|
22
|
+
* sandbox implementation).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { LocalFileStorage } from '@strands-agents/sdk/storage'
|
|
27
|
+
*
|
|
28
|
+
* const storage = new LocalFileStorage('./.strands/')
|
|
29
|
+
* await storage.write('sessions/abc/snapshot.json', bytes)
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class LocalFileStorage {
|
|
33
|
+
_baseDir;
|
|
34
|
+
_sandbox;
|
|
35
|
+
/**
|
|
36
|
+
* @param baseDir - Root directory under which keys are stored. Defaults to `./.strands/`.
|
|
37
|
+
* @param sandbox - Optional sandbox to route I/O through. Usually set via {@link forSandbox}.
|
|
38
|
+
*/
|
|
39
|
+
constructor(baseDir = './.strands/', sandbox) {
|
|
40
|
+
this._baseDir = baseDir;
|
|
41
|
+
this._sandbox = sandbox;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Returns a storage instance whose I/O is routed through `sandbox`.
|
|
45
|
+
*
|
|
46
|
+
* Instances already bound to a sandbox return themselves unchanged.
|
|
47
|
+
*
|
|
48
|
+
* @param sandbox - Sandbox to route the returned instance's I/O through
|
|
49
|
+
* @returns A new `LocalFileStorage` with the same base directory, routed through `sandbox`
|
|
50
|
+
*/
|
|
51
|
+
forSandbox(sandbox) {
|
|
52
|
+
if (this._sandbox)
|
|
53
|
+
return this;
|
|
54
|
+
return new LocalFileStorage(this._baseDir, sandbox);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Stores `data` under `key`, overwriting any existing value.
|
|
58
|
+
*
|
|
59
|
+
* @param key - Opaque, `/`-separated key identifying the value
|
|
60
|
+
* @param data - Raw bytes to persist
|
|
61
|
+
* @throws {@link StorageError} if the key is invalid or the write fails
|
|
62
|
+
*/
|
|
63
|
+
async write(key, data) {
|
|
64
|
+
const normalized = normalizeKey(key);
|
|
65
|
+
const path = this._pathFor(normalized);
|
|
66
|
+
if (this._sandbox) {
|
|
67
|
+
try {
|
|
68
|
+
await this._sandbox.writeFile(path, data);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new StorageError(`Failed to write '${normalized}' to sandbox storage`, { cause: error });
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let tmpPath;
|
|
76
|
+
try {
|
|
77
|
+
const { mkdir, writeFile, rename } = await import('node:fs/promises');
|
|
78
|
+
const { dirname } = await import('node:path');
|
|
79
|
+
await mkdir(dirname(path), { recursive: true });
|
|
80
|
+
const { randomUUID } = await import('node:crypto');
|
|
81
|
+
tmpPath = `${path}.__strands_tmp_${randomUUID()}`;
|
|
82
|
+
await writeFile(tmpPath, data);
|
|
83
|
+
await rename(tmpPath, path);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (tmpPath) {
|
|
87
|
+
const { rm } = await import('node:fs/promises');
|
|
88
|
+
await rm(tmpPath, { force: true }).catch(() => { });
|
|
89
|
+
}
|
|
90
|
+
throw new StorageError(`Failed to write '${normalized}' to local storage`, { cause: error });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Retrieves the bytes previously stored under `key`.
|
|
95
|
+
*
|
|
96
|
+
* @param key - The key to read
|
|
97
|
+
* @returns The stored bytes, or `null` if no value exists for `key`
|
|
98
|
+
* @throws {@link StorageError} if the key is invalid or the read fails
|
|
99
|
+
*/
|
|
100
|
+
async read(key) {
|
|
101
|
+
const normalized = normalizeKey(key);
|
|
102
|
+
const path = this._pathFor(normalized);
|
|
103
|
+
if (this._sandbox) {
|
|
104
|
+
try {
|
|
105
|
+
return await this._sandbox.readFile(path);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (isNotFoundError(error))
|
|
109
|
+
return null;
|
|
110
|
+
throw new StorageError(`Failed to read '${normalized}' from sandbox storage`, { cause: error });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const { readFile } = await import('node:fs/promises');
|
|
115
|
+
const content = await readFile(path);
|
|
116
|
+
return new Uint8Array(content);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (isNotFoundError(error))
|
|
120
|
+
return null;
|
|
121
|
+
throw new StorageError(`Failed to read '${normalized}' from local storage`, { cause: error });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Deletes the value stored under `key`. A no-op if the key does not exist.
|
|
126
|
+
*
|
|
127
|
+
* @param key - The key to delete
|
|
128
|
+
* @throws {@link StorageError} if the key is invalid or the delete fails
|
|
129
|
+
*/
|
|
130
|
+
async delete(key) {
|
|
131
|
+
const normalized = normalizeKey(key);
|
|
132
|
+
const path = this._pathFor(normalized);
|
|
133
|
+
if (this._sandbox) {
|
|
134
|
+
try {
|
|
135
|
+
await this._sandbox.removeFile(path);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (!isNotFoundError(error)) {
|
|
139
|
+
throw new StorageError(`Failed to delete '${normalized}' from sandbox storage`, { cause: error });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const { rm } = await import('node:fs/promises');
|
|
146
|
+
await rm(path, { force: true });
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
throw new StorageError(`Failed to delete '${normalized}' from local storage`, { cause: error });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Lists the keys whose names begin with `prefix`, sorted lexicographically.
|
|
154
|
+
*
|
|
155
|
+
* @param prefix - Key prefix to match. An empty string matches all keys.
|
|
156
|
+
* @returns The matching keys, sorted ascending
|
|
157
|
+
* @throws {@link StorageError} if the prefix is invalid or the listing fails
|
|
158
|
+
*/
|
|
159
|
+
async list(prefix) {
|
|
160
|
+
const normalized = normalizePrefix(prefix);
|
|
161
|
+
const base = this._baseDir.replace(/\/$/, '');
|
|
162
|
+
// Narrow the walk to the deepest directory the prefix fully specifies
|
|
163
|
+
const lastSlash = normalized.lastIndexOf('/');
|
|
164
|
+
const dirPortion = lastSlash >= 0 ? normalized.slice(0, lastSlash) : '';
|
|
165
|
+
const startDir = dirPortion ? `${base}/${dirPortion}` : base;
|
|
166
|
+
const keys = this._sandbox
|
|
167
|
+
? await this._listKeysSandbox(startDir, dirPortion)
|
|
168
|
+
: await this._listKeysHost(startDir, dirPortion);
|
|
169
|
+
return keys.filter((key) => key.startsWith(normalized)).sort();
|
|
170
|
+
}
|
|
171
|
+
_pathFor(key) {
|
|
172
|
+
const base = this._baseDir.replace(/\/$/, '');
|
|
173
|
+
return `${base}/${key}`;
|
|
174
|
+
}
|
|
175
|
+
async _listKeysHost(dir, keyPrefix) {
|
|
176
|
+
const { readdir } = await import('node:fs/promises');
|
|
177
|
+
const walk = async (walkDir, walkPrefix) => {
|
|
178
|
+
let entries;
|
|
179
|
+
try {
|
|
180
|
+
entries = await readdir(walkDir, { withFileTypes: true });
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (isNotFoundError(error))
|
|
184
|
+
return [];
|
|
185
|
+
throw new StorageError(`Failed to list local storage under '${walkPrefix}'`, { cause: error });
|
|
186
|
+
}
|
|
187
|
+
const found = [];
|
|
188
|
+
for (const entry of entries) {
|
|
189
|
+
if (!entry.isDirectory() && entry.name.includes('.__strands_tmp'))
|
|
190
|
+
continue;
|
|
191
|
+
const childKey = walkPrefix ? `${walkPrefix}/${entry.name}` : entry.name;
|
|
192
|
+
if (entry.isDirectory()) {
|
|
193
|
+
found.push(...(await walk(`${walkDir}/${entry.name}`, childKey)));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
found.push(childKey);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return found;
|
|
200
|
+
};
|
|
201
|
+
return walk(dir, keyPrefix);
|
|
202
|
+
}
|
|
203
|
+
async _listKeysSandbox(dir, keyPrefix) {
|
|
204
|
+
const sandbox = this._sandbox;
|
|
205
|
+
const walk = async (walkDir, walkPrefix) => {
|
|
206
|
+
let entries;
|
|
207
|
+
try {
|
|
208
|
+
entries = await sandbox.listFiles(walkDir);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
if (isNotFoundError(error))
|
|
212
|
+
return [];
|
|
213
|
+
throw new StorageError(`Failed to list sandbox storage under '${walkPrefix}'`, { cause: error });
|
|
214
|
+
}
|
|
215
|
+
const found = [];
|
|
216
|
+
for (const entry of entries) {
|
|
217
|
+
if (!entry.isDir && entry.name.includes('.__strands_tmp'))
|
|
218
|
+
continue;
|
|
219
|
+
const childKey = walkPrefix ? `${walkPrefix}/${entry.name}` : entry.name;
|
|
220
|
+
if (entry.isDir) {
|
|
221
|
+
found.push(...(await walk(`${walkDir}/${entry.name}`, childKey)));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
found.push(childKey);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return found;
|
|
228
|
+
};
|
|
229
|
+
return walk(dir, keyPrefix);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Returns a prefixed view of this storage without mutating the original.
|
|
233
|
+
* The returned view preserves `forSandbox` for single-level namespacing;
|
|
234
|
+
* nested `.namespace()` calls on the view do not carry sandbox routing.
|
|
235
|
+
*/
|
|
236
|
+
namespace(prefix) {
|
|
237
|
+
const view = namespace(this, prefix);
|
|
238
|
+
return {
|
|
239
|
+
...view,
|
|
240
|
+
forSandbox: (sandbox) => namespace(this.forSandbox(sandbox), prefix),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=local-file-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-file-storage.js","sourceRoot":"","sources":["../../../src/storage/local-file-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Storage } from './storage.js';
|
|
2
|
+
/** Configuration for {@link S3Storage}. */
|
|
3
|
+
export interface S3StorageConfig {
|
|
4
|
+
/** Optional key prefix prepended to every key (a leading namespace within the bucket). */
|
|
5
|
+
prefix?: string;
|
|
6
|
+
/** AWS region override. When omitted, the SDK's standard resolution chain applies. Cannot be combined with `s3Client`. */
|
|
7
|
+
region?: string;
|
|
8
|
+
/** Pre-configured S3 client. Cannot be combined with `region`. */
|
|
9
|
+
s3Client?: import('@aws-sdk/client-s3').S3Client;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Amazon S3 {@link Storage} backend.
|
|
13
|
+
*
|
|
14
|
+
* Stores each key as an S3 object under an optional prefix. The AWS SDK is loaded
|
|
15
|
+
* lazily on first use and declared as an optional peer dependency, so consumers that
|
|
16
|
+
* never construct an `S3Storage` are not required to install `@aws-sdk/client-s3`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { S3Storage } from '@strands-agents/sdk/storage'
|
|
21
|
+
*
|
|
22
|
+
* const storage = new S3Storage('my-bucket', { prefix: 'agents/' })
|
|
23
|
+
* await storage.write('sessions/abc/snapshot.json', bytes)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class S3Storage implements Storage {
|
|
27
|
+
private readonly _bucket;
|
|
28
|
+
private readonly _prefix;
|
|
29
|
+
private readonly _region;
|
|
30
|
+
private _client;
|
|
31
|
+
/**
|
|
32
|
+
* @param bucket - Target S3 bucket name
|
|
33
|
+
* @param config - Optional prefix, region, or pre-configured client
|
|
34
|
+
* @throws {@link StorageError} if both `region` and `s3Client` are provided
|
|
35
|
+
*/
|
|
36
|
+
constructor(bucket: string, config?: S3StorageConfig);
|
|
37
|
+
/**
|
|
38
|
+
* Stores `data` under `key`, overwriting any existing value.
|
|
39
|
+
*
|
|
40
|
+
* @param key - Opaque, `/`-separated key identifying the value
|
|
41
|
+
* @param data - Raw bytes to persist
|
|
42
|
+
* @throws {@link StorageError} if the key is invalid or the upload fails
|
|
43
|
+
*/
|
|
44
|
+
write(key: string, data: Uint8Array): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves the bytes previously stored under `key`.
|
|
47
|
+
*
|
|
48
|
+
* @param key - The key to read
|
|
49
|
+
* @returns The stored bytes, or `null` if no value exists for `key`
|
|
50
|
+
* @throws {@link StorageError} if the key is invalid or the download fails
|
|
51
|
+
*/
|
|
52
|
+
read(key: string): Promise<Uint8Array | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Deletes the value stored under `key`. A no-op if the key does not exist.
|
|
55
|
+
*
|
|
56
|
+
* @param key - The key to delete
|
|
57
|
+
* @throws {@link StorageError} if the key is invalid or the delete request fails
|
|
58
|
+
*/
|
|
59
|
+
delete(key: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Lists the keys whose names begin with `prefix`, sorted lexicographically.
|
|
62
|
+
*
|
|
63
|
+
* @param prefix - Key prefix to match. An empty string matches all keys.
|
|
64
|
+
* @returns The matching keys, sorted ascending
|
|
65
|
+
* @throws {@link StorageError} if the prefix is invalid or the list request fails
|
|
66
|
+
*/
|
|
67
|
+
list(prefix: string): Promise<string[]>;
|
|
68
|
+
private _getClient;
|
|
69
|
+
/** Returns a prefixed view of this storage without mutating the original. */
|
|
70
|
+
namespace(prefix: string): Storage;
|
|
71
|
+
private _objectKey;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=s3-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/s3-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAK3C,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0HAA0H;IAC1H,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,oBAAoB,EAAE,QAAQ,CAAA;CACjD;AAID;;;;;;;;;;;;;;GAcG;AACH,qBAAa,SAAU,YAAW,OAAO;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,OAAO,CAAmD;IAElE;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe;IAUpD;;;;;;OAMG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzD;;;;;;OAMG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkBnD;;;;;OAKG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxC;;;;;;OAMG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YA6B/B,UAAU;IAOxB,6EAA6E;IAC7E,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { StorageError } from '../errors.js';
|
|
2
|
+
import { namespace, normalizeKey, normalizePrefix } from './storage.js';
|
|
3
|
+
const S3_PAGE_SIZE = 1000;
|
|
4
|
+
/**
|
|
5
|
+
* Amazon S3 {@link Storage} backend.
|
|
6
|
+
*
|
|
7
|
+
* Stores each key as an S3 object under an optional prefix. The AWS SDK is loaded
|
|
8
|
+
* lazily on first use and declared as an optional peer dependency, so consumers that
|
|
9
|
+
* never construct an `S3Storage` are not required to install `@aws-sdk/client-s3`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { S3Storage } from '@strands-agents/sdk/storage'
|
|
14
|
+
*
|
|
15
|
+
* const storage = new S3Storage('my-bucket', { prefix: 'agents/' })
|
|
16
|
+
* await storage.write('sessions/abc/snapshot.json', bytes)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class S3Storage {
|
|
20
|
+
_bucket;
|
|
21
|
+
_prefix;
|
|
22
|
+
_region;
|
|
23
|
+
_client;
|
|
24
|
+
/**
|
|
25
|
+
* @param bucket - Target S3 bucket name
|
|
26
|
+
* @param config - Optional prefix, region, or pre-configured client
|
|
27
|
+
* @throws {@link StorageError} if both `region` and `s3Client` are provided
|
|
28
|
+
*/
|
|
29
|
+
constructor(bucket, config) {
|
|
30
|
+
if (config?.s3Client && config.region) {
|
|
31
|
+
throw new StorageError('Cannot specify both s3Client and region. Configure the region on the S3Client instead.');
|
|
32
|
+
}
|
|
33
|
+
this._bucket = bucket;
|
|
34
|
+
this._prefix = config?.prefix ? config.prefix.split('/').filter(Boolean).join('/') + '/' : '';
|
|
35
|
+
this._region = config?.region;
|
|
36
|
+
this._client = config?.s3Client;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Stores `data` under `key`, overwriting any existing value.
|
|
40
|
+
*
|
|
41
|
+
* @param key - Opaque, `/`-separated key identifying the value
|
|
42
|
+
* @param data - Raw bytes to persist
|
|
43
|
+
* @throws {@link StorageError} if the key is invalid or the upload fails
|
|
44
|
+
*/
|
|
45
|
+
async write(key, data) {
|
|
46
|
+
const normalized = normalizeKey(key);
|
|
47
|
+
const client = await this._getClient();
|
|
48
|
+
const { PutObjectCommand } = await import('@aws-sdk/client-s3');
|
|
49
|
+
try {
|
|
50
|
+
await client.send(new PutObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized), Body: data }));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
throw new StorageError(`Failed to write '${normalized}' to S3 bucket '${this._bucket}'`, { cause: error });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves the bytes previously stored under `key`.
|
|
58
|
+
*
|
|
59
|
+
* @param key - The key to read
|
|
60
|
+
* @returns The stored bytes, or `null` if no value exists for `key`
|
|
61
|
+
* @throws {@link StorageError} if the key is invalid or the download fails
|
|
62
|
+
*/
|
|
63
|
+
async read(key) {
|
|
64
|
+
const normalized = normalizeKey(key);
|
|
65
|
+
const client = await this._getClient();
|
|
66
|
+
const { GetObjectCommand } = await import('@aws-sdk/client-s3');
|
|
67
|
+
try {
|
|
68
|
+
const response = await client.send(new GetObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized) }));
|
|
69
|
+
const body = await response.Body?.transformToByteArray();
|
|
70
|
+
return body ? new Uint8Array(body) : null;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error instanceof Error && (error.name === 'NoSuchKey' || error.name === 'NotFound')) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
throw new StorageError(`Failed to read '${normalized}' from S3 bucket '${this._bucket}'`, { cause: error });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Deletes the value stored under `key`. A no-op if the key does not exist.
|
|
81
|
+
*
|
|
82
|
+
* @param key - The key to delete
|
|
83
|
+
* @throws {@link StorageError} if the key is invalid or the delete request fails
|
|
84
|
+
*/
|
|
85
|
+
async delete(key) {
|
|
86
|
+
const normalized = normalizeKey(key);
|
|
87
|
+
const client = await this._getClient();
|
|
88
|
+
const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
|
|
89
|
+
try {
|
|
90
|
+
await client.send(new DeleteObjectCommand({ Bucket: this._bucket, Key: this._objectKey(normalized) }));
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new StorageError(`Failed to delete '${normalized}' from S3 bucket '${this._bucket}'`, { cause: error });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Lists the keys whose names begin with `prefix`, sorted lexicographically.
|
|
98
|
+
*
|
|
99
|
+
* @param prefix - Key prefix to match. An empty string matches all keys.
|
|
100
|
+
* @returns The matching keys, sorted ascending
|
|
101
|
+
* @throws {@link StorageError} if the prefix is invalid or the list request fails
|
|
102
|
+
*/
|
|
103
|
+
async list(prefix) {
|
|
104
|
+
const normalized = normalizePrefix(prefix);
|
|
105
|
+
const client = await this._getClient();
|
|
106
|
+
const { ListObjectsV2Command } = await import('@aws-sdk/client-s3');
|
|
107
|
+
const listPrefix = `${this._prefix}${normalized}`;
|
|
108
|
+
const keys = [];
|
|
109
|
+
let continuationToken;
|
|
110
|
+
try {
|
|
111
|
+
do {
|
|
112
|
+
const response = await client.send(new ListObjectsV2Command({
|
|
113
|
+
Bucket: this._bucket,
|
|
114
|
+
Prefix: listPrefix,
|
|
115
|
+
MaxKeys: S3_PAGE_SIZE,
|
|
116
|
+
ContinuationToken: continuationToken,
|
|
117
|
+
}));
|
|
118
|
+
for (const object of response.Contents ?? []) {
|
|
119
|
+
if (object.Key === undefined)
|
|
120
|
+
continue;
|
|
121
|
+
keys.push(this._prefix ? object.Key.slice(this._prefix.length) : object.Key);
|
|
122
|
+
}
|
|
123
|
+
continuationToken = response.IsTruncated ? response.NextContinuationToken : undefined;
|
|
124
|
+
} while (continuationToken);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw new StorageError(`Failed to list S3 bucket '${this._bucket}' under '${normalized}'`, { cause: error });
|
|
128
|
+
}
|
|
129
|
+
return keys.sort();
|
|
130
|
+
}
|
|
131
|
+
async _getClient() {
|
|
132
|
+
if (this._client)
|
|
133
|
+
return this._client;
|
|
134
|
+
const { S3Client } = await import('@aws-sdk/client-s3');
|
|
135
|
+
this._client = new S3Client(this._region ? { region: this._region } : {});
|
|
136
|
+
return this._client;
|
|
137
|
+
}
|
|
138
|
+
/** Returns a prefixed view of this storage without mutating the original. */
|
|
139
|
+
namespace(prefix) {
|
|
140
|
+
return namespace(this, prefix);
|
|
141
|
+
}
|
|
142
|
+
_objectKey(key) {
|
|
143
|
+
return `${this._prefix}${key}`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=s3-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-storage.js","sourceRoot":"","sources":["../../../src/storage/s3-storage.ts"],"names":[],"mappings":"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"}
|