@btravstack/storage 0.37.0 → 0.39.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btravstack/storage",
3
- "version": "0.37.0",
3
+ "version": "0.39.0",
4
4
  "description": "A Storage port for @btravstack/core: an in-memory adapter, an S3-compatible adapter with presigned reads, and a composition that spans, counts and logs every operation",
5
5
  "keywords": [
6
6
  "dependency-injection",
@@ -55,11 +55,11 @@
55
55
  "devDependencies": {
56
56
  "@aws-sdk/client-s3": "3.1149.0",
57
57
  "@aws-sdk/s3-request-presigner": "3.1149.0",
58
- "@btravstack/config": "0.37.0",
59
- "@btravstack/core": "0.37.0",
60
- "@btravstack/di": "0.37.0",
58
+ "@btravstack/config": "0.39.0",
59
+ "@btravstack/core": "0.39.0",
60
+ "@btravstack/di": "0.39.0",
61
61
  "@btravstack/internal-test-infra": "0.0.0",
62
- "@btravstack/observability": "0.37.0",
62
+ "@btravstack/observability": "0.39.0",
63
63
  "@btravstack/tsconfig": "0.4.0",
64
64
  "@opentelemetry/api": "1.9.1",
65
65
  "@opentelemetry/sdk-metrics": "2.12.0",
@@ -76,9 +76,9 @@
76
76
  "peerDependencies": {
77
77
  "@aws-sdk/client-s3": "^3.1000.0",
78
78
  "@aws-sdk/s3-request-presigner": "^3.1000.0",
79
- "@btravstack/config": "^0.37.0",
80
- "@btravstack/core": "^0.37.0",
81
- "@btravstack/di": "^0.37.0",
79
+ "@btravstack/config": "^0.39.0",
80
+ "@btravstack/core": "^0.39.0",
81
+ "@btravstack/di": "^0.39.0",
82
82
  "unthrown": "^5.0.0"
83
83
  },
84
84
  "peerDependenciesMeta": {
@@ -1,92 +0,0 @@
1
- import { AsyncResult } from "unthrown";
2
- //#region src/storage.d.ts
3
- /** One stored object: its bytes and what they are. */
4
- type StoredObject = {
5
- readonly bytes: Uint8Array;
6
- readonly contentType: string;
7
- };
8
- declare const ObjectNotFound_base: import("unthrown").TaggedErrorConstructor<"ObjectNotFound">;
9
- /** The key is not there. Only `get` answers it — see `delete` and `presignedUrl` below. */
10
- declare class ObjectNotFound extends ObjectNotFound_base<{
11
- readonly key: string;
12
- }> {}
13
- declare const ObjectExists_base: import("unthrown").TaggedErrorConstructor<"ObjectExists">;
14
- /** An object already holds the key. Only `putIfAbsent` answers it. */
15
- declare class ObjectExists extends ObjectExists_base<{
16
- readonly key: string;
17
- }> {}
18
- declare const StorageUnavailable_base: import("unthrown").TaggedErrorConstructor<"StorageUnavailable">;
19
- /** The store could not answer — the endpoint is down, the credentials were refused, the bucket is gone. */
20
- declare class StorageUnavailable extends StorageUnavailable_base<{
21
- readonly operation: "put" | "putIfAbsent" | "get" | "delete" | "presignedUrl" | "presignedUpload";
22
- readonly key: string;
23
- readonly reason: string;
24
- }> {}
25
- declare const PresignNotSupported_base: import("unthrown").TaggedErrorConstructor<"PresignNotSupported">;
26
- /** The adapter cannot mint a time-limited URL, and says so rather than pretending. */
27
- declare class PresignNotSupported extends PresignNotSupported_base<{
28
- readonly key: string;
29
- }> {}
30
- type StorageService = {
31
- readonly put: (key: string, bytes: Uint8Array, options: {
32
- readonly contentType: string;
33
- }) => AsyncResult<void, StorageUnavailable>;
34
- /** Writes the object only if no object holds the key: the first writer wins, atomically, in the store. */
35
- readonly putIfAbsent: (key: string, bytes: Uint8Array, options: {
36
- readonly contentType: string;
37
- }) => AsyncResult<void, ObjectExists | StorageUnavailable>;
38
- readonly get: (key: string) => AsyncResult<StoredObject, ObjectNotFound | StorageUnavailable>;
39
- /** Deleting a key nobody stored is `Ok`: delete is idempotent, which is S3's own behaviour rather than a fiction over it. */
40
- readonly delete: (key: string) => AsyncResult<void, StorageUnavailable>;
41
- /**
42
- * A URL that reads the object for `ttlMs`, without the caller holding
43
- * credentials.
44
- *
45
- * There is **no `ObjectNotFound` arm**: presigning is a signature computation
46
- * that asks the store nothing, so a URL for an absent key is minted happily
47
- * and 404s when followed. Checking would cost a HEAD per call.
48
- */
49
- readonly presignedUrl: (key: string, options: {
50
- readonly ttlMs: number;
51
- }) => AsyncResult<string, PresignNotSupported | StorageUnavailable>;
52
- /**
53
- * A URL that writes the object for `ttlMs`, without the caller holding
54
- * credentials — so the bytes go from the client to the store and never
55
- * through this process.
56
- *
57
- * **`contentType` and `contentLength` are signed, not advisory.** They are
58
- * part of the signature, so a client sending different ones is refused by the
59
- * store. The same URL can write the key repeatedly until expiry, replacing
60
- * the previous object with different bytes of that size and type. Neither
61
- * signed header proves the bytes. `contentLength` is required — an unsigned
62
- * length would allow an unbounded single write, and there is no ceiling a
63
- * presigned PUT can express other than the exact number.
64
- *
65
- * The application still decides every input: whether this caller may write
66
- * this key, how long the URL lives, and what size it is willing to accept.
67
- * The adapter computes a signature over that decision and nothing more.
68
- */
69
- readonly presignedUpload: (key: string, options: {
70
- readonly ttlMs: number;
71
- readonly contentType: string;
72
- readonly contentLength: number;
73
- }) => AsyncResult<string, PresignNotSupported | StorageUnavailable>;
74
- };
75
- declare const Storage_base: import("@btravstack/di").PortClass<"Storage">;
76
- /**
77
- * The port an application depends on.
78
- *
79
- * Keys are plain strings the caller composes, tenant included: a store is an
80
- * application service, and the framework has no concept of a tenant to put in a
81
- * slot.
82
- *
83
- * **Bytes, not streams.** An object here is a document. Streaming would change
84
- * every signature, adapter and test to serve a case that wants a different
85
- * design anyway — a stated non-goal, not an oversight.
86
- */
87
- declare class Storage extends Storage_base<StorageService> {}
88
- declare const StorageBackend_base: import("@btravstack/di").PortClass<"StorageBackend">;
89
- /** The port every adapter provides, and the one an application never depends on. */
90
- declare class StorageBackend extends StorageBackend_base<StorageService> {}
91
- //#endregion
92
- export { StorageBackend as a, StoredObject as c, Storage as i, ObjectNotFound as n, StorageService as o, PresignNotSupported as r, StorageUnavailable as s, ObjectExists as t };
@@ -1,92 +0,0 @@
1
- import { AsyncResult } from "unthrown";
2
- //#region src/storage.d.ts
3
- /** One stored object: its bytes and what they are. */
4
- type StoredObject = {
5
- readonly bytes: Uint8Array;
6
- readonly contentType: string;
7
- };
8
- declare const ObjectNotFound_base: import("unthrown").TaggedErrorConstructor<"ObjectNotFound">;
9
- /** The key is not there. Only `get` answers it — see `delete` and `presignedUrl` below. */
10
- declare class ObjectNotFound extends ObjectNotFound_base<{
11
- readonly key: string;
12
- }> {}
13
- declare const ObjectExists_base: import("unthrown").TaggedErrorConstructor<"ObjectExists">;
14
- /** An object already holds the key. Only `putIfAbsent` answers it. */
15
- declare class ObjectExists extends ObjectExists_base<{
16
- readonly key: string;
17
- }> {}
18
- declare const StorageUnavailable_base: import("unthrown").TaggedErrorConstructor<"StorageUnavailable">;
19
- /** The store could not answer — the endpoint is down, the credentials were refused, the bucket is gone. */
20
- declare class StorageUnavailable extends StorageUnavailable_base<{
21
- readonly operation: "put" | "putIfAbsent" | "get" | "delete" | "presignedUrl" | "presignedUpload";
22
- readonly key: string;
23
- readonly reason: string;
24
- }> {}
25
- declare const PresignNotSupported_base: import("unthrown").TaggedErrorConstructor<"PresignNotSupported">;
26
- /** The adapter cannot mint a time-limited URL, and says so rather than pretending. */
27
- declare class PresignNotSupported extends PresignNotSupported_base<{
28
- readonly key: string;
29
- }> {}
30
- type StorageService = {
31
- readonly put: (key: string, bytes: Uint8Array, options: {
32
- readonly contentType: string;
33
- }) => AsyncResult<void, StorageUnavailable>;
34
- /** Writes the object only if no object holds the key: the first writer wins, atomically, in the store. */
35
- readonly putIfAbsent: (key: string, bytes: Uint8Array, options: {
36
- readonly contentType: string;
37
- }) => AsyncResult<void, ObjectExists | StorageUnavailable>;
38
- readonly get: (key: string) => AsyncResult<StoredObject, ObjectNotFound | StorageUnavailable>;
39
- /** Deleting a key nobody stored is `Ok`: delete is idempotent, which is S3's own behaviour rather than a fiction over it. */
40
- readonly delete: (key: string) => AsyncResult<void, StorageUnavailable>;
41
- /**
42
- * A URL that reads the object for `ttlMs`, without the caller holding
43
- * credentials.
44
- *
45
- * There is **no `ObjectNotFound` arm**: presigning is a signature computation
46
- * that asks the store nothing, so a URL for an absent key is minted happily
47
- * and 404s when followed. Checking would cost a HEAD per call.
48
- */
49
- readonly presignedUrl: (key: string, options: {
50
- readonly ttlMs: number;
51
- }) => AsyncResult<string, PresignNotSupported | StorageUnavailable>;
52
- /**
53
- * A URL that writes the object for `ttlMs`, without the caller holding
54
- * credentials — so the bytes go from the client to the store and never
55
- * through this process.
56
- *
57
- * **`contentType` and `contentLength` are signed, not advisory.** They are
58
- * part of the signature, so a client sending different ones is refused by the
59
- * store. The same URL can write the key repeatedly until expiry, replacing
60
- * the previous object with different bytes of that size and type. Neither
61
- * signed header proves the bytes. `contentLength` is required — an unsigned
62
- * length would allow an unbounded single write, and there is no ceiling a
63
- * presigned PUT can express other than the exact number.
64
- *
65
- * The application still decides every input: whether this caller may write
66
- * this key, how long the URL lives, and what size it is willing to accept.
67
- * The adapter computes a signature over that decision and nothing more.
68
- */
69
- readonly presignedUpload: (key: string, options: {
70
- readonly ttlMs: number;
71
- readonly contentType: string;
72
- readonly contentLength: number;
73
- }) => AsyncResult<string, PresignNotSupported | StorageUnavailable>;
74
- };
75
- declare const Storage_base: import("@btravstack/di").PortClass<"Storage">;
76
- /**
77
- * The port an application depends on.
78
- *
79
- * Keys are plain strings the caller composes, tenant included: a store is an
80
- * application service, and the framework has no concept of a tenant to put in a
81
- * slot.
82
- *
83
- * **Bytes, not streams.** An object here is a document. Streaming would change
84
- * every signature, adapter and test to serve a case that wants a different
85
- * design anyway — a stated non-goal, not an oversight.
86
- */
87
- declare class Storage extends Storage_base<StorageService> {}
88
- declare const StorageBackend_base: import("@btravstack/di").PortClass<"StorageBackend">;
89
- /** The port every adapter provides, and the one an application never depends on. */
90
- declare class StorageBackend extends StorageBackend_base<StorageService> {}
91
- //#endregion
92
- export { StorageBackend as a, StoredObject as c, Storage as i, ObjectNotFound as n, StorageService as o, PresignNotSupported as r, StorageUnavailable as s, ObjectExists as t };