@@ -3,7 +3,12 @@ import assert from "node:assert/strict";
33import { createRequire } from "node:module" ;
44
55const require = createRequire ( import . meta. url ) ;
6- const { SourceMap, resultPtr, wasmMemory } = require ( "../pkg/srcmap_sourcemap_wasm.js" ) ;
6+ const {
7+ LazySourceMap,
8+ SourceMap,
9+ resultPtr,
10+ wasmMemory,
11+ } = require ( "../pkg/srcmap_sourcemap_wasm.js" ) ;
712
813const SIMPLE_MAP = JSON . stringify ( {
914 version : 3 ,
@@ -426,3 +431,135 @@ describe("indexed source maps", () => {
426431 sm . free ( ) ;
427432 } ) ;
428433} ) ;
434+
435+ describe ( "LazySourceMap" , ( ) => {
436+ const indexedMap = JSON . stringify ( {
437+ version : 3 ,
438+ sections : [
439+ {
440+ offset : { line : 0 , column : 0 } ,
441+ map : {
442+ version : 3 ,
443+ sources : [ "a.js" ] ,
444+ names : [ ] ,
445+ mappings : "AAAA" ,
446+ } ,
447+ } ,
448+ ] ,
449+ } ) ;
450+
451+ const compareLookup = ( eager , lazy , line , column ) => {
452+ assert . deepEqual (
453+ lazy . originalPositionFor ( line , column ) ,
454+ eager . originalPositionFor ( line , column ) ,
455+ ) ;
456+ } ;
457+
458+ it ( "constructs from JSON and matches eager structured lookups" , ( ) => {
459+ const eager = new SourceMap ( MULTI_SOURCE_MAP ) ;
460+ const lazy = new LazySourceMap ( MULTI_SOURCE_MAP ) ;
461+
462+ assert . deepEqual ( lazy . sources , eager . sources ) ;
463+ assert . deepEqual ( lazy . names , eager . names ) ;
464+ compareLookup ( eager , lazy , 0 , 0 ) ;
465+ compareLookup ( eager , lazy , 1 , 0 ) ;
466+ compareLookup ( eager , lazy , 999 , 999 ) ;
467+
468+ lazy . free ( ) ;
469+ eager . free ( ) ;
470+ } ) ;
471+
472+ it ( "constructs from mappings and metadata" , ( ) => {
473+ const map = JSON . parse ( MULTI_SOURCE_MAP ) ;
474+ const metadata = JSON . stringify ( {
475+ version : map . version ,
476+ sources : map . sources ,
477+ names : map . names ,
478+ } ) ;
479+ const eager = new SourceMap ( MULTI_SOURCE_MAP ) ;
480+ const lazy = LazySourceMap . fromParts ( map . mappings , metadata ) ;
481+
482+ compareLookup ( eager , lazy , 0 , 0 ) ;
483+ compareLookup ( eager , lazy , 1 , 5 ) ;
484+
485+ lazy . free ( ) ;
486+ eager . free ( ) ;
487+ } ) ;
488+
489+ it ( "matches eager flat lookups" , ( ) => {
490+ const eager = new SourceMap ( SIMPLE_MAP ) ;
491+ const lazy = new LazySourceMap ( SIMPLE_MAP ) ;
492+
493+ assert . deepEqual ( [ ...lazy . originalPositionFlat ( 0 , 9 ) ] , [ ...eager . originalPositionFlat ( 0 , 9 ) ] ) ;
494+ assert . deepEqual (
495+ [ ...lazy . originalPositionFlat ( 999 , 999 ) ] ,
496+ [ ...eager . originalPositionFlat ( 999 , 999 ) ] ,
497+ ) ;
498+
499+ lazy . free ( ) ;
500+ eager . free ( ) ;
501+ } ) ;
502+
503+ it ( "matches eager static-buffer lookups" , ( ) => {
504+ const eager = new SourceMap ( MULTI_SOURCE_MAP ) ;
505+ const lazy = new LazySourceMap ( MULTI_SOURCE_MAP ) ;
506+ const offset = resultPtr ( ) ;
507+
508+ assert . equal ( lazy . originalPositionBuf ( 1 , 5 ) , true ) ;
509+ const view = new Int32Array ( wasmMemory ( ) . buffer , offset , 4 ) ;
510+ assert . deepEqual ( [ ...view ] , [ ...eager . originalPositionFlat ( 1 , 5 ) ] ) ;
511+ assert . equal ( lazy . originalPositionBuf ( 999 , 999 ) , false ) ;
512+
513+ lazy . free ( ) ;
514+ eager . free ( ) ;
515+ } ) ;
516+
517+ it ( "matches eager batch lookups" , ( ) => {
518+ const eager = new SourceMap ( MULTI_SOURCE_MAP ) ;
519+ const lazy = new LazySourceMap ( MULTI_SOURCE_MAP ) ;
520+ const queries = new Int32Array ( [ 0 , 0 , 1 , 0 , 1 , 5 , 999 , 999 ] ) ;
521+
522+ assert . deepEqual (
523+ [ ...lazy . originalPositionsFor ( queries ) ] ,
524+ [ ...eager . originalPositionsFor ( queries ) ] ,
525+ ) ;
526+
527+ lazy . free ( ) ;
528+ eager . free ( ) ;
529+ } ) ;
530+
531+ it ( "keeps cached results stable across repeated and backward queries" , ( ) => {
532+ const eager = new SourceMap ( MULTI_SOURCE_MAP ) ;
533+ const lazy = new LazySourceMap ( MULTI_SOURCE_MAP ) ;
534+ const queries = [
535+ [ 1 , 5 ] ,
536+ [ 1 , 0 ] ,
537+ [ 0 , 0 ] ,
538+ [ 1 , 5 ] ,
539+ [ 0 , 0 ] ,
540+ ] ;
541+
542+ for ( const [ line , column ] of queries ) {
543+ compareLookup ( eager , lazy , line , column ) ;
544+ }
545+
546+ lazy . free ( ) ;
547+ eager . free ( ) ;
548+ } ) ;
549+
550+ it ( "rejects invalid and indexed JSON" , ( ) => {
551+ assert . throws ( ( ) => new LazySourceMap ( "not json" ) ) ;
552+ assert . throws (
553+ ( ) => new LazySourceMap ( indexedMap ) ,
554+ / s e c t i o n m a p m u s t n o t b e a n i n d e x e d s o u r c e m a p / ,
555+ ) ;
556+ } ) ;
557+
558+ it ( "releases its WASM allocation" , ( ) => {
559+ const lazy = new LazySourceMap ( SIMPLE_MAP ) ;
560+
561+ lazy . free ( ) ;
562+
563+ assert . throws ( ( ) => lazy . originalPositionFor ( 0 , 0 ) ) ;
564+ } ) ;
565+ } ) ;
0 commit comments