@peerbit/blocks-interface 2.1.8 → 2.2.1

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 CHANGED
@@ -13,3 +13,23 @@ consumer boundary, after the bytes are authenticated.
13
13
  DAG-CBOR block can still allocate its decoded object graph, so callers handling
14
14
  attacker-selected CIDs should prefer `verifyBlockBytes` unless they explicitly
15
15
  need the logical value and enforce suitable resource bounds.
16
+
17
+ ## Reclamation capability
18
+
19
+ `Blocks.localReclamation` is an operational capability, not caller-declared
20
+ metadata. A service may report `enforcedReclamation: "scoped-references-v1"`
21
+ through the additive `observedLocalStoreSafety` property only when that
22
+ capability exists; callers must additionally require a `ready` health result.
23
+ The existing `localStoreSafety` property and `BlockStoreSafety` declaration
24
+ type remain restricted to `enforcedReclamation: "none"` for source
25
+ compatibility. `DeclaredBlockStoreSafety` is an explicit alias, while
26
+ `ObservedBlockStoreSafety` includes the service-minted enforced variant.
27
+ Custom-store configuration therefore cannot assert an enforcement mechanism it
28
+ does not implement. Peerbit's enforced metadata value is private to the
29
+ built-in wrapper and is derived from that wrapper's actual capability; neither
30
+ the opt-in flag nor caller metadata can mint it.
31
+
32
+ Each `openScope` key is exactly 32 bytes and is defensively copied. Scope
33
+ handles belong to one service lifecycle. Managed retain/release operations are
34
+ single-block, bounded, idempotent, local-only, and isolated from raw `put`/`rm`
35
+ blocks.
@@ -1,5 +1,5 @@
1
- import { type WaitForPeer } from "@peerbit/stream-interface";
2
- import { type Block } from "multiformats/block";
1
+ import type { WaitForPeer } from "@peerbit/stream-interface";
2
+ import type { Block } from "multiformats/block";
3
3
  export type GetOptions = {
4
4
  remote?: {
5
5
  signal?: AbortSignal;
@@ -42,6 +42,60 @@ export type BlockStoreSafety = Readonly<{
42
42
  referenceDomain: BlockStoreReferenceDomain;
43
43
  enforcedReclamation: "none";
44
44
  }>;
45
+ /** Explicit alias for APIs that accept caller-declared safety facts. */
46
+ export type DeclaredBlockStoreSafety = BlockStoreSafety;
47
+ /**
48
+ * Observed service safety. The enforced variant is valid only together with a
49
+ * matching, ready `Blocks.localReclamation` capability; metadata alone never
50
+ * grants deletion authority.
51
+ */
52
+ export type ObservedBlockStoreSafety = BlockStoreSafety | Readonly<{
53
+ referenceDomain: "block-service";
54
+ enforcedReclamation: "scoped-references-v1";
55
+ }>;
56
+ export type ScopedBlockReclamationLimits = Readonly<{
57
+ maxBlockBytes: number;
58
+ maxCidBytes: number;
59
+ scopeKeyBytes: number;
60
+ maxReferencesPerBlock: number;
61
+ maxPendingOperations: number;
62
+ maxPendingBytes: number;
63
+ }>;
64
+ export type ScopedBlockReclamationFaultCode = "ambiguous-mutation" | "corrupt-state" | "storage-failure";
65
+ export type ScopedBlockReclamationHealth = Readonly<{
66
+ status: "opening" | "ready" | "closed";
67
+ }> | Readonly<{
68
+ status: "faulted";
69
+ reason: ScopedBlockReclamationFaultCode;
70
+ }>;
71
+ export type ScopedBlockReleaseResult = "not-retained" | "retained" | "reclaimed";
72
+ /**
73
+ * One durable ownership scope inside a block-service managed namespace.
74
+ *
75
+ * A scope key is local authority, not a network identity. Callers must use a
76
+ * stable, collision-resistant value under their control; this mechanism does
77
+ * not isolate mutually hostile code that can invoke `openScope` with another
78
+ * caller's key. `retain` copies and CID-verifies bytes before publishing the
79
+ * reference. `release` can delete only managed bytes after the last durable
80
+ * scope reference is gone. Calls are idempotent and deliberately single-block
81
+ * so each unit of work is bounded.
82
+ */
83
+ export interface ScopedBlockReclamationScopeV1 {
84
+ put(bytes: Uint8Array): MaybePromise<string>;
85
+ retain(cid: string, bytes: Uint8Array): MaybePromise<string>;
86
+ release(cid: string): MaybePromise<ScopedBlockReleaseResult>;
87
+ }
88
+ /**
89
+ * Opt-in, local-only reference enforcement for a block-service-owned managed
90
+ * namespace. It never adopts or deletes blocks written through the legacy/raw
91
+ * `Blocks.put`/`Blocks.rm` namespace.
92
+ */
93
+ export interface ScopedBlockReclamationV1 {
94
+ readonly kind: "scoped-references-v1";
95
+ readonly limits: ScopedBlockReclamationLimits;
96
+ health(): ScopedBlockReclamationHealth;
97
+ openScope(scopeKey: Uint8Array): ScopedBlockReclamationScopeV1;
98
+ }
45
99
  export declare const UNKNOWN_BLOCK_STORE_SAFETY: BlockStoreSafety;
46
100
  export declare const BLOCK_SERVICE_BLOCK_STORE_SAFETY: BlockStoreSafety;
47
101
  /**
@@ -53,11 +107,26 @@ export declare const BLOCK_SERVICE_BLOCK_STORE_SAFETY: BlockStoreSafety;
53
107
  export declare const normalizeBlockStoreSafety: (value: unknown) => BlockStoreSafety;
54
108
  export interface Blocks extends WaitForPeer {
55
109
  /**
56
- * Safety metadata for this service's local physical block namespace.
57
- * Absence is equivalent to {@link UNKNOWN_BLOCK_STORE_SAFETY} so older and
58
- * custom implementations fail closed.
110
+ * Legacy caller-declared safety metadata for this service's local physical
111
+ * block namespace. Its type and values remain restricted to
112
+ * `enforcedReclamation: "none"`.
59
113
  */
60
114
  readonly localStoreSafety?: BlockStoreSafety;
115
+ /**
116
+ * Optional service-observed safety metadata. Absence is equivalent to
117
+ * `localStoreSafety` (or {@link UNKNOWN_BLOCK_STORE_SAFETY} when both are
118
+ * absent), so older and custom implementations fail closed.
119
+ *
120
+ * The enforced variant is descriptive only; callers must also require the
121
+ * matching, ready `localReclamation` capability.
122
+ */
123
+ readonly observedLocalStoreSafety?: ObservedBlockStoreSafety;
124
+ /**
125
+ * Present only when this exact service owns and enforces a separate managed
126
+ * namespace. Callers must require `health().status === "ready"`; metadata
127
+ * alone is not authority to delete.
128
+ */
129
+ readonly localReclamation?: ScopedBlockReclamationV1;
61
130
  put(data: Uint8Array | {
62
131
  block: Block<any, any, any, any>;
63
132
  cid: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -1,5 +1,3 @@
1
- import {} from "@peerbit/stream-interface";
2
- import {} from "multiformats/block";
3
1
  export const UNKNOWN_BLOCK_STORE_SAFETY = Object.freeze({
4
2
  referenceDomain: "unknown",
5
3
  enforcedReclamation: "none",
@@ -30,6 +28,8 @@ export const normalizeBlockStoreSafety = (value) => {
30
28
  referenceDomain !== "unknown") {
31
29
  throw new TypeError("Invalid block-store reference domain");
32
30
  }
31
+ // Enforced reclamation is an operational capability, not a caller assertion.
32
+ // DirectBlock mints its scoped capability only for its own supported store.
33
33
  if (enforcedReclamation !== "none") {
34
34
  throw new TypeError("Unsupported block-store reclamation capability");
35
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAc,MAAM,oBAAoB,CAAC;AAsDhD,MAAM,CAAC,MAAM,0BAA0B,GAAqB,MAAM,CAAC,MAAM,CAAC;IACzE,eAAe,EAAE,SAAS;IAC1B,mBAAmB,EAAE,MAAM;CAC3B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAAqB,MAAM,CAAC,MAAM,CAC9E;IACC,eAAe,EAAE,eAAe;IAChC,mBAAmB,EAAE,MAAM;CAC3B,CACD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACxC,KAAc,EACK,EAAE;IACrB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,0BAA0B,CAAC;IAC3D,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,eAAe,GAAI,KAAuC;SAC9D,eAAe,CAAC;IAClB,MAAM,mBAAmB,GAAI,KAA2C;SACtE,mBAAmB,CAAC;IACtB,IACC,eAAe,KAAK,eAAe;QACnC,eAAe,KAAK,kBAAkB;QACtC,eAAe,KAAK,QAAQ;QAC5B,eAAe,KAAK,SAAS,EAC5B,CAAC;QACF,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,mBAAmB,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC;AAiDF,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AA6HA,MAAM,CAAC,MAAM,0BAA0B,GAAqB,MAAM,CAAC,MAAM,CAAC;IACzE,eAAe,EAAE,SAAS;IAC1B,mBAAmB,EAAE,MAAM;CAC3B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAAqB,MAAM,CAAC,MAAM,CAC9E;IACC,eAAe,EAAE,eAAe;IAChC,mBAAmB,EAAE,MAAM;CAC3B,CACD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACxC,KAAc,EACK,EAAE;IACrB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,0BAA0B,CAAC;IAC3D,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,eAAe,GAAI,KAAuC;SAC9D,eAAe,CAAC;IAClB,MAAM,mBAAmB,GAAI,KAA2C;SACtE,mBAAmB,CAAC;IACtB,IACC,eAAe,KAAK,eAAe;QACnC,eAAe,KAAK,kBAAkB;QACtC,eAAe,KAAK,QAAQ;QAC5B,eAAe,KAAK,SAAS,EAC5B,CAAC;QACF,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC7D,CAAC;IACD,6EAA6E;IAC7E,4EAA4E;IAC5E,IAAI,mBAAmB,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,mBAAmB,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC;AAgEF,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/blocks-interface",
3
- "version": "2.1.8",
3
+ "version": "2.2.1",
4
4
  "description": "Block store streaming",
5
5
  "type": "module",
6
6
  "sideEffects": false,
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { type WaitForPeer } from "@peerbit/stream-interface";
2
- import { type Block } from "multiformats/block";
1
+ import type { WaitForPeer } from "@peerbit/stream-interface";
2
+ import type { Block } from "multiformats/block";
3
3
 
4
4
  export type GetOptions = {
5
5
  remote?:
@@ -53,6 +53,76 @@ export type BlockStoreSafety = Readonly<{
53
53
  enforcedReclamation: "none";
54
54
  }>;
55
55
 
56
+ /** Explicit alias for APIs that accept caller-declared safety facts. */
57
+ export type DeclaredBlockStoreSafety = BlockStoreSafety;
58
+
59
+ /**
60
+ * Observed service safety. The enforced variant is valid only together with a
61
+ * matching, ready `Blocks.localReclamation` capability; metadata alone never
62
+ * grants deletion authority.
63
+ */
64
+ export type ObservedBlockStoreSafety =
65
+ | BlockStoreSafety
66
+ | Readonly<{
67
+ referenceDomain: "block-service";
68
+ enforcedReclamation: "scoped-references-v1";
69
+ }>;
70
+
71
+ export type ScopedBlockReclamationLimits = Readonly<{
72
+ maxBlockBytes: number;
73
+ maxCidBytes: number;
74
+ scopeKeyBytes: number;
75
+ maxReferencesPerBlock: number;
76
+ maxPendingOperations: number;
77
+ maxPendingBytes: number;
78
+ }>;
79
+
80
+ export type ScopedBlockReclamationFaultCode =
81
+ | "ambiguous-mutation"
82
+ | "corrupt-state"
83
+ | "storage-failure";
84
+
85
+ export type ScopedBlockReclamationHealth =
86
+ | Readonly<{ status: "opening" | "ready" | "closed" }>
87
+ | Readonly<{
88
+ status: "faulted";
89
+ reason: ScopedBlockReclamationFaultCode;
90
+ }>;
91
+
92
+ export type ScopedBlockReleaseResult =
93
+ | "not-retained"
94
+ | "retained"
95
+ | "reclaimed";
96
+
97
+ /**
98
+ * One durable ownership scope inside a block-service managed namespace.
99
+ *
100
+ * A scope key is local authority, not a network identity. Callers must use a
101
+ * stable, collision-resistant value under their control; this mechanism does
102
+ * not isolate mutually hostile code that can invoke `openScope` with another
103
+ * caller's key. `retain` copies and CID-verifies bytes before publishing the
104
+ * reference. `release` can delete only managed bytes after the last durable
105
+ * scope reference is gone. Calls are idempotent and deliberately single-block
106
+ * so each unit of work is bounded.
107
+ */
108
+ export interface ScopedBlockReclamationScopeV1 {
109
+ put(bytes: Uint8Array): MaybePromise<string>;
110
+ retain(cid: string, bytes: Uint8Array): MaybePromise<string>;
111
+ release(cid: string): MaybePromise<ScopedBlockReleaseResult>;
112
+ }
113
+
114
+ /**
115
+ * Opt-in, local-only reference enforcement for a block-service-owned managed
116
+ * namespace. It never adopts or deletes blocks written through the legacy/raw
117
+ * `Blocks.put`/`Blocks.rm` namespace.
118
+ */
119
+ export interface ScopedBlockReclamationV1 {
120
+ readonly kind: "scoped-references-v1";
121
+ readonly limits: ScopedBlockReclamationLimits;
122
+ health(): ScopedBlockReclamationHealth;
123
+ openScope(scopeKey: Uint8Array): ScopedBlockReclamationScopeV1;
124
+ }
125
+
56
126
  export const UNKNOWN_BLOCK_STORE_SAFETY: BlockStoreSafety = Object.freeze({
57
127
  referenceDomain: "unknown",
58
128
  enforcedReclamation: "none",
@@ -90,6 +160,8 @@ export const normalizeBlockStoreSafety = (
90
160
  ) {
91
161
  throw new TypeError("Invalid block-store reference domain");
92
162
  }
163
+ // Enforced reclamation is an operational capability, not a caller assertion.
164
+ // DirectBlock mints its scoped capability only for its own supported store.
93
165
  if (enforcedReclamation !== "none") {
94
166
  throw new TypeError("Unsupported block-store reclamation capability");
95
167
  }
@@ -98,11 +170,26 @@ export const normalizeBlockStoreSafety = (
98
170
 
99
171
  export interface Blocks extends WaitForPeer {
100
172
  /**
101
- * Safety metadata for this service's local physical block namespace.
102
- * Absence is equivalent to {@link UNKNOWN_BLOCK_STORE_SAFETY} so older and
103
- * custom implementations fail closed.
173
+ * Legacy caller-declared safety metadata for this service's local physical
174
+ * block namespace. Its type and values remain restricted to
175
+ * `enforcedReclamation: "none"`.
104
176
  */
105
177
  readonly localStoreSafety?: BlockStoreSafety;
178
+ /**
179
+ * Optional service-observed safety metadata. Absence is equivalent to
180
+ * `localStoreSafety` (or {@link UNKNOWN_BLOCK_STORE_SAFETY} when both are
181
+ * absent), so older and custom implementations fail closed.
182
+ *
183
+ * The enforced variant is descriptive only; callers must also require the
184
+ * matching, ready `localReclamation` capability.
185
+ */
186
+ readonly observedLocalStoreSafety?: ObservedBlockStoreSafety;
187
+ /**
188
+ * Present only when this exact service owns and enforces a separate managed
189
+ * namespace. Callers must require `health().status === "ready"`; metadata
190
+ * alone is not authority to delete.
191
+ */
192
+ readonly localReclamation?: ScopedBlockReclamationV1;
106
193
  put(
107
194
  data: Uint8Array | { block: Block<any, any, any, any>; cid: string },
108
195
  ): MaybePromise<string>;