poe-code 12.0.3 → 12.0.4

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.
Files changed (35) hide show
  1. package/dist/index.js +423 -5
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safejs/dist/chunks/{chunk-T55OILHA.js → chunk-LF5LY5O3.js} +2 -2
  6. package/packages/safejs/dist/chunks/{chunk-Z3ZMLYCK.js → chunk-XBRQ72W6.js} +387 -5
  7. package/packages/safejs/dist/chunks/chunk-XBRQ72W6.js.map +7 -0
  8. package/packages/safejs/dist/cli.js +2 -2
  9. package/packages/safejs/dist/core.js +1 -1
  10. package/packages/safejs/dist/index.js +2 -2
  11. package/packages/safejs/dist/interp/float32.d.ts +16 -0
  12. package/packages/safejs/dist/interp/float32.js +65 -0
  13. package/packages/safejs/dist/interp/globals/float32array.d.ts +6 -0
  14. package/packages/safejs/dist/interp/globals/float32array.js +130 -0
  15. package/packages/safejs/dist/interp/globals/object-array.js +6 -0
  16. package/packages/safejs/dist/interp/host-bridge.js +18 -0
  17. package/packages/safejs/dist/interp/host-call.js +15 -0
  18. package/packages/safejs/dist/interp/interpreter.js +17 -1
  19. package/packages/safejs/dist/interp/iteration.js +4 -0
  20. package/packages/safejs/dist/interp/values.d.ts +1 -1
  21. package/packages/safejs/dist/interp/values.js +56 -0
  22. package/packages/safejs/dist/lint/rules/known-globals.d.ts +1 -1
  23. package/packages/safejs/dist/lint/rules/known-globals.js +1 -0
  24. package/packages/safejs/dist/run.js +2 -0
  25. package/packages/safejs/dist/snapshot/dump-format.js +20 -2
  26. package/packages/safejs/dist/snapshot/float32array.d.ts +12 -0
  27. package/packages/safejs/dist/snapshot/float32array.js +46 -0
  28. package/packages/safejs/dist/snapshot/replay-data.d.ts +5 -1
  29. package/packages/safejs/dist/snapshot/replay-data.js +29 -0
  30. package/packages/safejs/dist/snapshot/restore.js +14 -0
  31. package/packages/safejs/dist/snapshot/serialize.d.ts +5 -2
  32. package/packages/safejs/dist/snapshot/serialize.js +17 -2
  33. package/packages/safejs/dist/snapshot/validation.js +11 -1
  34. package/packages/safejs/dist/chunks/chunk-Z3ZMLYCK.js.map +0 -7
  35. /package/packages/safejs/dist/chunks/{chunk-T55OILHA.js.map → chunk-LF5LY5O3.js.map} +0 -0
@@ -0,0 +1,46 @@
1
+ import { float32Storage, isFloat32Array } from "../interp/float32.js";
2
+ export function encodeFloat32Storage(value, id, buffers, reference) {
3
+ const storage = float32Storage(value);
4
+ const existing = buffers.get(storage.buffer);
5
+ if (existing === undefined)
6
+ buffers.set(storage.buffer, id);
7
+ return {
8
+ kind: "float32array",
9
+ byteOffset: storage.byteOffset,
10
+ length: storage.length,
11
+ ...(existing === undefined
12
+ ? { bytes: Array.from(new Uint8Array(storage.buffer)) }
13
+ : { buffer: reference(existing) })
14
+ };
15
+ }
16
+ export function validateFloat32Storage(value) {
17
+ if (!Number.isSafeInteger(value.length) ||
18
+ Number(value.length) < 0 ||
19
+ !Number.isSafeInteger(value.byteOffset) ||
20
+ Number(value.byteOffset) < 0 ||
21
+ Number(value.byteOffset) % 4 !== 0)
22
+ throw new TypeError("Invalid Float32Array view dimensions.");
23
+ if (Object.hasOwn(value, "bytes") === Object.hasOwn(value, "buffer"))
24
+ throw new TypeError("Float32Array requires one backing storage description.");
25
+ if (Object.hasOwn(value, "bytes")) {
26
+ if (!Array.isArray(value.bytes) ||
27
+ value.bytes.some((byte) => !Number.isInteger(byte) || byte < 0 || byte > 255) ||
28
+ Number(value.length) > Math.floor((value.bytes.length - Number(value.byteOffset)) / 4))
29
+ throw new TypeError("Invalid Float32Array backing bytes.");
30
+ }
31
+ }
32
+ export function decodeFloat32Storage(value, resolve) {
33
+ validateFloat32Storage(value);
34
+ let buffer;
35
+ if (Array.isArray(value.bytes)) {
36
+ buffer = new ArrayBuffer(value.bytes.length);
37
+ new Uint8Array(buffer).set(value.bytes);
38
+ }
39
+ else {
40
+ const referenced = resolve(value.buffer);
41
+ if (!isFloat32Array(referenced))
42
+ throw new TypeError("Invalid Float32Array backing reference.");
43
+ buffer = float32Storage(referenced).buffer;
44
+ }
45
+ return new Float32Array(buffer, Number(value.byteOffset), Number(value.length));
46
+ }
@@ -1,3 +1,4 @@
1
+ import { type Float32Data } from "./float32array.js";
1
2
  import { type SandboxErrorName } from "../error/shape.js";
