@ifc-lite/parser 5.1.0 → 6.1.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/dist/classification-resolver.d.ts.map +1 -1
- package/dist/classification-resolver.js +35 -10
- package/dist/classification-resolver.js.map +1 -1
- package/dist/columnar-entity-preparation.d.ts +25 -0
- package/dist/columnar-entity-preparation.d.ts.map +1 -0
- package/dist/columnar-entity-preparation.js +282 -0
- package/dist/columnar-entity-preparation.js.map +1 -0
- package/dist/columnar-parser-indexes.d.ts +17 -1
- package/dist/columnar-parser-indexes.d.ts.map +1 -1
- package/dist/columnar-parser-indexes.js +31 -21
- package/dist/columnar-parser-indexes.js.map +1 -1
- package/dist/columnar-parser-root-attributes.d.ts +66 -0
- package/dist/columnar-parser-root-attributes.d.ts.map +1 -0
- package/dist/columnar-parser-root-attributes.js +245 -0
- package/dist/columnar-parser-root-attributes.js.map +1 -0
- package/dist/columnar-parser.d.ts +26 -63
- package/dist/columnar-parser.d.ts.map +1 -1
- package/dist/columnar-parser.js +384 -751
- package/dist/columnar-parser.js.map +1 -1
- package/dist/compact-entity-index-columns.d.ts +17 -0
- package/dist/compact-entity-index-columns.d.ts.map +1 -0
- package/dist/compact-entity-index-columns.js +15 -0
- package/dist/compact-entity-index-columns.js.map +1 -0
- package/dist/compact-entity-index-transport.d.ts +2 -12
- package/dist/compact-entity-index-transport.d.ts.map +1 -1
- package/dist/compact-entity-index-transport.js +1 -11
- package/dist/compact-entity-index-transport.js.map +1 -1
- package/dist/compact-entity-index.d.ts +6 -0
- package/dist/compact-entity-index.d.ts.map +1 -1
- package/dist/compact-entity-index.js +12 -20
- package/dist/compact-entity-index.js.map +1 -1
- package/dist/cost-extractor.d.ts +10 -0
- package/dist/cost-extractor.d.ts.map +1 -0
- package/dist/cost-extractor.js +369 -0
- package/dist/cost-extractor.js.map +1 -0
- package/dist/cost-schedule-2x3.d.ts +31 -0
- package/dist/cost-schedule-2x3.d.ts.map +1 -0
- package/dist/cost-schedule-2x3.js +75 -0
- package/dist/cost-schedule-2x3.js.map +1 -0
- package/dist/cost-types.d.ts +105 -0
- package/dist/cost-types.d.ts.map +1 -0
- package/dist/cost-types.js +5 -0
- package/dist/cost-types.js.map +1 -0
- package/dist/data-store-transport.d.ts +3 -2
- package/dist/data-store-transport.d.ts.map +1 -1
- package/dist/data-store-transport.js +10 -34
- package/dist/data-store-transport.js.map +1 -1
- package/dist/drop-census.d.ts +136 -0
- package/dist/drop-census.d.ts.map +1 -0
- package/dist/drop-census.js +53 -0
- package/dist/drop-census.js.map +1 -0
- package/dist/entity-refs-from-index.d.ts +10 -0
- package/dist/entity-refs-from-index.d.ts.map +1 -1
- package/dist/entity-refs-from-index.js +52 -36
- package/dist/entity-refs-from-index.js.map +1 -1
- package/dist/entity-scanner.d.ts +5 -0
- package/dist/entity-scanner.d.ts.map +1 -1
- package/dist/entity-scanner.js +30 -12
- package/dist/entity-scanner.js.map +1 -1
- package/dist/entity-type-byte-interner.d.ts +12 -0
- package/dist/entity-type-byte-interner.d.ts.map +1 -0
- package/dist/entity-type-byte-interner.js +66 -0
- package/dist/entity-type-byte-interner.js.map +1 -0
- package/dist/generated/ifc2x3/schema-registry.d.ts +50 -0
- package/dist/generated/ifc2x3/schema-registry.d.ts.map +1 -0
- package/dist/generated/ifc2x3/schema-registry.js +50052 -0
- package/dist/generated/ifc2x3/schema-registry.js.map +1 -0
- package/dist/generated/ifc4x3/schema-registry.d.ts +50 -0
- package/dist/generated/ifc4x3/schema-registry.d.ts.map +1 -0
- package/dist/generated/ifc4x3/schema-registry.js +71299 -0
- package/dist/generated/ifc4x3/schema-registry.js.map +1 -0
- package/dist/generated/schema-registry-by-version.d.ts +61 -0
- package/dist/generated/schema-registry-by-version.d.ts.map +1 -0
- package/dist/generated/schema-registry-by-version.js +86 -0
- package/dist/generated/schema-registry-by-version.js.map +1 -0
- package/dist/group-assignment-factor.d.ts +13 -0
- package/dist/group-assignment-factor.d.ts.map +1 -0
- package/dist/group-assignment-factor.js +30 -0
- package/dist/group-assignment-factor.js.map +1 -0
- package/dist/ifczip.d.ts +6 -0
- package/dist/ifczip.d.ts.map +1 -1
- package/dist/ifczip.js +20 -11
- package/dist/ifczip.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/on-demand-extractors.d.ts +1 -0
- package/dist/on-demand-extractors.d.ts.map +1 -1
- package/dist/on-demand-extractors.js +2 -1
- package/dist/on-demand-extractors.js.map +1 -1
- package/dist/parser.worker.d.ts +6 -3
- package/dist/parser.worker.d.ts.map +1 -1
- package/dist/parser.worker.js +24 -12
- package/dist/parser.worker.js.map +1 -1
- package/dist/prepass-source-fingerprint.d.ts +3 -0
- package/dist/prepass-source-fingerprint.d.ts.map +1 -0
- package/dist/prepass-source-fingerprint.js +13 -0
- package/dist/prepass-source-fingerprint.js.map +1 -0
- package/dist/property-value-parser.d.ts +10 -0
- package/dist/property-value-parser.d.ts.map +1 -1
- package/dist/property-value-parser.js +40 -1
- package/dist/property-value-parser.js.map +1 -1
- package/dist/scan-entities-balanced.d.ts.map +1 -1
- package/dist/scan-entities-balanced.js +8 -6
- package/dist/scan-entities-balanced.js.map +1 -1
- package/dist/scan-worker-lexing.d.ts +14 -0
- package/dist/scan-worker-lexing.d.ts.map +1 -0
- package/dist/scan-worker-lexing.js +101 -0
- package/dist/scan-worker-lexing.js.map +1 -0
- package/dist/scan-worker-source.d.ts +1 -1
- package/dist/scan-worker-source.d.ts.map +1 -1
- package/dist/scan-worker-source.js +61 -59
- package/dist/scan-worker-source.js.map +1 -1
- package/dist/schedule-extractor.d.ts +2 -80
- package/dist/schedule-extractor.d.ts.map +1 -1
- package/dist/schedule-extractor.js +100 -225
- package/dist/schedule-extractor.js.map +1 -1
- package/dist/schedule-serializer-builders.d.ts +28 -0
- package/dist/schedule-serializer-builders.d.ts.map +1 -0
- package/dist/schedule-serializer-builders.js +163 -0
- package/dist/schedule-serializer-builders.js.map +1 -0
- package/dist/schedule-serializer.d.ts +6 -0
- package/dist/schedule-serializer.d.ts.map +1 -1
- package/dist/schedule-serializer.js +26 -165
- package/dist/schedule-serializer.js.map +1 -1
- package/dist/schedule-types.d.ts +211 -0
- package/dist/schedule-types.d.ts.map +1 -0
- package/dist/schedule-types.js +221 -0
- package/dist/schedule-types.js.map +1 -0
- package/dist/select-entity-columns.d.ts +7 -0
- package/dist/select-entity-columns.d.ts.map +1 -0
- package/dist/select-entity-columns.js +43 -0
- package/dist/select-entity-columns.js.map +1 -0
- package/dist/spatial-hierarchy-ambiguity.d.ts +39 -0
- package/dist/spatial-hierarchy-ambiguity.d.ts.map +1 -0
- package/dist/spatial-hierarchy-ambiguity.js +25 -0
- package/dist/spatial-hierarchy-ambiguity.js.map +1 -0
- package/dist/spatial-hierarchy-attributes.d.ts +54 -0
- package/dist/spatial-hierarchy-attributes.d.ts.map +1 -0
- package/dist/spatial-hierarchy-attributes.js +145 -0
- package/dist/spatial-hierarchy-attributes.js.map +1 -0
- package/dist/spatial-hierarchy-builder.d.ts +6 -38
- package/dist/spatial-hierarchy-builder.d.ts.map +1 -1
- package/dist/spatial-hierarchy-builder.js +48 -166
- package/dist/spatial-hierarchy-builder.js.map +1 -1
- package/dist/spatial-hierarchy-canonical-parent.d.ts +86 -0
- package/dist/spatial-hierarchy-canonical-parent.d.ts.map +1 -0
- package/dist/spatial-hierarchy-canonical-parent.js +212 -0
- package/dist/spatial-hierarchy-canonical-parent.js.map +1 -0
- package/dist/step-lexing.d.ts +1 -1
- package/dist/step-lexing.d.ts.map +1 -1
- package/dist/step-lexing.js +1 -56
- package/dist/step-lexing.js.map +1 -1
- package/dist/step-record-boundary.d.ts +28 -0
- package/dist/step-record-boundary.d.ts.map +1 -0
- package/dist/step-record-boundary.js +108 -0
- package/dist/step-record-boundary.js.map +1 -0
- package/dist/step-record-boundary.vectors.d.ts +58 -0
- package/dist/step-record-boundary.vectors.d.ts.map +1 -0
- package/dist/step-record-boundary.vectors.js +80 -0
- package/dist/step-record-boundary.vectors.js.map +1 -0
- package/dist/structural-extractor.d.ts +9 -0
- package/dist/structural-extractor.d.ts.map +1 -0
- package/dist/structural-extractor.js +310 -0
- package/dist/structural-extractor.js.map +1 -0
- package/dist/structural-load-extractor.d.ts +147 -0
- package/dist/structural-load-extractor.d.ts.map +1 -0
- package/dist/structural-load-extractor.js +178 -0
- package/dist/structural-load-extractor.js.map +1 -0
- package/dist/structural-step-values.d.ts +51 -0
- package/dist/structural-step-values.d.ts.map +1 -0
- package/dist/structural-step-values.js +109 -0
- package/dist/structural-step-values.js.map +1 -0
- package/dist/structural-types.d.ts +145 -0
- package/dist/structural-types.d.ts.map +1 -0
- package/dist/structural-types.js +5 -0
- package/dist/structural-types.js.map +1 -0
- package/dist/tokenizer.d.ts +11 -5
- package/dist/tokenizer.d.ts.map +1 -1
- package/dist/tokenizer.js +75 -21
- package/dist/tokenizer.js.map +1 -1
- package/dist/wasm-init-retry.d.ts +6 -42
- package/dist/wasm-init-retry.d.ts.map +1 -1
- package/dist/wasm-init-retry.js +6 -99
- package/dist/wasm-init-retry.js.map +1 -1
- package/dist/wasm-panic-forward.d.ts +7 -63
- package/dist/wasm-panic-forward.d.ts.map +1 -1
- package/dist/wasm-panic-forward.js +7 -100
- package/dist/wasm-panic-forward.js.map +1 -1
- package/dist/worker-index-publication.d.ts +43 -0
- package/dist/worker-index-publication.d.ts.map +1 -0
- package/dist/worker-index-publication.js +129 -0
- package/dist/worker-index-publication.js.map +1 -0
- package/dist/worker-parser.d.ts +5 -2
- package/dist/worker-parser.d.ts.map +1 -1
- package/dist/worker-parser.js +22 -10
- package/dist/worker-parser.js.map +1 -1
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-init-retry.d.ts","sourceRoot":"","sources":["../src/wasm-init-retry.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"wasm-init-retry.d.ts","sourceRoot":"","sources":["../src/wasm-init-retry.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,0BAA0B,CAAC"}
|
package/dist/wasm-init-retry.js
CHANGED
|
@@ -2,105 +2,12 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Re-export of the shared WASM load-retry classification (issue #4247).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* cold CDN edge, a mid-deploy race, a flaky proxy/antivirus — can produce a
|
|
12
|
-
* one-off failure that a second attempt recovers.
|
|
13
|
-
*
|
|
14
|
-
* Extracted from the worker so it is unit-testable without a real wasm bundle.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* True when `message` looks like a transient transport/download failure of the
|
|
18
|
-
* engine binary (worth one retry) rather than a genuine corrupt-module or
|
|
19
|
-
* validation error (which must propagate immediately so real bugs aren't
|
|
20
|
-
* masked).
|
|
21
|
-
*
|
|
22
|
-
* Per the WebAssembly Web API, the streaming loader validates the HTTP response
|
|
23
|
-
* (status, MIME, CORS) and rejects with a `TypeError` BEFORE compiling, so only
|
|
24
|
-
* those transport failures are retry-worthy. Invalid bytes (corrupt module,
|
|
25
|
-
* wrong magic header) reject with a `CompileError` — retrying just refetches
|
|
26
|
-
* the same bad bytes, so those fail fast.
|
|
27
|
-
*/
|
|
28
|
-
export function isTransientWasmLoadError(message) {
|
|
29
|
-
// Fail fast on genuine module-validation errors even if a transport-ish word
|
|
30
|
-
// somehow appears in the message.
|
|
31
|
-
if (/compileerror|validation error|magic (?:word|number)|invalid (?:wasm|module)/i.test(message)) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return /HTTP status code is not ok|failed to fetch|network ?error|load failed/i.test(message);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* A message that already names the thing that failed to load, so re-throwing it
|
|
38
|
-
* with an attribution prefix would only add noise. Deliberately includes
|
|
39
|
-
* `WebAssembly` (the `'compile' on 'WebAssembly'` phrasings) — those are exactly
|
|
40
|
-
* the signatures `isWasmAssetUnavailableError` (wasm-asset-error.ts) matches to
|
|
41
|
-
* drive the #1363 stale-deploy reload, and they must reach it byte-for-byte.
|
|
42
|
-
*/
|
|
43
|
-
const SELF_IDENTIFYING = /wasm|webassembly/i;
|
|
44
|
-
/**
|
|
45
|
-
* A failed *module* load already carries its own specifier. Prefixing one with
|
|
46
|
-
* `ifc-lite_bg.wasm` would make it look to that same #1363 matcher like a
|
|
47
|
-
* rotated ENGINE BINARY (`/\.wasm/` + "dynamically imported module") and
|
|
48
|
-
* trigger a spurious page reload, so those are passed through untouched.
|
|
49
|
-
*/
|
|
50
|
-
const MODULE_LOAD_FAILURE = /dynamically imported module|module script/i;
|
|
51
|
-
/**
|
|
52
|
-
* Name the engine binary in a transport failure that names nothing (issue #1903).
|
|
53
|
-
*
|
|
54
|
-
* wasm-bindgen's generated loader `await`s the `fetch()` it starts, so a
|
|
55
|
-
* network-level rejection propagates RAW: WebKit words it `TypeError: Load
|
|
56
|
-
* failed`, Chromium `TypeError: Failed to fetch`, and because the rejection
|
|
57
|
-
* originates inside the fetch rather than in our frames it carries an EMPTY
|
|
58
|
-
* stack. Two words and no frames is unattributable by construction — the toast,
|
|
59
|
-
* `classifyLoadError` in the viewer, and error tracking all see a bare
|
|
60
|
-
* `TypeError` that could have come from anywhere in the load.
|
|
61
|
-
*
|
|
62
|
-
* So when the final failure identifies nothing, re-throw it naming the binary
|
|
63
|
-
* and the call site, preserving the original as `.cause`. Anything that already
|
|
64
|
-
* identifies itself is returned unchanged.
|
|
65
|
-
*/
|
|
66
|
-
function attributeEngineLoadFailure(error, label) {
|
|
67
|
-
if (!(error instanceof Error))
|
|
68
|
-
return error;
|
|
69
|
-
const msg = error.message;
|
|
70
|
-
if (!isTransientWasmLoadError(msg))
|
|
71
|
-
return error;
|
|
72
|
-
if (SELF_IDENTIFYING.test(msg) || MODULE_LOAD_FAILURE.test(msg))
|
|
73
|
-
return error;
|
|
74
|
-
return new Error(`Failed to load the WASM engine binary (ifc-lite_bg.wasm) in ${label}: ${msg}`, { cause: error });
|
|
75
|
-
}
|
|
76
|
-
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
77
|
-
/**
|
|
78
|
-
* Run `init` once; on a transient-looking failure, wait and retry exactly once.
|
|
79
|
-
* Non-transient failures propagate without a retry. The second failure (if any)
|
|
80
|
-
* propagates to the caller — attributed to the engine binary when the browser's
|
|
81
|
-
* own wording identifies nothing (see {@link attributeEngineLoadFailure}).
|
|
82
|
-
*
|
|
83
|
-
* @param init Thunk that performs the actual `init(...)` call (so callers can
|
|
84
|
-
* bind their own wasm URL / arguments).
|
|
7
|
+
* The real implementation lives in `@ifc-lite/wasm-lifecycle` so
|
|
8
|
+
* `@ifc-lite/geometry` and `@ifc-lite/parser` share exactly one copy of the
|
|
9
|
+
* transient-vs-fatal WASM load-failure logic instead of maintaining two
|
|
10
|
+
* independently-editable "twin" files.
|
|
85
11
|
*/
|
|
86
|
-
export
|
|
87
|
-
const { retryDelayMs = 300, sleep = defaultSleep, warn = console.warn, label = 'wasm' } = options;
|
|
88
|
-
try {
|
|
89
|
-
await init();
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
94
|
-
if (!isTransientWasmLoadError(msg))
|
|
95
|
-
throw err;
|
|
96
|
-
warn(`[${label}] WASM engine load failed (${msg}); retrying once`);
|
|
97
|
-
await sleep(retryDelayMs);
|
|
98
|
-
try {
|
|
99
|
-
await init();
|
|
100
|
-
}
|
|
101
|
-
catch (retryErr) {
|
|
102
|
-
throw attributeEngineLoadFailure(retryErr, label);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
12
|
+
export { initWasmWithRetry, isTransientWasmLoadError, } from '@ifc-lite/wasm-lifecycle';
|
|
106
13
|
//# sourceMappingURL=wasm-init-retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-init-retry.js","sourceRoot":"","sources":["../src/wasm-init-retry.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"wasm-init-retry.js","sourceRoot":"","sources":["../src/wasm-init-retry.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AACH,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GAEzB,MAAM,0BAA0B,CAAC"}
|
|
@@ -1,67 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* (#
|
|
2
|
+
* Re-export of the shared worker-to-main-thread wasm panic-location forwarder
|
|
3
|
+
* (issue #4247).
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* (`apps/viewer/src/lib/analytics-scrub.ts`'s `attachWasmPanicLocation`), but
|
|
10
|
-
* a worker-realm trap leaves that stash stranded in the worker's global,
|
|
11
|
-
* which the main thread can never see across the realm boundary.
|
|
12
|
-
*
|
|
13
|
-
* `takeWasmPanicStash` reads + consumes the stash worker-side so it can ride
|
|
14
|
-
* the worker's own `{type:'error'}` message; `restashWasmPanicLocation`
|
|
15
|
-
* re-plants it on the main thread's global so the EXISTING #2527 gate (same
|
|
16
|
-
* key, same TTL, same consume-once semantics) picks it up unmodified.
|
|
17
|
-
*
|
|
18
|
-
* Location only, never the panic's message — the message can embed
|
|
19
|
-
* model-derived text (see `utils.rs`'s privacy contract); the location alone
|
|
20
|
-
* travels on the error message and through this module.
|
|
21
|
-
*
|
|
22
|
-
* NOTE: this file is intentionally byte-identical to
|
|
23
|
-
* `packages/geometry/src/wasm-panic-forward.ts` — both `@ifc-lite/geometry`
|
|
24
|
-
* and `@ifc-lite/parser` need the exact same realm-forwarding contract, and
|
|
25
|
-
* neither package depends on the other (nor is `@ifc-lite/wasm`, the one
|
|
26
|
-
* package both DO depend on, a safe home: it ships only the wasm-pack build
|
|
27
|
-
* output, with no TypeScript build step of its own, and `test`/`typecheck`
|
|
28
|
-
* for either consumer already runs its build via turbo's `^build` — adding a
|
|
29
|
-
* hand-written TS module there would make every geometry/parser test run
|
|
30
|
-
* gate on a full Rust→wasm rebuild). Keep any change to one copy in lockstep
|
|
31
|
-
* with the other; `wasm-panic-forward.test.ts` is duplicated the same way.
|
|
32
|
-
*/
|
|
33
|
-
/** Kept in lockstep with `PANIC_STASH_KEY` in `rust/wasm-bindings/src/utils.rs`,
|
|
34
|
-
* `WASM_PANIC_STASH_KEY` in `apps/viewer/src/lib/analytics-scrub.ts`, and this
|
|
35
|
-
* module's twin at `packages/geometry/src/wasm-panic-forward.ts`. */
|
|
36
|
-
export declare const WASM_PANIC_STASH_KEY = "__ifclite_wasm_panic";
|
|
37
|
-
export interface WasmPanicStash {
|
|
38
|
-
location: string;
|
|
39
|
-
at: number;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Worker-side: read and CONSUME this realm's panic stash so it can be
|
|
43
|
-
* forwarded on the worker's own error message. Consume-once regardless of
|
|
44
|
-
* shape validity — an unconsumed malformed stash must not linger to
|
|
45
|
-
* mislabel a later trap, mirroring the main-thread gate's own rule.
|
|
46
|
-
*/
|
|
47
|
-
export declare function takeWasmPanicStash(realm: object): WasmPanicStash | undefined;
|
|
48
|
-
/**
|
|
49
|
-
* Main-side: re-plant a worker-forwarded stash on this realm's global so the
|
|
50
|
-
* existing #2527 `attachWasmPanicLocation` gate consumes it unmodified.
|
|
51
|
-
*
|
|
52
|
-
* Gated on `errorMessage` looking like a wasm trap: the worker forwards
|
|
53
|
-
* `wasmPanicLocation`/`wasmPanicAt` on ANY `{type:'error'}` message (a stale
|
|
54
|
-
* stash from an earlier suppressed panic can ride out on an ordinary,
|
|
55
|
-
* non-trap worker error), and re-planting unconditionally would let that
|
|
56
|
-
* stale location sit on `globalThis` until an unrelated trap-shaped
|
|
57
|
-
* exception consumed it — mislabeling that trap. Only a message that itself
|
|
58
|
-
* looks like a wasm trap is allowed to re-plant.
|
|
59
|
-
*
|
|
60
|
-
* Never clobbers an existing, unconsumed stash — a genuine main-thread trap
|
|
61
|
-
* that hasn't been captured yet must win over a worker trap that merely
|
|
62
|
-
* arrived first (the older-looking stash, if stale, is simply dropped later
|
|
63
|
-
* by the TTL check at attach time; this function never overwrites either
|
|
64
|
-
* way).
|
|
5
|
+
* The real implementation lives in `@ifc-lite/wasm-lifecycle` so
|
|
6
|
+
* `@ifc-lite/geometry` and `@ifc-lite/parser` share exactly one copy of the
|
|
7
|
+
* #2527 realm-forwarding contract instead of maintaining two
|
|
8
|
+
* independently-editable "twin" files.
|
|
65
9
|
*/
|
|
66
|
-
export
|
|
10
|
+
export { WASM_PANIC_STASH_KEY, takeWasmPanicStash, restashWasmPanicLocation, type WasmPanicStash, } from '@ifc-lite/wasm-lifecycle';
|
|
67
11
|
//# sourceMappingURL=wasm-panic-forward.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-panic-forward.d.ts","sourceRoot":"","sources":["../src/wasm-panic-forward.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"wasm-panic-forward.d.ts","sourceRoot":"","sources":["../src/wasm-panic-forward.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,cAAc,GACpB,MAAM,0BAA0B,CAAC"}
|
|
@@ -2,106 +2,13 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* (#
|
|
5
|
+
* Re-export of the shared worker-to-main-thread wasm panic-location forwarder
|
|
6
|
+
* (issue #4247).
|
|
7
7
|
*
|
|
8
|
-
* The
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* (`apps/viewer/src/lib/analytics-scrub.ts`'s `attachWasmPanicLocation`), but
|
|
13
|
-
* a worker-realm trap leaves that stash stranded in the worker's global,
|
|
14
|
-
* which the main thread can never see across the realm boundary.
|
|
15
|
-
*
|
|
16
|
-
* `takeWasmPanicStash` reads + consumes the stash worker-side so it can ride
|
|
17
|
-
* the worker's own `{type:'error'}` message; `restashWasmPanicLocation`
|
|
18
|
-
* re-plants it on the main thread's global so the EXISTING #2527 gate (same
|
|
19
|
-
* key, same TTL, same consume-once semantics) picks it up unmodified.
|
|
20
|
-
*
|
|
21
|
-
* Location only, never the panic's message — the message can embed
|
|
22
|
-
* model-derived text (see `utils.rs`'s privacy contract); the location alone
|
|
23
|
-
* travels on the error message and through this module.
|
|
24
|
-
*
|
|
25
|
-
* NOTE: this file is intentionally byte-identical to
|
|
26
|
-
* `packages/geometry/src/wasm-panic-forward.ts` — both `@ifc-lite/geometry`
|
|
27
|
-
* and `@ifc-lite/parser` need the exact same realm-forwarding contract, and
|
|
28
|
-
* neither package depends on the other (nor is `@ifc-lite/wasm`, the one
|
|
29
|
-
* package both DO depend on, a safe home: it ships only the wasm-pack build
|
|
30
|
-
* output, with no TypeScript build step of its own, and `test`/`typecheck`
|
|
31
|
-
* for either consumer already runs its build via turbo's `^build` — adding a
|
|
32
|
-
* hand-written TS module there would make every geometry/parser test run
|
|
33
|
-
* gate on a full Rust→wasm rebuild). Keep any change to one copy in lockstep
|
|
34
|
-
* with the other; `wasm-panic-forward.test.ts` is duplicated the same way.
|
|
35
|
-
*/
|
|
36
|
-
/** Kept in lockstep with `PANIC_STASH_KEY` in `rust/wasm-bindings/src/utils.rs`,
|
|
37
|
-
* `WASM_PANIC_STASH_KEY` in `apps/viewer/src/lib/analytics-scrub.ts`, and this
|
|
38
|
-
* module's twin at `packages/geometry/src/wasm-panic-forward.ts`. */
|
|
39
|
-
export const WASM_PANIC_STASH_KEY = '__ifclite_wasm_panic';
|
|
40
|
-
/**
|
|
41
|
-
* Trap-shape text match, kept in lockstep with `WASM_TRAP_TEXT` in
|
|
42
|
-
* `apps/viewer/src/lib/analytics-scrub.ts` and this module's twin at
|
|
43
|
-
* `packages/geometry/src/wasm-panic-forward.ts`. Deliberately excludes bare
|
|
44
|
-
* "unreachable" inside network-failure phrasing ("network is unreachable",
|
|
45
|
-
* "host unreachable") — those are not wasm traps.
|
|
46
|
-
*/
|
|
47
|
-
const WASM_TRAP_TEXT = /(?<!network is |host |destination |address )\bunreachable\b|\bRuntimeError\b|memory access out of bounds|index out of bounds|indirect call to null|integer (?:overflow|divide by zero)|call stack exhausted/i;
|
|
48
|
-
function looksLikeWasmTrap(message) {
|
|
49
|
-
return WASM_TRAP_TEXT.test(message);
|
|
50
|
-
}
|
|
51
|
-
/** Validate + narrow an unknown stash value read off a realm global. */
|
|
52
|
-
function readStashShape(value) {
|
|
53
|
-
if (typeof value !== 'object' || value === null)
|
|
54
|
-
return undefined;
|
|
55
|
-
const { location, at } = value;
|
|
56
|
-
if (typeof location !== 'string' || location === '')
|
|
57
|
-
return undefined;
|
|
58
|
-
// Reject non-finite (`NaN`/`Infinity`) and future timestamps — both pass
|
|
59
|
-
// the analytics TTL gate's `Date.now() - at <= TTL` check trivially
|
|
60
|
-
// (`Infinity` makes the delta `-Infinity`; a future `at` makes it
|
|
61
|
-
// negative), which would let a malformed stash label a later trap.
|
|
62
|
-
if (typeof at !== 'number' || !Number.isFinite(at) || at > Date.now())
|
|
63
|
-
return undefined;
|
|
64
|
-
return { location, at };
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Worker-side: read and CONSUME this realm's panic stash so it can be
|
|
68
|
-
* forwarded on the worker's own error message. Consume-once regardless of
|
|
69
|
-
* shape validity — an unconsumed malformed stash must not linger to
|
|
70
|
-
* mislabel a later trap, mirroring the main-thread gate's own rule.
|
|
71
|
-
*/
|
|
72
|
-
export function takeWasmPanicStash(realm) {
|
|
73
|
-
const g = realm;
|
|
74
|
-
const raw = g[WASM_PANIC_STASH_KEY];
|
|
75
|
-
delete g[WASM_PANIC_STASH_KEY];
|
|
76
|
-
return readStashShape(raw);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Main-side: re-plant a worker-forwarded stash on this realm's global so the
|
|
80
|
-
* existing #2527 `attachWasmPanicLocation` gate consumes it unmodified.
|
|
81
|
-
*
|
|
82
|
-
* Gated on `errorMessage` looking like a wasm trap: the worker forwards
|
|
83
|
-
* `wasmPanicLocation`/`wasmPanicAt` on ANY `{type:'error'}` message (a stale
|
|
84
|
-
* stash from an earlier suppressed panic can ride out on an ordinary,
|
|
85
|
-
* non-trap worker error), and re-planting unconditionally would let that
|
|
86
|
-
* stale location sit on `globalThis` until an unrelated trap-shaped
|
|
87
|
-
* exception consumed it — mislabeling that trap. Only a message that itself
|
|
88
|
-
* looks like a wasm trap is allowed to re-plant.
|
|
89
|
-
*
|
|
90
|
-
* Never clobbers an existing, unconsumed stash — a genuine main-thread trap
|
|
91
|
-
* that hasn't been captured yet must win over a worker trap that merely
|
|
92
|
-
* arrived first (the older-looking stash, if stale, is simply dropped later
|
|
93
|
-
* by the TTL check at attach time; this function never overwrites either
|
|
94
|
-
* way).
|
|
8
|
+
* The real implementation lives in `@ifc-lite/wasm-lifecycle` so
|
|
9
|
+
* `@ifc-lite/geometry` and `@ifc-lite/parser` share exactly one copy of the
|
|
10
|
+
* #2527 realm-forwarding contract instead of maintaining two
|
|
11
|
+
* independently-editable "twin" files.
|
|
95
12
|
*/
|
|
96
|
-
export
|
|
97
|
-
const stash = readStashShape({ location, at });
|
|
98
|
-
if (!stash)
|
|
99
|
-
return;
|
|
100
|
-
if (!looksLikeWasmTrap(errorMessage))
|
|
101
|
-
return;
|
|
102
|
-
const g = realm;
|
|
103
|
-
if (g[WASM_PANIC_STASH_KEY] !== undefined)
|
|
104
|
-
return;
|
|
105
|
-
g[WASM_PANIC_STASH_KEY] = stash;
|
|
106
|
-
}
|
|
13
|
+
export { WASM_PANIC_STASH_KEY, takeWasmPanicStash, restashWasmPanicLocation, } from '@ifc-lite/wasm-lifecycle';
|
|
107
14
|
//# sourceMappingURL=wasm-panic-forward.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-panic-forward.js","sourceRoot":"","sources":["../src/wasm-panic-forward.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"wasm-panic-forward.js","sourceRoot":"","sources":["../src/wasm-panic-forward.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;GAQG;AACH,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GAEzB,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IfcDataStore } from './columnar-parser.js';
|
|
2
|
+
import { type CompactEntityIndexColumns } from './compact-entity-index-transport.js';
|
|
3
|
+
import { type DataStoreTransport } from './data-store-transport.js';
|
|
4
|
+
import type { IfcSourceBytes } from './source-bytes.js';
|
|
5
|
+
interface PackedIndex {
|
|
6
|
+
format: 'packed-index-v1';
|
|
7
|
+
byId: CompactEntityIndexColumns;
|
|
8
|
+
names: string[];
|
|
9
|
+
offsets: Uint32Array;
|
|
10
|
+
ids: Uint32Array | Float64Array;
|
|
11
|
+
}
|
|
12
|
+
interface IndexReference {
|
|
13
|
+
format: 'published-index-v1';
|
|
14
|
+
}
|
|
15
|
+
export type WorkerStorePayload = Omit<DataStoreTransport, 'entityIndex'> & {
|
|
16
|
+
entityIndex: DataStoreTransport['entityIndex'] | PackedIndex | IndexReference;
|
|
17
|
+
};
|
|
18
|
+
/** #3985: canonical parser primary columns/byType are immutable after the
|
|
19
|
+
* spatial callback. Deferred atoms get a separate final index. This publisher
|
|
20
|
+
* must not be used by a producer that edits published numeric columns in place.
|
|
21
|
+
* Public receiver arrays and LRU entries are never the retained wire seed.
|
|
22
|
+
*/
|
|
23
|
+
export declare class WorkerIndexPublisher {
|
|
24
|
+
private readonly enabled;
|
|
25
|
+
private published?;
|
|
26
|
+
constructor(enabled: boolean);
|
|
27
|
+
serialize(store: IfcDataStore, final: boolean): {
|
|
28
|
+
payload: WorkerStorePayload;
|
|
29
|
+
transfers: Transferable[];
|
|
30
|
+
transportBytes: number;
|
|
31
|
+
};
|
|
32
|
+
/** Call only after the partial postMessage succeeds. */
|
|
33
|
+
publishedPartial(store: IfcDataStore): void;
|
|
34
|
+
}
|
|
35
|
+
/** One instance per parse request, never a federation/global cache. */
|
|
36
|
+
export declare class WorkerIndexReceiver {
|
|
37
|
+
private seed?;
|
|
38
|
+
capturePartial(payload: WorkerStorePayload): void;
|
|
39
|
+
hydrate(payload: WorkerStorePayload, source: IfcSourceBytes): IfcDataStore;
|
|
40
|
+
clear(): void;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=worker-index-publication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-index-publication.d.ts","sourceRoot":"","sources":["../src/worker-index-publication.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAA+B,KAAK,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAClH,OAAO,EAAiD,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACnH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,UAAU,WAAW;IACnB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,EAAE,yBAAyB,CAAC;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;IACrB,GAAG,EAAE,WAAW,GAAG,YAAY,CAAC;CACjC;AACD,UAAU,cAAc;IAAG,MAAM,EAAE,oBAAoB,CAAA;CAAE;AACzD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,GAAG;IACzE,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,GAAG,WAAW,GAAG,cAAc,CAAC;CAC/E,CAAC;AA2BF;;;;GAIG;AACH,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,OAAO,CAAC,SAAS,CAAC,CAIhB;gBAE2B,OAAO,EAAE,OAAO;IAE7C,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG;QAAE,OAAO,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,YAAY,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;IAwClI,wDAAwD;IACxD,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;CAQ5C;AAED,uEAAuE;AACvE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAc;IAE3B,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAMjD,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,GAAG,YAAY;IAsB1E,KAAK,IAAI,IAAI;CACd"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { CompactEntityIndex } from './compact-entity-index.js';
|
|
5
|
+
import { compactEntityIndexToColumns } from './compact-entity-index-transport.js';
|
|
6
|
+
import { fromTransport, toTransport, transportByteSize } from './data-store-transport.js';
|
|
7
|
+
function packIndex(store, byId) {
|
|
8
|
+
const entries = [...store.entityIndex.byType];
|
|
9
|
+
let count = 0;
|
|
10
|
+
let u32 = true;
|
|
11
|
+
for (const [, values] of entries) {
|
|
12
|
+
count += values.length;
|
|
13
|
+
for (const id of values) {
|
|
14
|
+
if (!Number.isInteger(id) || id < 0 || id > 0xffffffff || Object.is(id, -0))
|
|
15
|
+
u32 = false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (count > 0xffffffff)
|
|
19
|
+
throw new Error('Packed byType index exceeds u32 offset capacity');
|
|
20
|
+
// Arbitrary number[] producers retain their numbers, including NaN/-0 and
|
|
21
|
+
// IDs above u32. Canonical parser IDs use the compact representation.
|
|
22
|
+
const ids = u32 ? new Uint32Array(count) : new Float64Array(count);
|
|
23
|
+
const offsets = new Uint32Array(entries.length + 1);
|
|
24
|
+
let offset = 0;
|
|
25
|
+
for (let i = 0; i < entries.length; i++) {
|
|
26
|
+
offsets[i] = offset;
|
|
27
|
+
ids.set(entries[i][1], offset);
|
|
28
|
+
offset += entries[i][1].length;
|
|
29
|
+
}
|
|
30
|
+
offsets[entries.length] = offset;
|
|
31
|
+
return { format: 'packed-index-v1', byId, names: entries.map(([name]) => name), offsets, ids };
|
|
32
|
+
}
|
|
33
|
+
/** #3985: canonical parser primary columns/byType are immutable after the
|
|
34
|
+
* spatial callback. Deferred atoms get a separate final index. This publisher
|
|
35
|
+
* must not be used by a producer that edits published numeric columns in place.
|
|
36
|
+
* Public receiver arrays and LRU entries are never the retained wire seed.
|
|
37
|
+
*/
|
|
38
|
+
export class WorkerIndexPublisher {
|
|
39
|
+
enabled;
|
|
40
|
+
published;
|
|
41
|
+
constructor(enabled) {
|
|
42
|
+
this.enabled = enabled;
|
|
43
|
+
}
|
|
44
|
+
serialize(store, final) {
|
|
45
|
+
// TODO(remove-by: all supported parser-worker clients negotiate packed-index-v1, parser maintainers), #3985.
|
|
46
|
+
if (!this.enabled) {
|
|
47
|
+
const envelope = toTransport(store);
|
|
48
|
+
return { ...envelope, transfers: final ? envelope.transfers : [], transportBytes: transportByteSize(envelope.payload) };
|
|
49
|
+
}
|
|
50
|
+
if (!(store.entityIndex.byId instanceof CompactEntityIndex)) {
|
|
51
|
+
throw new Error('Worker publication requires CompactEntityIndex');
|
|
52
|
+
}
|
|
53
|
+
const byId = compactEntityIndexToColumns(store.entityIndex.byId);
|
|
54
|
+
const previous = this.published;
|
|
55
|
+
const entries = [...store.entityIndex.byType];
|
|
56
|
+
const reference = final && previous && previous.index === store.entityIndex
|
|
57
|
+
&& previous.columns.expressIds === byId.expressIds
|
|
58
|
+
&& previous.columns.byteOffsets === byId.byteOffsets
|
|
59
|
+
&& previous.columns.byteLengths === byId.byteLengths
|
|
60
|
+
&& previous.columns.typeIndices === byId.typeIndices
|
|
61
|
+
&& previous.columns.typeStrings.length === byId.typeStrings.length
|
|
62
|
+
&& previous.columns.typeStrings.every((name, i) => name === byId.typeStrings[i])
|
|
63
|
+
&& previous.entries.length === store.entityIndex.byType.size
|
|
64
|
+
&& previous.entries.every(([name, values, length], i) => entries[i][0] === name && entries[i][1] === values && values.length === length);
|
|
65
|
+
const envelope = toTransport(store, { byId, byType: [] });
|
|
66
|
+
const entityIndex = reference
|
|
67
|
+
? { format: 'published-index-v1' } : packIndex(store, byId);
|
|
68
|
+
const primaryBuffers = new Set([
|
|
69
|
+
byId.expressIds.buffer, byId.byteOffsets.buffer, byId.byteLengths.buffer, byId.typeIndices.buffer,
|
|
70
|
+
]);
|
|
71
|
+
// #3985: even a referenced index keeps its original ABs in this final
|
|
72
|
+
// transfer list. Unreachable transfers detach/dispose worker ownership at
|
|
73
|
+
// successful publication, without adding another main-thread index.
|
|
74
|
+
// This does not promise when the browser reclaims physical backing.
|
|
75
|
+
const transfers = final ? envelope.transfers : [];
|
|
76
|
+
if (entityIndex.format === 'packed-index-v1')
|
|
77
|
+
transfers.push(entityIndex.ids.buffer, entityIndex.offsets.buffer);
|
|
78
|
+
// Count reachable payload bytes, excluding detached disposal-only backing.
|
|
79
|
+
const transportBytes = transportByteSize(envelope.payload)
|
|
80
|
+
- (reference ? [...primaryBuffers].reduce((sum, buffer) => sum + (buffer instanceof ArrayBuffer ? buffer.byteLength : 0), 0) : 0)
|
|
81
|
+
+ (entityIndex.format === 'packed-index-v1' ? entityIndex.ids.byteLength + entityIndex.offsets.byteLength : 0);
|
|
82
|
+
return { payload: { ...envelope.payload, entityIndex }, transfers, transportBytes };
|
|
83
|
+
}
|
|
84
|
+
/** Call only after the partial postMessage succeeds. */
|
|
85
|
+
publishedPartial(store) {
|
|
86
|
+
if (!this.enabled || !(store.entityIndex.byId instanceof CompactEntityIndex))
|
|
87
|
+
return;
|
|
88
|
+
this.published = {
|
|
89
|
+
index: store.entityIndex,
|
|
90
|
+
columns: compactEntityIndexToColumns(store.entityIndex.byId),
|
|
91
|
+
entries: [...store.entityIndex.byType].map(([name, values]) => [name, values, values.length]),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** One instance per parse request, never a federation/global cache. */
|
|
96
|
+
export class WorkerIndexReceiver {
|
|
97
|
+
seed;
|
|
98
|
+
capturePartial(payload) {
|
|
99
|
+
if ('format' in payload.entityIndex && payload.entityIndex.format === 'packed-index-v1') {
|
|
100
|
+
this.seed = payload.entityIndex;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
hydrate(payload, source) {
|
|
104
|
+
const index = payload.entityIndex;
|
|
105
|
+
if (!('format' in index))
|
|
106
|
+
return fromTransport({ ...payload, entityIndex: index }, source);
|
|
107
|
+
const packed = index.format === 'published-index-v1' ? this.seed : index;
|
|
108
|
+
if (!packed)
|
|
109
|
+
throw new Error('Final parser index references a missing partial publication');
|
|
110
|
+
if (packed.offsets.length !== packed.names.length + 1 || packed.offsets[0] !== 0
|
|
111
|
+
|| packed.offsets[packed.names.length] !== packed.ids.length) {
|
|
112
|
+
throw new Error('Invalid packed parser index offsets');
|
|
113
|
+
}
|
|
114
|
+
const byType = new Map();
|
|
115
|
+
for (let i = 0; i < packed.names.length; i++) {
|
|
116
|
+
const start = packed.offsets[i], end = packed.offsets[i + 1];
|
|
117
|
+
if (end < start || end > packed.ids.length || byType.has(packed.names[i])) {
|
|
118
|
+
throw new Error('Invalid packed parser index range or duplicate type');
|
|
119
|
+
}
|
|
120
|
+
const values = new Array(end - start);
|
|
121
|
+
for (let row = start; row < end; row++)
|
|
122
|
+
values[row - start] = packed.ids[row];
|
|
123
|
+
byType.set(packed.names[i], values);
|
|
124
|
+
}
|
|
125
|
+
return fromTransport({ ...payload, entityIndex: { byId: packed.byId, byType: [] } }, source, byType);
|
|
126
|
+
}
|
|
127
|
+
clear() { this.seed = undefined; }
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=worker-index-publication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-index-publication.js","sourceRoot":"","sources":["../src/worker-index-publication.ts"],"names":[],"mappings":"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"}
|
package/dist/worker-parser.d.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* 2. Caller constructs a `WorkerParser` and calls `parseColumnar(sab, …)`.
|
|
9
9
|
* 3. The worker emits `progress`, `diagnostic`, optional `partial-store`,
|
|
10
10
|
* then `complete` (or `error`). This wrapper resolves the returned
|
|
11
|
-
* Promise
|
|
11
|
+
* Promise after receiving `complete` and hydrating the result. The
|
|
12
|
+
* completed worker is terminated before receiver reconstruction.
|
|
12
13
|
*
|
|
13
14
|
* On `partial-store` the wrapper invokes `options.onSpatialReady` so the
|
|
14
15
|
* viewer can render the spatial-hierarchy panel before the full parse
|
|
@@ -16,8 +17,10 @@
|
|
|
16
17
|
*/
|
|
17
18
|
import type { IfcDataStore } from './columnar-parser.js';
|
|
18
19
|
import type { ParseOptions } from './index.js';
|
|
19
|
-
import {
|
|
20
|
+
import type { ParserMemorySnapshot } from './data-store-transport.js';
|
|
20
21
|
export interface WorkerParserOptions extends ParseOptions {
|
|
22
|
+
/** Fresh per-request 16-byte prepass fingerprint cell; never awaited. */
|
|
23
|
+
sourceFingerprint?: SharedArrayBuffer;
|
|
21
24
|
/** Override the worker URL. Default: bundler-resolved `parser.worker.ts`. */
|
|
22
25
|
workerUrl?: URL | string;
|
|
23
26
|
/** Optional callback receiving the per-parse memory snapshot at completion. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-parser.d.ts","sourceRoot":"","sources":["../src/worker-parser.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"worker-parser.d.ts","sourceRoot":"","sources":["../src/worker-parser.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAQtE,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC;IACzB,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC5D;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAMT;IAEhB;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;gBAOjB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,GAAG,GAAG,MAAM,CAAA;KAAO;IAQtD;;;;;;OAMG;IACH,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,YAAY,CAAC;IA0KlG;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CACZ,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,MAAM,EACzB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,IAAI;IAmBP,gEAAgE;IAChE,SAAS,IAAI,IAAI;CAUlB"}
|
package/dist/worker-parser.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
-
import {
|
|
4
|
+
import { WorkerIndexReceiver } from './worker-index-publication.js';
|
|
5
5
|
import { contiguousSourceBytes } from './source-bytes.js';
|
|
6
6
|
import { restashWasmPanicLocation } from './wasm-panic-forward.js';
|
|
7
7
|
export class WorkerParser {
|
|
@@ -71,13 +71,15 @@ export class WorkerParser {
|
|
|
71
71
|
// memoising on the shared Uint8Array; sharing the accessor is the same
|
|
72
72
|
// guarantee without the side table.
|
|
73
73
|
let sourceBytes;
|
|
74
|
+
const indexReceiver = new WorkerIndexReceiver();
|
|
74
75
|
const hydrate = (payload) => {
|
|
75
76
|
// #3983: the worker hashes the source before the first UI publication.
|
|
76
77
|
// Retain one accessor across partial/full stores and compression swaps.
|
|
77
78
|
sourceBytes ??= contiguousSourceBytes(new Uint8Array(source), payload.sourceContentKey ?? undefined);
|
|
78
|
-
return
|
|
79
|
+
return indexReceiver.hydrate(payload, sourceBytes);
|
|
79
80
|
};
|
|
80
81
|
const settle = (cleanup) => {
|
|
82
|
+
indexReceiver.clear();
|
|
81
83
|
worker.onmessage = null;
|
|
82
84
|
worker.onerror = null;
|
|
83
85
|
worker.onmessageerror = null;
|
|
@@ -95,9 +97,10 @@ export class WorkerParser {
|
|
|
95
97
|
options.onDiagnostic?.(msg.message);
|
|
96
98
|
return;
|
|
97
99
|
case 'partial-store': {
|
|
98
|
-
if (!options.onSpatialReady)
|
|
99
|
-
return;
|
|
100
100
|
try {
|
|
101
|
+
indexReceiver.capturePartial(msg.payload);
|
|
102
|
+
if (!options.onSpatialReady)
|
|
103
|
+
return;
|
|
101
104
|
const partial = hydrate(msg.payload);
|
|
102
105
|
options.onSpatialReady(partial);
|
|
103
106
|
}
|
|
@@ -110,18 +113,21 @@ export class WorkerParser {
|
|
|
110
113
|
}
|
|
111
114
|
case 'complete': {
|
|
112
115
|
try {
|
|
116
|
+
// #3985: the received message owns its transferred columns. Stop
|
|
117
|
+
// the completed sender before allocating receiver collections;
|
|
118
|
+
// retain indexReceiver's partial seed until hydration completes.
|
|
119
|
+
worker.terminate();
|
|
120
|
+
if (this.worker === worker)
|
|
121
|
+
this.worker = null;
|
|
113
122
|
const dataStore = hydrate(msg.payload);
|
|
114
123
|
options.onMemorySnapshot?.(msg.memory);
|
|
115
|
-
settle(() => {
|
|
116
|
-
worker.terminate();
|
|
117
|
-
this.worker = null;
|
|
118
|
-
});
|
|
124
|
+
settle(() => { });
|
|
119
125
|
resolve(dataStore);
|
|
120
126
|
}
|
|
121
127
|
catch (err) {
|
|
122
128
|
settle(() => {
|
|
123
|
-
worker
|
|
124
|
-
|
|
129
|
+
if (this.worker === worker)
|
|
130
|
+
this.worker = null;
|
|
125
131
|
});
|
|
126
132
|
reject(new Error(`complete hydrate failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
127
133
|
}
|
|
@@ -178,6 +184,8 @@ export class WorkerParser {
|
|
|
178
184
|
}
|
|
179
185
|
const input = {
|
|
180
186
|
type: 'parse',
|
|
187
|
+
sourceFingerprint: options.sourceFingerprint,
|
|
188
|
+
indexTransport: 'packed-index-v1',
|
|
181
189
|
id,
|
|
182
190
|
source,
|
|
183
191
|
yieldIntervalMs: options.yieldIntervalMs,
|
|
@@ -240,6 +248,10 @@ export class WorkerParser {
|
|
|
240
248
|
/** Terminate the worker if running. Safe to call repeatedly. */
|
|
241
249
|
terminate() {
|
|
242
250
|
if (this.worker) {
|
|
251
|
+
// Drop the per-request hydration closure, including its packed index seed.
|
|
252
|
+
this.worker.onmessage = null;
|
|
253
|
+
this.worker.onerror = null;
|
|
254
|
+
this.worker.onmessageerror = null;
|
|
243
255
|
this.worker.terminate();
|
|
244
256
|
this.worker = null;
|
|
245
257
|
}
|