@@ -14,68 +14,19 @@ if (typeof sourceRoot !== 'string')
1414 throw new Error ( 'missing parser source root' ) ;
1515
1616const parser = await import ( pathToFileURL ( `${ sourceRoot } /lib/parser.js` ) . href ) ;
17- // The candidate builds a closer array with `matchBlocks`; the baseline builds a
18- // `BlockIndex` with `indexBlocks`. Either is passed to `parse` as the fourth
19- // argument, so one timed closure serves both.
20- const closerBuilder = await importOptional ( `${ sourceRoot } /lib/blocks.js` ) . then (
21- ( blocks ) => blocks && ( ( tokens ) => blocks . matchBlocks ( tokens ) . close )
17+ const { matchBlocks } = await import (
18+ pathToFileURL ( `${ sourceRoot } /lib/blocks.js` ) . href
2219) ;
23- const buildCloser =
24- closerBuilder ??
25- ( await importOptional ( `${ sourceRoot } /lib/block-index.js` ) ) ?. indexBlocks ;
26- if ( typeof parser . parse !== 'function' )
20+ const buildCloser = ( tokens ) => matchBlocks ( tokens ) . close ;
21+ if ( typeof parser . parse !== 'function' || typeof matchBlocks !== 'function' )
2722 throw new Error ( 'incompatible baseline parser API' ) ;
2823
2924const TARGET_MS = payload . targetBatchMs ?? 25 ;
3025const MIN_WARMUPS = payload . warmupMinimum ?? 5 ;
3126const MAX_WARMUPS = payload . warmupMaximum ?? 10 ;
3227const MEASURED_BATCHES = payload . measuredBatchCount ?? 6 ;
3328
34- /** @param {string } url @return {Promise<any> } undefined when the module is absent */
35- async function importOptional ( url ) {
36- try {
37- return await import ( pathToFileURL ( url ) . href ) ;
38- } catch ( error ) {
39- if (
40- error instanceof Error &&
41- 'code' in error &&
42- error . code === 'ERR_MODULE_NOT_FOUND'
43- ) {
44- return undefined ;
45- }
46- throw error ;
47- }
48- }
49-
50- /**
51- * Opaque components were nested arrays before the flat representation. Both
52- * shapes describe the same text, so compare them by their flattened form:
53- * arrays are spliced in and adjacent strings are merged.
54- */
55- function normalizeTree ( value ) {
56- if ( value === null || typeof value !== 'object' ) return value ;
57- if ( Array . isArray ( value ) ) return value . map ( normalizeTree ) ;
58- if ( value . type === 'OpaqueCall' ) {
59- const parts = [ ] ;
60- const pushPart = ( part ) => {
61- if ( Array . isArray ( part ) ) {
62- for ( const child of part ) pushPart ( child ) ;
63- } else if ( typeof part === 'string' && typeof parts . at ( - 1 ) === 'string' ) {
64- parts [ parts . length - 1 ] += part ;
65- } else {
66- parts . push ( normalizeTree ( part ) ) ;
67- }
68- } ;
69- for ( const part of value . components ) pushPart ( part ) ;
70- return { ...value , components : parts } ;
71- }
72- return Object . fromEntries (
73- Object . entries ( value ) . map ( ( [ key , child ] ) => [ key , normalizeTree ( child ) ] )
74- ) ;
75- }
76-
77- function digest ( input ) {
78- const value = normalizeTree ( input ) ;
29+ function digest ( value ) {
7930 const hash = createHash ( 'sha256' ) ;
8031 const stack = [ value ] ;
8132 while ( stack . length ) {
@@ -113,13 +64,10 @@ function consume(value) {
11364
11465function makeRun ( workload ) {
11566 const tokens = tokenize ( { css : workload . source } ) ;
116- const shared = buildCloser && workload . mode === 'hot-shared-index' ;
117- const closer = shared ? buildCloser ( tokens ) : undefined ;
118- return ( ) => {
119- if ( ! buildCloser ) return parser . parse ( tokens , 0 , tokens . length ) ;
120- const current = closer ?? buildCloser ( tokens ) ;
121- return parser . parse ( tokens , 0 , tokens . length , current ) ;
122- } ;
67+ const closer =
68+ workload . mode === 'hot-shared-index' ? buildCloser ( tokens ) : undefined ;
69+ return ( ) =>
70+ parser . parse ( tokens , 0 , tokens . length , closer ?? buildCloser ( tokens ) ) ;
12371}
12472
12573function timedBatch ( run , repetitions ) {
0 commit comments