2
3
  import { type SandboxClosure, type SandboxPromise, type SandboxValue } from "../interp/values.js";
3
4
  import { type SerializedArguments } from "./arguments.js";
@@ -22,7 +23,10 @@ type Properties = Record<string, {
22
23
  enumerable: boolean;
23
24
  writable: boolean;
24
25
  }>;
25
- type DataNode = {
26
+ type DataNode = (Float32Data<Atom> & {
27
+ properties: Properties;
28
+ extensible: boolean;
29
+ }) | {
26
30
  kind: "capability";
27
31
  id: string;
28
32
  properties: Atom;
@@ -1,4 +1,6 @@
1
1
  import { MAX_DATA_DEPTH } from "../graph-depth.js";
2
+ import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
3
+ import { decodeFloat32Storage, encodeFloat32Storage } from "./float32array.js";
2
4
  import { sandboxErrorNames, sandboxErrorTypes } from "../error/shape.js";
3
5
  import { createSandboxArguments, createSandboxClosure, createSandboxMap, createSandboxRegex, createSandboxSet, isSandboxArguments, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, isSandboxRegex, isSandboxSet } from "../interp/values.js";
4
6
  import { serializeArguments } from "./arguments.js";
@@ -8,6 +10,7 @@ export class MissingReplayCapabilityError extends TypeError {
8
10
  export function encodeReplayData(value, options = {}) {
9
11
  const nodes = [];
10
12
  const seen = new WeakMap();
13
+ const float32Buffers = new WeakMap();
11
14
  const encode = (entry, depth, path) => {
12
15
  if (depth > MAX_DATA_DEPTH)
13
16
  throw new TypeError("Replay data exceeds the nesting limit.");
@@ -55,6 +58,22 @@ export function encodeReplayData(value, options = {}) {
55
58
  properties: child(entry.properties, "properties")
56
59
  };
57
60
  }
61
+ else if (isFloat32Array(entry)) {
62
+ const storage = encodeFloat32Storage(entry, id, float32Buffers, (id) => ({
63
+ tag: "ref",
64
+ id
65
+ }));
66
+ const properties = Object.create(null);
67
+ for (const [key, descriptor] of float32DataProperties(entry)) {
68
+ properties[key] = {
69
+ value: child(descriptor.value, key),
70
+ configurable: descriptor.configurable === true,
71
+ enumerable: descriptor.enumerable === true,
72
+ writable: descriptor.writable === true
73
+ };
74
+ }
75
+ nodes[id] = { ...storage, properties, extensible: Object.isExtensible(entry) };
76
+ }
58
77
  else if (isSandboxMap(entry)) {
59
78
  nodes[id] = {
60
79
  kind: "map",
@@ -205,6 +224,16 @@ export function decodeReplayData(input, options = {}) {
205
224
  options.onCapabilityRestored?.(capability, copy);
206
225
  return copy;
207
226
  }
227
+ if (kind === "float32array") {
228
+ if (typeof node.extensible !== "boolean")
229
+ throw new TypeError("Invalid Float32Array extensibility.");
230
+ const result = decodeFloat32Storage(node, child);
231
+ restored.set(id, result);
232
+ defineProperties(result, record(own(node, "properties")), child);
233
+ if (!node.extensible)
234
+ Object.preventExtensions(result);
235
+ return result;
236
+ }
208
237
  if (kind === "map") {
209
238
  const result = createSandboxMap();
210
239
  restored.set(id, result);
@@ -1,4 +1,5 @@
1
1
  import { Budget } from "../interp/budget.js";
2
+ import { decodeFloat32Storage } from "./float32array.js";
2
3
  import { sandboxErrorTypes } from "../error/shape.js";
3
4
  import { SnapshotMismatchError } from "../restore.js";
4
5
  import { Scope } from "../interp/interpreter.js";
@@ -321,6 +322,19 @@ function restoreHeapValue(id, state) {
321
322
  if (serialized === undefined) {
322
323
  throw new Error(`Snapshot references unknown heap value ${id}.`);
323
324
  }
325
+ if (serialized.kind === "float32array") {
326
+ const value = decodeFloat32Storage(serialized, (reference) => deserializeValue(reference, state));
327
+ state.heapValueById.set(id, value);
328
+ for (const [key, entry] of Object.entries(serialized.entries)) {
329
+ Object.defineProperty(value, key, {
330
+ value: deserializeValue(entry, state),
331
+ enumerable: true,
332
+ configurable: true,
333
+ writable: true
334
+ });
335
+ }
336
+ return value;
337
+ }
324
338
  if (serialized.kind === "array") {
325
339
  const array = new Array("items" in serialized ? serialized.items.length : serialized.length);
326
340
  state.heapValueById.set(id, array);
@@ -1,6 +1,7 @@
1
1
  import { type SandboxErrorName } from "../error/shape.js";
2
2
  import { type SerializedArguments } from "./arguments.js";
3
3
  import { type SerializedArray } from "./arrays.js";
4
+ import { type Float32Data } from "./float32array.js";
4
5
  import { type SandboxMap, type SandboxGenerator, type SandboxRegex, type SandboxSet } from "../interp/values.js";
5
6
  type SnapshotId = number | string;
6
7
  type SerializedUndefinedValue = {
@@ -39,7 +40,9 @@ export type SerializedReferenceValue = {
39
40
  kind: "ref";
40
41
  id: number;
41
42
  };
42
- export type SerializedHeapValue = SerializedArguments<SerializedSnapshotValue> | SerializedArray<SerializedSnapshotValue> | {
43
+ export type SerializedHeapValue = (Float32Data<SerializedReferenceValue> & {
44
+ entries: Record<string, SerializedSnapshotValue>;
45
+ }) | SerializedArguments<SerializedSnapshotValue> | SerializedArray<SerializedSnapshotValue> | {
43
46
  kind: "object";
44
47
  entries: Record<string, SerializedSnapshotValue>;
45
48
  errorType?: SandboxErrorName;
@@ -69,7 +72,7 @@ export type RuntimePromiseValue = {
69
72
  id: SnapshotId;
70
73
  promise?: Promise<unknown>;
71
74
  };
72
- export type RuntimeSnapshotValue = boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
75
+ export type RuntimeSnapshotValue = Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxGenerator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
73
76
  [key: string]: RuntimeSnapshotValue;
74
77
  };
75
78
  export type RuntimeScopeFrame = {
@@ -3,6 +3,8 @@ import { sandboxErrorTypes } from "../error/shape.js";
3
3
  import { assertSnapshotGraphDepth } from "../graph-depth.js";
4
4
  import { serializeArguments } from "./arguments.js";
5
5
  import { requiresArrayEntries, serializeArray } from "./arrays.js";
6
+ import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
7
+ import { encodeFloat32Storage } from "./float32array.js";
6
8
  import { isSandboxArguments, isSandboxGenerator, isSandboxMap, isSandboxRegex, isSandboxSet } from "../interp/values.js";
7
9
  export class UnsnapshotableValueError extends Error {
8
10
  path;
@@ -26,6 +28,7 @@ export function serialize(input) {
26
28
  }
27
29
  }
28
30
  const state = {
31
+ float32Buffers: new WeakMap(),
29
32
  ancestors: new WeakMap(),
30
33
  heap: Object.create(null),
31
34
  heapIds: indexHeapContainers(input),
@@ -154,7 +157,7 @@ function serializeValue(value, path, state) {
154
157
  if (isSandboxRegex(value)) {
155
158
  return { kind: "regex", source: value.source, flags: value.flags, lastIndex: value.lastIndex };
156
159
  }
157
- if (isSandboxMap(value) || isSandboxSet(value)) {
160
+ if (isSandboxMap(value) || isSandboxSet(value) || isFloat32Array(value)) {
158
161
  const reference = serializeHeapReference(value, path, state);
159
162
  if (reference === undefined) {
160
163
  throw new TypeError(`Cannot serialize collection without a heap reference at ${path}.`);
@@ -183,7 +186,17 @@ function serializeHeapReference(value, path, state) {
183
186
  }
184
187
  if (!state.serializedHeapIds.has(id)) {
185
188
  state.serializedHeapIds.add(id);
186
- if (isSandboxArguments(value)) {
189
+ if (isFloat32Array(value)) {
190
+ const storage = encodeFloat32Storage(value, id, state.float32Buffers, (id) => ({
191
+ kind: "ref",
192
+ id
193
+ }));
194
+ const entries = Object.create(null);
195
+ state.heap[String(id)] = { ...storage, entries };
196
+ for (const [key, descriptor] of float32DataProperties(value))
197
+ entries[key] = serializeValue(descriptor.value, `${path}.${key}`, state);
198
+ }
199
+ else if (isSandboxArguments(value)) {
187
200
  state.heap[String(id)] = serializeArguments(value, (entry, key) => serializeValue(entry, `${path}.${key}`, state));
188
201
  }
189
202
  else if (isSandboxMap(value)) {
@@ -280,6 +293,7 @@ function indexHeapContainers(input) {
280
293
  for (const [value, stat] of stats.entries()) {
281
294
  if (stat.count > 1 ||
282
295
  stat.cyclic ||
296
+ isFloat32Array(value) ||
283
297
  (Array.isArray(value) && requiresArrayEntries(value)) ||
284
298
  sandboxErrorTypes.has(value) ||
285
299
  isSandboxArguments(value) ||
@@ -301,6 +315,7 @@ function collectContainerStats(value, stats, ancestors) {
301
315
  }
302
316
  if (!Array.isArray(value) &&
303
317
  !isPlainObject(value) &&
318
+ !isFloat32Array(value) &&
304
319
  !isSandboxMap(value) &&
305
320
  !isSandboxSet(value)) {
306
321
  return;
@@ -2,6 +2,7 @@ import { replaceErrorStack, sandboxErrorNames } from "../error/shape.js";
2
2
  import { types } from "node:util";
3
3
  import { DUMP_FORMAT_VERSION } from "./dump-format.js";
4
4
  import { MAX_DATA_DEPTH } from "../graph-depth.js";
5
+ import { validateFloat32Storage } from "./float32array.js";
5
6
  const DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
6
7
  const DEFAULT_MAX_ENTRIES = 100_000;
7
8
  const DEFAULT_MAX_STRING_LENGTH = 1_000_000;
@@ -78,6 +79,11 @@ function validateDumpHeap(root, state) {
78
79
  addUnique(heapIds, id, path);
79
80
  const entry = requireRecord(value, path);
80
81
  validateErrorType(entry, path);
82
+ if (entry.kind === "float32array") {
83
+ validateFloat32Storage(entry);
84
+ requireRecord(entry.entries, `${path}.entries`);
85
+ continue;
86
+ }
81
87
  if (entry.kind === "arguments") {
82
88
  validateArgumentsProperties(entry, path);
83
89
  continue;
@@ -395,7 +401,7 @@ function validateGeneratorShape(record, path, state) {
395
401
  function validateHeapValue(value, path, state) {
396
402
  const record = requireRecord(value, path);
397
403
  validateErrorType(record, path);
398
- if (!["arguments", "array", "object", "map", "set"].includes(String(record.kind)))
404
+ if (!["arguments", "array", "object", "map", "set", "float32array"].includes(String(record.kind)))
399
405
  fail("unknownTag", `${path}.kind`, "unknown heap tag");
400
406
  validateValue(record, path, 1, state);
401
407
  if (record.kind === "arguments")
@@ -404,6 +410,10 @@ function validateHeapValue(value, path, state) {
404
410
  validateArrayHeap(record, path, state);
405
411
  if (record.kind === "object")
406
412
  requireRecord(record.entries, `${path}.entries`);
413
+ if (record.kind === "float32array") {
414
+ validateFloat32Storage(record);
415
+ requireRecord(record.entries, `${path}.entries`);
416
+ }
407
417
  if (record.kind === "map") {
408
418
  const entries = requireArray(record.entries, `${path}.entries`, state);
409
419
  entries.forEach((entry, index) => {