@bldrs-ai/conway 1.363.1162 → 1.364.1164

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.
@@ -547,9 +547,30 @@ function decodeNeedsCopy(buffer) {
547
547
  const b = buffer;
548
548
  return b.resizable === true || b.growable === true;
549
549
  }
550
+ function copyOutOfResizable(view) {
551
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice();
552
+ }
550
553
  function decodeUtf8(view) {
551
554
  return decoder.decode(decodeNeedsCopy(view.buffer) ? view.slice() : view);
552
555
  }
556
+ var shimInstalled = false;
557
+ function installResizableTextDecoderShim() {
558
+ if (shimInstalled || typeof TextDecoder === "undefined") {
559
+ return;
560
+ }
561
+ shimInstalled = true;
562
+ const proto = TextDecoder.prototype;
563
+ const original = proto.decode;
564
+ proto.decode = function decode(input2, options) {
565
+ if (input2 !== void 0) {
566
+ const buffer = ArrayBuffer.isView(input2) ? input2.buffer : input2;
567
+ if (decodeNeedsCopy(buffer)) {
568
+ input2 = ArrayBuffer.isView(input2) ? copyOutOfResizable(input2) : new Uint8Array(input2).slice();
569
+ }
570
+ }
571
+ return original.call(this, input2, options);
572
+ };
573
+ }
553
574
 
554
575
  // compiled/src/parsing/integer_parser.js
555
576
  var INTEGER_STATES;
@@ -1131,6 +1152,7 @@ StepEnumParser.Instance = new StepEnumParser();
1131
1152
  var step_enum_parser_default = StepEnumParser;
1132
1153
 
1133
1154
  // compiled/src/step/parsing/step_string_parser.js
1155
+ installResizableTextDecoderShim();
1134
1156
  var STRING_PARSER_STATE;
