circuitjson-toolkit 1.2.0 → 1.3.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.
@@ -13,7 +13,7 @@ const METADATA_BUDGETS = new WeakMap()
13
13
  const EXTENSION_METADATA_LIMITS = Object.freeze({
14
14
  label: 'Canonical extension data',
15
15
  maxBytes: 128 * 1024 * 1024,
16
- maxItems: 2_000_000,
16
+ maxItems: 4_000_000,
17
17
  preserveBinary: true
18
18
  })
19
19
  const ASSET_SCALAR_FIELDS = new Set([
@@ -41,9 +41,10 @@ export class CircuitJsonReadOnlyDocument {
41
41
  * Seals an envelope whose exact model was already deeply frozen by validation.
42
42
  * @param {Record<string, any>} document Canonical document envelope.
43
43
  * @param {object[]} model Exact deeply frozen model owned by the proof.
44
+ * @param {{ standardBuiltins?: boolean }} [options] Proven metadata provenance.
44
45
  * @returns {Record<string, any>} The same read-only envelope.
45
46
  */
46
- static freezeValidated(document, model) {
47
+ static freezeValidated(document, model, options = {}) {
47
48
  if (!CircuitJsonValidationAuthority.permitsSeal(model)) {
48
49
  throw new TypeError(
49
50
  'Validated document sealing requires an unforgeable validation proof.'
@@ -76,7 +77,8 @@ export class CircuitJsonReadOnlyDocument {
76
77
  }
77
78
  return CircuitJsonReadOnlyDocument.#freezeDocument(
78
79
  document,
79
- frozenRoots
80
+ frozenRoots,
81
+ options?.standardBuiltins === true
80
82
  )
81
83
  }
82
84
 
@@ -84,14 +86,18 @@ export class CircuitJsonReadOnlyDocument {
84
86
  * Captures owned boundaries and freezes an envelope with known frozen roots.
85
87
  * @param {Record<string, any>} document Canonical document envelope.
86
88
  * @param {Set<object>} frozenRoots Deeply frozen roots that need no revisit.
89
+ * @param {boolean} [standardBuiltins] Whether extension built-ins have proven standard prototypes.
87
90
  * @returns {Record<string, any>} The same read-only envelope.
88
91
  */
89
- static #freezeDocument(document, frozenRoots) {
92
+ static #freezeDocument(document, frozenRoots, standardBuiltins = false) {
90
93
  const assets = CircuitJsonReadOnlyDocument.#documentAssets(document)
91
94
  const metadataState = StructuredDataSnapshot.createState()
92
95
  CircuitJsonReadOnlyDocument.#captureAssetData(assets, metadataState)
93
96
  const extensions =
94
- CircuitJsonReadOnlyDocument.#captureDocumentExtensions(document)
97
+ CircuitJsonReadOnlyDocument.#captureDocumentExtensions(
98
+ document,
99
+ standardBuiltins
100
+ )
95
101
  if (extensions && typeof extensions === 'object') {
96
102
  frozenRoots.add(extensions)
97
103
  }
@@ -199,9 +205,10 @@ export class CircuitJsonReadOnlyDocument {
199
205
  * transfer-sized item and byte ceilings.
200
206
  * @param {unknown} value Extension candidate.
201
207
  * @param {((snapshot: unknown) => unknown) | null} [normalize] Optional normalization over the owned mutable snapshot.
208
+ * @param {{ standardBuiltins?: boolean }} [options] Proven source-graph provenance.
202
209
  * @returns {unknown} Deeply immutable owned extension metadata.
203
210
  */
204
- static copyReadonlyExtensionValue(value, normalize = null) {
211
+ static copyReadonlyExtensionValue(value, normalize = null, options = {}) {
205
212
  if (
206
213
  value &&
207
214
  typeof value === 'object' &&
@@ -216,7 +223,10 @@ export class CircuitJsonReadOnlyDocument {
216
223
  }
217
224
  const snapshot = StructuredDataSnapshot.capture(
218
225
  value,
219
- StructuredDataSnapshot.createState(EXTENSION_METADATA_LIMITS)
226
+ StructuredDataSnapshot.createState({
227
+ ...EXTENSION_METADATA_LIMITS,
228
+ standardBuiltins: options?.standardBuiltins === true
229
+ })
220
230
  )
221
231
  ProtectedExtensionBinaryBoundary.protect(snapshot)
222
232
  const normalized = normalize ? normalize(snapshot) : snapshot
@@ -327,9 +337,10 @@ export class CircuitJsonReadOnlyDocument {
327
337
  * Captures an unowned worker or caller extension root with extension-sized
328
338
  * bounds before the generic source metadata pass begins.
329
339
  * @param {Record<string, any>} document Canonical document envelope.
340
+ * @param {boolean} standardBuiltins Whether extension built-ins have proven standard prototypes.
330
341
  * @returns {unknown} Owned extension root or undefined.
331
342
  */
332
- static #captureDocumentExtensions(document) {
343
+ static #captureDocumentExtensions(document, standardBuiltins) {
333
344
  let descriptor
334
345
  try {
335
346
  descriptor = Object.getOwnPropertyDescriptor(document, 'extensions')
@@ -345,7 +356,9 @@ export class CircuitJsonReadOnlyDocument {
345
356
  )
346
357
  }
347
358
  const captured = CircuitJsonReadOnlyDocument.copyReadonlyExtensionValue(
348
- descriptor.value
359
+ descriptor.value,
360
+ null,
361
+ { standardBuiltins }
349
362
  )
350
363
  if (captured === descriptor.value) return captured
351
364
  Object.defineProperty(document, 'extensions', {
@@ -53,9 +53,10 @@ export class CircuitJsonValidationProof {
53
53
  /**
54
54
  * Validates, freezes, and proves one canonical document envelope.
55
55
  * @param {Record<string, any>} document Canonical document envelope.
56
+ * @param {{ standardBuiltins?: boolean }} [options] Proven metadata provenance.
56
57
  * @returns {Record<string, any>} The same read-only document envelope.
57
58
  */
58
- static validateAndAttach(document) {
59
+ static validateAndAttach(document, options = {}) {
59
60
  const model = CircuitJsonValidationProof.#requireModelData(document)
60
61
  if (!CircuitJsonValidationProof.#matches(document, model)) {
61
62
  const errors =
@@ -80,7 +81,8 @@ export class CircuitJsonValidationProof {
80
81
  }
81
82
  const readonlyDocument = CircuitJsonReadOnlyDocument.freezeValidated(
82
83
  document,
83
- model
84
+ model,
85
+ options
84
86
  )
85
87
  if (
86
88
  CircuitJsonValidationProof.#requireModelData(readonlyDocument) !==
@@ -12,7 +12,7 @@ export class ProtectedExtensionBinaryBoundary {
12
12
  * @returns {void}
13
13
  */
14
14
  static protect(root) {
15
- if (BinaryDataSnapshot.describe(root)) {
15
+ if (BinaryDataSnapshot.describeStandard(root)) {
16
16
  throw new TypeError(
17
17
  'Canonical extension root must be a plain data container.'
18
18
  )
@@ -51,7 +51,7 @@ export class ProtectedExtensionBinaryBoundary {
51
51
  stack.push(child)
52
52
  continue
53
53
  }
54
- const binary = BinaryDataSnapshot.describe(child)
54
+ const binary = BinaryDataSnapshot.describeStandard(child)
55
55
  if (!binary) continue
56
56
  const ownedBinary = child
57
57
  /** @returns {ArrayBuffer | Uint8Array | DataView} A defensive binary copy. */
@@ -26,8 +26,8 @@ const SET_VALUES = Set.prototype.values
26
26
  export class StructuredDataSnapshot {
27
27
  /**
28
28
  * Creates state shared by multiple metadata roots in one request.
29
- * @param {{ label?: string, maxBytes?: number, maxItems?: number, preserveBinary?: boolean }} [limits] Capture limits.
30
- * @returns {{ seen: Map<object, unknown>, accounted: Set<object>, bytes: number, items: number, label: string, maxBytes: number, maxItems: number, preserveBinary: boolean }} Capture state.
29
+ * @param {{ label?: string, maxBytes?: number, maxItems?: number, preserveBinary?: boolean, standardBuiltins?: boolean }} [limits] Capture limits and proven graph provenance.
30
+ * @returns {{ seen: Map<object, unknown>, accounted: Set<object>, bytes: number, items: number, label: string, maxBytes: number, maxItems: number, preserveBinary: boolean, standardBuiltins: boolean }} Capture state.
31
31
  */
32
32
  static createState(limits = {}) {
33
33
  const maxBytes =
@@ -52,7 +52,8 @@ export class StructuredDataSnapshot {
52
52
  label: String(limits.label || 'Canonical asset source'),
53
53
  maxBytes,
54
54
  maxItems,
55
- preserveBinary: limits.preserveBinary === true
55
+ preserveBinary: limits.preserveBinary === true,
56
+ standardBuiltins: limits.standardBuiltins === true
56
57
  }
57
58
  }
58
59
 
@@ -71,7 +72,8 @@ export class StructuredDataSnapshot {
71
72
  !Number.isSafeInteger(state.maxBytes) ||
72
73
  !Number.isSafeInteger(state.maxItems) ||
73
74
  typeof state.label !== 'string' ||
74
- typeof state.preserveBinary !== 'boolean'
75
+ typeof state.preserveBinary !== 'boolean' ||
76
+ typeof state.standardBuiltins !== 'boolean'
75
77
  ) {
76
78
  throw new TypeError('Invalid source-metadata capture state.')
77
79
  }
@@ -93,7 +95,8 @@ export class StructuredDataSnapshot {
93
95
  !Number.isSafeInteger(state.maxBytes) ||
94
96
  !Number.isSafeInteger(state.maxItems) ||
95
97
  typeof state.label !== 'string' ||
96
- typeof state.preserveBinary !== 'boolean'
98
+ typeof state.preserveBinary !== 'boolean' ||
99
+ typeof state.standardBuiltins !== 'boolean'
97
100
  ) {
98
101
  throw new TypeError('Invalid source-metadata capture state.')
99
102
  }
@@ -224,7 +227,9 @@ export class StructuredDataSnapshot {
224
227
  if (state.seen.has(value)) return state.seen.get(value)
225
228
  StructuredDataSnapshot.#reserve(state, 1)
226
229
 
227
- const binary = BinaryDataSnapshot.describe(value)
230
+ const binary = state.standardBuiltins
231
+ ? BinaryDataSnapshot.describeStandard(value)
232
+ : BinaryDataSnapshot.describe(value)
228
233
  if (binary) {
229
234
  return StructuredDataSnapshot.#binary(value, binary, state)
230
235
  }