33 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44
55import { ownedWasmBuffer } from './wasm-owned-buffer.js' ;
6+ import { publishPrepassFingerprint , runPrepassWithFingerprint } from './prepass-source-fingerprint.js' ;
67import { canReuseWorkerSource , type SourcePrepassApi , type FinalizeStyleArgs } from './worker-prepass-source.js' ;
78import init , { initSync , IfcAPI } from '@ifc-lite/wasm' ;
89import { initWasmWithRetry } from './wasm-init-retry.js' ;
@@ -174,6 +175,7 @@ export interface GeometryWorkerScanShardMessage {
174175
175176export interface GeometryWorkerPrePassMessage {
176177 type : 'prepass-streaming' ;
178+ sourceFingerprint ?: SharedArrayBuffer ;
177179 sharedBuffer : SharedArrayBuffer ;
178180 /** Jobs per chunk (defaults to 50_000). */
179181 chunkSize ?: number ;
@@ -319,6 +321,7 @@ export interface GeometryWorkerStylesShardResultMessage {
319321 */
320322export interface GeometryWorkerPrePassShardedMessage {
321323 type : 'prepass-streaming-sharded' ;
324+ sourceFingerprint ?: SharedArrayBuffer ;
322325 sharedBuffer : SharedArrayBuffer ;
323326 chunkSize ?: number ;
324327 disabledTypes ?: string [ ] ;
@@ -1384,26 +1387,20 @@ async function handleMessage(e: MessageEvent<GeometryWorkerRequest>): Promise<vo
13841387 const ifcApi = await ensureInit ( ) ;
13851388 ( self as unknown as Worker ) . postMessage ( { type : 'prepass-progress' , phase : 'parsing' } ) ;
13861389 const { sharedBuffer, indexIds, indexStarts, indexLengths, indexClasses } = e . data ;
1390+ const sourceFingerprint = e . data . sourceFingerprint ;
13871391 const chunkSize = e . data . chunkSize ?? 50_000 ;
13881392 const disabledTypes = e . data . disabledTypes ?? undefined ;
13891393 const skipTypeGeometry = e . data . skipTypeGeometry === true ;
13901394 const onEvent = ( event : unknown ) => {
1395+ publishPrepassFingerprint ( sourceFingerprint , sharedBuffer . byteLength , event ) ;
13911396 ( self as unknown as Worker ) . postMessage ( { type : 'prepass-stream' , event } ) ;
13921397 } ;
13931398 const run = (
13941399 bytes : Uint8Array ,
13951400 ids : Uint32Array , starts : Uint32Array , lengths : Uint32Array , classes : Uint8Array ,
13961401 ) =>
1397- ( ifcApi as unknown as {
1398- buildPrePassStreamingSharded : (
1399- data : Uint8Array , onEvent : ( e : unknown ) => void , chunkSize : number ,
1400- disabledTypes : string [ ] | undefined , skipTypeGeometry : boolean ,
1401- ids : Uint32Array , starts : Uint32Array , lengths : Uint32Array , classes : Uint8Array ,
1402- ) => unknown ;
1403- } ) . buildPrePassStreamingSharded (
1404- bytes , onEvent , chunkSize , disabledTypes , skipTypeGeometry ,
1405- ids , starts , lengths , classes ,
1406- ) ;
1402+ runPrepassWithFingerprint ( ifcApi , [ bytes , onEvent , chunkSize , disabledTypes , skipTypeGeometry ] ,
1403+ sourceFingerprint , [ ids , starts , lengths , classes ] ) ;
14071404 try {
14081405 run ( viewSharedBytes ( sharedBuffer ) , indexIds , indexStarts , indexLengths , indexClasses ) ;
14091406 } catch ( err ) {
@@ -1469,6 +1466,7 @@ async function handleMessage(e: MessageEvent<GeometryWorkerRequest>): Promise<vo
14691466 // before the first chunk lands.
14701467 ( self as unknown as Worker ) . postMessage ( { type : 'prepass-progress' , phase : 'parsing' } ) ;
14711468 const sharedBuffer = e . data . sharedBuffer ;
1469+ const sourceFingerprint = e . data . sourceFingerprint ;
14721470 const chunkSize = e . data . chunkSize ?? 50_000 ;
14731471 // #1097 load-time visibility filter (skip disabled types at job gen).
14741472 const disabledTypes = e . data . disabledTypes ?? undefined ;
@@ -1479,10 +1477,11 @@ async function handleMessage(e: MessageEvent<GeometryWorkerRequest>): Promise<vo
14791477 // zero-copy view first, fall back to a materialised copy only if
14801478 // wasm-bindgen rejects the view.
14811479 const onEvent = ( event : unknown ) => {
1480+ publishPrepassFingerprint ( sourceFingerprint , sharedBuffer . byteLength , event ) ;
14821481 ( self as unknown as Worker ) . postMessage ( { type : 'prepass-stream' , event } ) ;
14831482 } ;
14841483 const runPrepass = ( bytes : Uint8Array ) =>
1485- ifcApi . buildPrePassStreaming ( bytes , onEvent , chunkSize , disabledTypes , skipTypeGeometry ) ;
1484+ runPrepassWithFingerprint ( ifcApi , [ bytes , onEvent , chunkSize , disabledTypes , skipTypeGeometry ] , sourceFingerprint ) ;
14861485 try {
14871486 // Zero-copy SAB view first; wasm-bindgen copies it into linear memory.
14881487 runPrepass ( viewSharedBytes ( sharedBuffer ) ) ;
@@ -1593,7 +1592,8 @@ async function handleMessage(e: MessageEvent<GeometryWorkerRequest>): Promise<vo
15931592 // size from a previous dense model).
15941593 batchSizing = resolveBatchSizing ( e . data . batchSizing ) ;
15951594 adaptiveBatchJobs = batchSizing . maxJobs ;
1596- // Reuse this load's shard source; reset non-sharded/reused loads before geometry (#3989).
1595+ // Shard scanning has already installed this load's source (#3989).
1596+ // Non-sharded/reused loads still reset before their first geometry batch.
15971597 if ( ! sourcePreparedForStream || ! canReuseWorkerSource ( installedSourceSessionId , e . data . sourceSessionId ) ) {
15981598 sourceBytesApplied = false ;
15991599 cachedSourceBytes = null ;
0 commit comments