1135
1157
  (function(STRING_PARSER_STATE2) {
1136
1158
  STRING_PARSER_STATE2[STRING_PARSER_STATE2["TERMINUS"] = 0] = "TERMINUS";
@@ -69630,7 +69652,7 @@ IfcStepParser.Instance = new IfcStepParser();
69630
69652
  var ifc_step_parser_default = IfcStepParser;
69631
69653
 
69632
69654
  // compiled/src/version/version.js
69633
- var versionString = "Conway Web-Ifc Shim v1.363.1162";
69655
+ var versionString = "Conway Web-Ifc Shim v1.364.1164";
69634
69656
 
69635
69657
  // compiled/src/statistics/statistics.js
69636
69658
  var Statistics = class {
@@ -15497,9 +15497,30 @@ function decodeNeedsCopy(buffer) {
15497
15497
  const b = buffer;
15498
15498
  return b.resizable === true || b.growable === true;
15499
15499
  }
15500
+ function copyOutOfResizable(view) {
15501
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice();
15502
+ }
15500
15503
  function decodeUtf8(view) {
15501
15504
  return decoder.decode(decodeNeedsCopy(view.buffer) ? view.slice() : view);
15502
15505
  }
15506
+ var shimInstalled = false;
15507
+ function installResizableTextDecoderShim() {
15508
+ if (shimInstalled || typeof TextDecoder === "undefined") {
15509
+ return;
15510
+ }
15511
+ shimInstalled = true;
15512
+ const proto = TextDecoder.prototype;
15513
+ const original = proto.decode;
15514
+ proto.decode = function decode(input, options) {
15515
+ if (input !== void 0) {
15516
+ const buffer = ArrayBuffer.isView(input) ? input.buffer : input;
15517
+ if (decodeNeedsCopy(buffer)) {
15518
+ input = ArrayBuffer.isView(input) ? copyOutOfResizable(input) : new Uint8Array(input).slice();
15519
+ }
15520
+ }
15521
+ return original.call(this, input, options);
15522
+ };
15523
+ }
15503
15524
 
15504
15525
  // compiled/src/parsing/integer_parser.js
15505
15526
  var INTEGER_STATES;
@@ -16081,6 +16102,7 @@ StepEnumParser.Instance = new StepEnumParser();
16081
16102
  var step_enum_parser_default = StepEnumParser;
16082
16103
 
16083
16104
  // compiled/src/step/parsing/step_string_parser.js
16105
+ installResizableTextDecoderShim();
16084
16106
  var STRING_PARSER_STATE;
16085
16107
  (function(STRING_PARSER_STATE2) {
16086
16108
  STRING_PARSER_STATE2[STRING_PARSER_STATE2["TERMINUS"] = 0] = "TERMINUS";
@@ -85886,7 +85908,7 @@ var IfcSceneBuilder = class {
85886
85908
  };
85887
85909
 
85888
85910
  // compiled/src/version/version.js
85889
- var versionString = "Conway Web-Ifc Shim v1.363.1162";
85911
+ var versionString = "Conway Web-Ifc Shim v1.364.1164";
85890
85912
 
85891
85913
  // compiled/src/statistics/statistics.js
85892
85914
  var Statistics = class {
@@ -16008,9 +16008,30 @@ function decodeNeedsCopy(buffer) {
16008
16008
  const b = buffer;
16009
16009
  return b.resizable === true || b.growable === true;
16010
16010
  }
16011
+ function copyOutOfResizable(view) {
16012
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice();
16013
+ }
16011
16014
  function decodeUtf8(view) {
16012
16015
  return decoder.decode(decodeNeedsCopy(view.buffer) ? view.slice() : view);
16013
16016
  }
16017
+ var shimInstalled = false;
16018
+ function installResizableTextDecoderShim() {
16019
+ if (shimInstalled || typeof TextDecoder === "undefined") {
16020
+ return;
16021
+ }
16022
+ shimInstalled = true;
16023
+ const proto = TextDecoder.prototype;
16024
+ const original = proto.decode;
16025
+ proto.decode = function decode(input, options) {
16026
+ if (input !== void 0) {
16027
+ const buffer = ArrayBuffer.isView(input) ? input.buffer : input;
16028
+ if (decodeNeedsCopy(buffer)) {
16029
+ input = ArrayBuffer.isView(input) ? copyOutOfResizable(input) : new Uint8Array(input).slice();
16030
+ }
16031
+ }
16032
+ return original.call(this, input, options);
16033
+ };
16034
+ }
16014
16035
 
16015
16036
  // compiled/src/step/parsing/step_entity_identifier_parser.js
16016
16037
  var IDENTIFIER_PARSER_STATE;
@@ -16081,6 +16102,7 @@ StepEnumParser.Instance = new StepEnumParser();
16081
16102
  var step_enum_parser_default = StepEnumParser;
16082
16103
 
16083
16104
  // compiled/src/step/parsing/step_string_parser.js
16105
+ installResizableTextDecoderShim();
16084
16106
  var STRING_PARSER_STATE;
16085
16107
  (function(STRING_PARSER_STATE2) {
16086
16108
  STRING_PARSER_STATE2[STRING_PARSER_STATE2["TERMINUS"] = 0] = "TERMINUS";
@@ -79337,7 +79359,7 @@ var ExtractResult;
79337
79359
  })(ExtractResult || (ExtractResult = {}));
79338
79360
 
79339
79361
  // compiled/src/version/version.js
79340
- var versionString = "Conway Web-Ifc Shim v1.363.1162";
79362
+ var versionString = "Conway Web-Ifc Shim v1.364.1164";
79341
79363
 
79342
79364
  // compiled/src/statistics/statistics.js
79343
79365
  var Statistics = class {
@@ -1461,9 +1461,30 @@ function decodeNeedsCopy(buffer) {
1461
1461
  const b = buffer;
1462
1462
  return b.resizable === true || b.growable === true;
1463
1463
  }
1464
+ function copyOutOfResizable(view) {
1465
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice();
1466
+ }
1464
1467
  function decodeUtf8(view) {
1465
1468
  return decoder.decode(decodeNeedsCopy(view.buffer) ? view.slice() : view);
1466
1469
  }
1470
+ var shimInstalled = false;
1471
+ function installResizableTextDecoderShim() {
1472
+ if (shimInstalled || typeof TextDecoder === "undefined") {
1473
+ return;
1474
+ }
1475
+ shimInstalled = true;
1476
+ const proto = TextDecoder.prototype;
1477
+ const original = proto.decode;
1478
+ proto.decode = function decode(input, options) {
1479
+ if (input !== void 0) {
1480
+ const buffer = ArrayBuffer.isView(input) ? input.buffer : input;
1481
+ if (decodeNeedsCopy(buffer)) {
1482
+ input = ArrayBuffer.isView(input) ? copyOutOfResizable(input) : new Uint8Array(input).slice();
1483
+ }
1484
+ }
1485
+ return original.call(this, input, options);
1486
+ };
1487
+ }
1467
1488
 
1468
1489
  // compiled/src/parsing/integer_parser.js
1469
1490
  var INTEGER_STATES;
@@ -2045,6 +2066,7 @@ StepEnumParser.Instance = new StepEnumParser();
2045
2066
  var step_enum_parser_default = StepEnumParser;
2046
2067
 
2047
2068
  // compiled/src/step/parsing/step_string_parser.js
2069
+ installResizableTextDecoderShim();
2048
2070
  var STRING_PARSER_STATE;
2049
2071
  (function(STRING_PARSER_STATE2) {
2050
2072
  STRING_PARSER_STATE2[STRING_PARSER_STATE2["TERMINUS"] = 0] = "TERMINUS";
@@ -69628,7 +69650,7 @@ IfcStepParser.Instance = new IfcStepParser();
69628
69650
  var ifc_step_parser_default = IfcStepParser;
69629
69651
 
69630
69652
  // compiled/src/version/version.js
69631
- var versionString = "Conway Web-Ifc Shim v1.363.1162";
69653
+ var versionString = "Conway Web-Ifc Shim v1.364.1164";
69632
69654
 
69633
69655
  // compiled/src/statistics/statistics.js
69634
69656
  var Statistics = class {
@@ -1,17 +1,23 @@
1
1
  /**
2
- * UTF-8 decoding for STEP bytes that may live in the wasm heap.
2
+ * UTF-8 decoding compat for the Emscripten 6.0.2 resizable wasm heap.
3
3
  *
4
4
  * Under Emscripten 6.0.2 the browser wasm heap is exposed as a *resizable*
5
- * ArrayBuffer (or a growable SharedArrayBuffer on the threaded build). Strict
6
- * browsers' `TextDecoder.decode()` throws a TypeError when handed a view backed
7
- * by such a buffer ("...can't be a resizable ArrayBuffer"). When STEP entity
8
- * string/enum bytes are decoded straight from a heap view, that throw is caught
9
- * upstream as an extraction error and the affected face/style is silently
10
- * dropped — producing see-through geometry in Chrome/Firefox, while Safari
11
- * (which tolerates it) and Node (lenient) render correctly.
5
+ * ArrayBuffer (a growable SharedArrayBuffer on the threaded build — see
6
+ * `wasmMemory.toResizableBuffer()` in the generated glue). Strict browsers'
7
+ * `TextDecoder.decode()` throws a TypeError when handed a view backed by such a
8
+ * buffer ("...can't be a resizable ArrayBuffer"). Anything that decodes a heap
9
+ * view then throws and, when that happens inside geometry extraction, the face
10
+ * is silently dropped — producing see-through models in Chrome/Firefox, while
11
+ * Safari (which tolerates it) and Node (whose heap is not resizable) are fine.
12
12
  *
13
- * `decodeUtf8` copies the view out of a resizable/growable buffer before
14
- * decoding; Node, Safari, and pre-6 builds keep the zero-copy fast path.
13
+ * Two decoders hit this:
14
+ * 1. Our own STEP string/enum decodes routed through `decodeUtf8` below.
15
+ * 2. Emscripten's `UTF8ToString` / embind `std::string` returns in the wasm
16
+ * glue, which we do NOT own — covered by the global prototype shim, since
17
+ * the glue calls `TextDecoder.prototype.decode` like everyone else.
18
+ *
19
+ * Both copy the bytes out of a resizable/growable buffer first; plain buffers
20
+ * (Node, Safari, pre-6 builds) keep the zero-copy fast path.
15
21
  */
16
22
  /**
17
23
  * UTF-8 decode a byte view, tolerating wasm-heap-backed resizable/growable
@@ -21,4 +27,13 @@
21
27
  * @return The decoded string.
22
28
  */
23
29
  export declare function decodeUtf8(view: Uint8Array): string;
30
+ /**
31
+ * Install a global, idempotent `TextDecoder.prototype.decode` shim that copies a
32
+ * view out of a resizable/growable buffer before decoding. This covers decodes
33
+ * we do not own — chiefly Emscripten's `UTF8ToString` and embind `std::string`
34
+ * returns in the wasm glue, which read straight from the resizable wasm heap and
35
+ * would otherwise throw mid-extraction and drop geometry. A no-op where
36
+ * `TextDecoder` is absent or the buffer is plain.
37
+ */
38
+ export declare function installResizableTextDecoderShim(): void;
24
39
  //# sourceMappingURL=decode_utf8.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"decode_utf8.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/decode_utf8.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"decode_utf8.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/decode_utf8.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA+BH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEnD;AAID;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAqBtD"}
@@ -1,17 +1,23 @@
1
1
  /**
2
- * UTF-8 decoding for STEP bytes that may live in the wasm heap.
2
+ * UTF-8 decoding compat for the Emscripten 6.0.2 resizable wasm heap.
3
3
  *
4
4
  * Under Emscripten 6.0.2 the browser wasm heap is exposed as a *resizable*
5
- * ArrayBuffer (or a growable SharedArrayBuffer on the threaded build). Strict
6
- * browsers' `TextDecoder.decode()` throws a TypeError when handed a view backed
7
- * by such a buffer ("...can't be a resizable ArrayBuffer"). When STEP entity
8
- * string/enum bytes are decoded straight from a heap view, that throw is caught
9
- * upstream as an extraction error and the affected face/style is silently
10
- * dropped — producing see-through geometry in Chrome/Firefox, while Safari
11
- * (which tolerates it) and Node (lenient) render correctly.
5
+ * ArrayBuffer (a growable SharedArrayBuffer on the threaded build — see
6
+ * `wasmMemory.toResizableBuffer()` in the generated glue). Strict browsers'
7
+ * `TextDecoder.decode()` throws a TypeError when handed a view backed by such a
8
+ * buffer ("...can't be a resizable ArrayBuffer"). Anything that decodes a heap
9
+ * view then throws and, when that happens inside geometry extraction, the face
10
+ * is silently dropped — producing see-through models in Chrome/Firefox, while
11
+ * Safari (which tolerates it) and Node (whose heap is not resizable) are fine.
12
12
  *
13
- * `decodeUtf8` copies the view out of a resizable/growable buffer before
14
- * decoding; Node, Safari, and pre-6 builds keep the zero-copy fast path.
13
+ * Two decoders hit this:
14
+ * 1. Our own STEP string/enum decodes routed through `decodeUtf8` below.
15
+ * 2. Emscripten's `UTF8ToString` / embind `std::string` returns in the wasm
16
+ * glue, which we do NOT own — covered by the global prototype shim, since
17
+ * the glue calls `TextDecoder.prototype.decode` like everyone else.
18
+ *
19
+ * Both copy the bytes out of a resizable/growable buffer first; plain buffers
20
+ * (Node, Safari, pre-6 builds) keep the zero-copy fast path.
15
21
  */
16
22
  const decoder = new TextDecoder();
17
23
  /**
@@ -19,7 +25,7 @@ const decoder = new TextDecoder();
19
25
  *
20
26
  * `resizable` (ArrayBuffer) and `growable` (SharedArrayBuffer) are the buffer
21
27
  * shapes strict engines refuse; both are absent (undefined) on plain buffers,
22
- * so this stays false — and the caller stays zero-copy — everywhere except the
28
+ * so this stays false — and callers stay zero-copy — everywhere except the
23
29
  * Emscripten 6 browser heap.
24
30
  *
25
31
  * @param buffer The backing buffer of a byte view.
@@ -29,6 +35,15 @@ function decodeNeedsCopy(buffer) {
29
35
  const b = buffer;
30
36
  return b.resizable === true || b.growable === true;
31
37
  }
38
+ /**
39
+ * Copy an array-buffer view into a fresh, plain (non-resizable) `Uint8Array`.
40
+ *
41
+ * @param view The view to copy.
42
+ * @return A plain-buffer copy of the view's bytes.
43
+ */
44
+ function copyOutOfResizable(view) {
45
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength).slice();
46
+ }
32
47
  /**
33
48
  * UTF-8 decode a byte view, tolerating wasm-heap-backed resizable/growable
34
49
  * buffers that `TextDecoder.decode()` would otherwise reject.
@@ -39,3 +54,31 @@ function decodeNeedsCopy(buffer) {
39
54
  export function decodeUtf8(view) {
40
55
  return decoder.decode(decodeNeedsCopy(view.buffer) ? view.slice() : view);
41
56
  }
57
+ let shimInstalled = false;
58
+ /**
59
+ * Install a global, idempotent `TextDecoder.prototype.decode` shim that copies a
60
+ * view out of a resizable/growable buffer before decoding. This covers decodes
61
+ * we do not own — chiefly Emscripten's `UTF8ToString` and embind `std::string`
62
+ * returns in the wasm glue, which read straight from the resizable wasm heap and
63
+ * would otherwise throw mid-extraction and drop geometry. A no-op where
64
+ * `TextDecoder` is absent or the buffer is plain.
65
+ */
66
+ export function installResizableTextDecoderShim() {
67
+ if (shimInstalled || typeof TextDecoder === 'undefined') {
68
+ return;
69
+ }
70
+ shimInstalled = true;
71
+ const proto = TextDecoder.prototype;
72
+ const original = proto.decode;
73
+ proto.decode = function decode(input, options) {
74
+ if (input !== undefined) {
75
+ const buffer = (ArrayBuffer.isView(input) ? input.buffer : input);
76
+ if (decodeNeedsCopy(buffer)) {
77
+ input = ArrayBuffer.isView(input) ?
78
+ copyOutOfResizable(input) :
79
+ new Uint8Array(input).slice();
80
+ }
81
+ }
82
+ return original.call(this, input, options);
83
+ };
84
+ }
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, test } from "@jest/globals";
2
- import { decodeUtf8 } from "./decode_utf8.js";
2
+ import { decodeUtf8, installResizableTextDecoderShim } from "./decode_utf8.js";
3
3
  /**
4
4
  * Build a Uint8Array view whose backing buffer is a *resizable* ArrayBuffer —
5
5
  * the shape the Emscripten 6.0.2 browser wasm heap presents, and which strict
@@ -58,4 +58,31 @@ describe("decodeUtf8", () => {
58
58
  const view = resizableView("caf\u00E9 \u2014 \u03A9");
59
59
  expect(decodeUtf8(view)).toBe("caf\u00E9 \u2014 \u03A9");
60
60
  });
61
+ test("global shim rescues decodes we do not own (e.g. the wasm glue)", () => {
62
+ // The wasm glue's UTF8ToString / embind string returns call
63
+ // TextDecoder.prototype.decode directly on resizable-heap views — we can't
64
+ // route those through decodeUtf8. The global shim must intercept them.
65
+ const proto = TextDecoder.prototype;
66
+ const realDecode = proto.decode;
67
+ // Simulate a strict browser: the base decode throws on a resizable view.
68
+ proto.decode = function strict(input, opts) {
69
+ const buffer = (ArrayBuffer.isView(input) ? input.buffer : input);
70
+ if (buffer?.resizable === true) {
71
+ throw new TypeError("TextDecoder.decode: ... can't be a resizable ArrayBuffer");
72
+ }
73
+ return realDecode.call(this, input, opts);
74
+ };
75
+ try {
76
+ const view = resizableView("ADVANCED_FACE_STRING_VALUE");
77
+ // Before the shim, a raw decode (the glue's path) throws.
78
+ expect(() => proto.decode.call(new TextDecoder(), view)).toThrow(TypeError);
79
+ // Install the shim on top of the strict base.
80
+ installResizableTextDecoderShim();
81
+ // Now the same raw decode is intercepted, copied out, and succeeds.
82
+ expect(new TextDecoder().decode(view)).toBe("ADVANCED_FACE_STRING_VALUE");
83
+ }
84
+ finally {
85
+ proto.decode = realDecode;
86
+ }
87
+ });
61
88
  });
@@ -1 +1 @@
1
- {"version":3,"file":"step_string_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_string_parser.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,MAAM,mCAAmC,CAAA;AAkDjE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,iBAAiB;IAE7D;;OAEG;;IA6BI,OAAO,UACH,UAAU,UACT,MAAM,aACH,MAAM,aACP,MAAM,KAAO,MAAM,GAAG,SAAS,CAuR5C;IAED;;;;;;;;OAQG;IACI,KAAK,UAAW,UAAU,UAAU,MAAM,aAAa,MAAM,KAAG,MAAM,GAAG,SAAS,CAexF;IAED,gBAAuB,QAAQ,mBAAyB;CACzD"}
1
+ {"version":3,"file":"step_string_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_string_parser.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,MAAM,mCAAmC,CAAA;AAwDjE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,iBAAiB;IAE7D;;OAEG;;IA6BI,OAAO,UACH,UAAU,UACT,MAAM,aACH,MAAM,aACP,MAAM,KAAO,MAAM,GAAG,SAAS,CAuR5C;IAED;;;;;;;;OAQG;IACI,KAAK,UAAW,UAAU,UAAU,MAAM,aAAa,MAAM,KAAG,MAAM,GAAG,SAAS,CAexF;IAED,gBAAuB,QAAQ,mBAAyB;CACzD"}
@@ -1,6 +1,11 @@
1
1
  import ParsingConstants from "../../parsing/parsing_constants.js";
2
2
  import ParsingDfa16Table from "../../parsing/parsing_dfa_16table.js";
3
- import { decodeUtf8 } from "./decode_utf8.js";
3
+ import { decodeUtf8, installResizableTextDecoderShim } from "./decode_utf8.js";
4
+ // Emscripten 6's browser wasm heap is a resizable ArrayBuffer, on which strict
5
+ // browsers' TextDecoder.decode() throws — including the glue's own UTF8ToString
6
+ // during geometry extraction. Install the global copy-first shim as the STEP
7
+ // pipeline loads, before any heap-string decode. Idempotent.
8
+ installResizableTextDecoderShim();
4
9
  /**
5
10
  * Enum representing the state machine of the string parser DFA.
6
11
  */
@@ -5,5 +5,5 @@
5
5
  // only the first segment (major) is meaningful and is the one CI carries forward.
6
6
  // Must stay in `vN.N.N` shape: the CI stamp regex, scripts/updateVersion.mjs, and
7
7
  // statistics.ts all match `v\d+\.\d+\.\d+`.
8
- const versionString = 'Conway Web-Ifc Shim v1.363.1162';
8
+ const versionString = 'Conway Web-Ifc Shim v1.364.1164';
9
9
  export { versionString };