thebird 1.2.79 → 1.2.81

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.
Files changed (79) hide show
  1. package/.github/workflows/publish.yml +9 -1
  2. package/CHANGELOG.md +217 -0
  3. package/CLAUDE.md +16 -0
  4. package/docs/agent-chat.js +7 -4
  5. package/docs/app.js +14 -11
  6. package/docs/defaults.json +1 -1
  7. package/docs/index.html +23 -6
  8. package/docs/kilo-fs-mirror.js +15 -0
  9. package/docs/kilo-http-stream.js +47 -0
  10. package/docs/node-builtins.js +24 -0
  11. package/docs/preview/index.html +32 -0
  12. package/docs/preview-sw-client.js +37 -6
  13. package/docs/preview-sw.js +55 -51
  14. package/docs/shell-awk.js +113 -0
  15. package/docs/shell-builtins-extra.js +121 -0
  16. package/docs/shell-builtins-text.js +109 -0
  17. package/docs/shell-builtins-util.js +112 -0
  18. package/docs/shell-builtins.js +183 -0
  19. package/docs/shell-bun.js +45 -0
  20. package/docs/shell-control.js +132 -0
  21. package/docs/shell-deno.js +54 -0
  22. package/docs/shell-exec.js +85 -0
  23. package/docs/shell-expand.js +164 -0
  24. package/docs/shell-fd.js +86 -0
  25. package/docs/shell-jobs.js +86 -0
  26. package/docs/shell-node-advanced.js +86 -0
  27. package/docs/shell-node-brotli.js +22 -0
  28. package/docs/shell-node-busnet.js +90 -0
  29. package/docs/shell-node-cipher.js +61 -0
  30. package/docs/shell-node-cluster.js +33 -0
  31. package/docs/shell-node-coreutils.js +36 -0
  32. package/docs/shell-node-crypto.js +137 -0
  33. package/docs/shell-node-dns.js +41 -0
  34. package/docs/shell-node-extras.js +148 -0
  35. package/docs/shell-node-firefox.js +95 -0
  36. package/docs/shell-node-git.js +60 -0
  37. package/docs/shell-node-inspector.js +39 -0
  38. package/docs/shell-node-io.js +131 -0
  39. package/docs/shell-node-ipc.js +15 -0
  40. package/docs/shell-node-keyobject.js +60 -0
  41. package/docs/shell-node-modules.js +157 -0
  42. package/docs/shell-node-native.js +31 -0
  43. package/docs/shell-node-net.js +71 -0
  44. package/docs/shell-node-observe.js +80 -0
  45. package/docs/shell-node-opfs.js +54 -0
  46. package/docs/shell-node-procfs.js +42 -0
  47. package/docs/shell-node-profiler.js +50 -0
  48. package/docs/shell-node-registry.js +24 -0
  49. package/docs/shell-node-resolve.js +147 -0
  50. package/docs/shell-node-runtime.js +83 -0
  51. package/docs/shell-node-srcmap.js +52 -0
  52. package/docs/shell-node-stdlib.js +103 -0
  53. package/docs/shell-node-streams.js +66 -0
  54. package/docs/shell-node-tar.js +47 -0
  55. package/docs/shell-node-testrunner.js +35 -0
  56. package/docs/shell-node-util-extras.js +66 -0
  57. package/docs/shell-node.js +175 -169
  58. package/docs/shell-npm.js +173 -0
  59. package/docs/shell-parser.js +122 -0
  60. package/docs/shell-pm-layout.js +62 -0
  61. package/docs/shell-pm.js +39 -0
  62. package/docs/shell-posix.js +70 -0
  63. package/docs/shell-procsub.js +65 -0
  64. package/docs/shell-readline.js +59 -4
  65. package/docs/shell-runtime.js +37 -0
  66. package/docs/shell-sed.js +83 -0
  67. package/docs/shell-signals.js +54 -0
  68. package/docs/shell-sw-jobs.js +76 -0
  69. package/docs/shell-ts.js +30 -0
  70. package/docs/shell.js +161 -152
  71. package/docs/terminal.js +9 -11
  72. package/docs/todo.html +211 -0
  73. package/package.json +1 -1
  74. package/server.js +43 -4
  75. package/start-kilo.js +45 -0
  76. package/test.js +199 -0
  77. package/.codeinsight +0 -73
  78. package/docs/acp-stream.js +0 -102
  79. package/docs/coi-serviceworker.js +0 -2
@@ -0,0 +1,80 @@
1
+ export function makeDebugRegistry(){
2
+ const reg={modules:{},streamsOpen:new Set(),workersActive:new Set(),cryptoOps:0,requireCount:0,zlibBytes:{in:0,out:0},http2Sessions:0,vmContexts:0,activeRequires:[]};
3
+ if(typeof window!=='undefined'){window.__debug=window.__debug||{};window.__debug.node=reg;}
4
+ return reg;
5
+ }
6
+
7
+ export function makeDiagnosticsChannel(){
8
+ const channels=new Map();
9
+ const ch=name=>{if(!channels.has(name))channels.set(name,{name,subs:new Set(),subscribe(fn){this.subs.add(fn);return this;},unsubscribe(fn){this.subs.delete(fn);return this;},publish(msg){for(const fn of this.subs)try{fn(msg,name);}catch{}},hasSubscribers(){return this.subs.size>0;}});return channels.get(name);};
10
+ return{
11
+ channel:ch,
12
+ subscribe(name,fn){ch(name).subscribe(fn);},
13
+ unsubscribe(name,fn){ch(name).unsubscribe(fn);},
14
+ hasSubscribers(name){return ch(name).hasSubscribers();},
15
+ tracingChannel(name){const start=ch(name+':start');const end=ch(name+':end');const asyncStart=ch(name+':asyncStart');const asyncEnd=ch(name+':asyncEnd');const error=ch(name+':error');return{start,end,asyncStart,asyncEnd,error,traceSync(fn,ctx){start.publish(ctx);try{const r=fn.call(ctx);end.publish({...ctx,result:r});return r;}catch(e){error.publish({...ctx,error:e});throw e;}},async tracePromise(fn,ctx){start.publish(ctx);try{const r=await fn.call(ctx);asyncEnd.publish({...ctx,result:r});return r;}catch(e){error.publish({...ctx,error:e});throw e;}}};},
16
+ };
17
+ }
18
+
19
+ export function makeTraceEvents(reg){
20
+ const events=[];
21
+ reg.traceEvents=events;
22
+ const tracings=[];
23
+ return{
24
+ createTracing({categories=[]}={}){const t={categories,enabled:false,enable(){this.enabled=true;tracings.push(this);},disable(){this.enabled=false;const i=tracings.indexOf(this);if(i>=0)tracings.splice(i,1);}};return t;},
25
+ getEnabledCategories(){const out=new Set();for(const t of tracings)if(t.enabled)for(const c of t.categories)out.add(c);return[...out];},
26
+ _emit(cat,name,data){if(events.length>=10000)events.shift();events.push({cat,name,data,ts:performance.now()});},
27
+ };
28
+ }
29
+
30
+ export function makeBufferPool(Buf,poolSize=8192){
31
+ let pool=new Uint8Array(poolSize);
32
+ let offset=0;
33
+ Buf.poolSize=poolSize;
34
+ const origAllocUnsafe=Buf.allocUnsafe;
35
+ Buf.allocUnsafe=size=>{if(size>=poolSize>>>1)return origAllocUnsafe(size);if(offset+size>poolSize){pool=new Uint8Array(poolSize);offset=0;}const slice=Buf.from(pool.buffer,pool.byteOffset+offset,size);offset+=size;offset=(offset+7)&~7;return slice;};
36
+ Buf.allocUnsafeSlow=size=>origAllocUnsafe(size);
37
+ return Buf;
38
+ }
39
+
40
+ export function makeProcessBindings(util){
41
+ const bindings={util:{isDate:v=>v instanceof Date,isRegExp:v=>v instanceof RegExp,isMap:v=>v instanceof Map,isSet:v=>v instanceof Set,isPromise:v=>v instanceof Promise,isNativeError:v=>v instanceof Error,isArrayBuffer:v=>v instanceof ArrayBuffer,isTypedArray:v=>ArrayBuffer.isView(v)&&!(v instanceof DataView),getHiddenValue:()=>undefined,setHiddenValue:()=>{}}};
42
+ return name=>{if(bindings[name])return bindings[name];throw new Error(`process.binding('${name}'): internal binding not exposed`);};
43
+ }
44
+
45
+ export function makePerfMemory(perf){
46
+ const getMemory=()=>{const m=performance.memory||{usedJSHeapSize:0,totalJSHeapSize:0,jsHeapSizeLimit:1073741824};return{rss:m.totalJSHeapSize||50000000,heapTotal:m.totalJSHeapSize||10000000,heapUsed:m.usedJSHeapSize||5000000,external:0,arrayBuffers:0};};
47
+ perf.measureUserAgentSpecificMemory=performance.measureUserAgentSpecificMemory?.bind(performance)||(async()=>({bytes:getMemory().heapUsed,breakdown:[]}));
48
+ return getMemory;
49
+ }
50
+
51
+ export function makeFetchPool(){
52
+ return class Agent{
53
+ constructor(opts={}){this.maxSockets=opts.maxSockets||Infinity;this.keepAlive=opts.keepAlive!==false;this._queue=[];this._active=0;this._controllers=new Set();}
54
+ _acquire(){if(this._active<this.maxSockets){this._active++;return Promise.resolve();}return new Promise(r=>this._queue.push(r));}
55
+ _release(){this._active--;const next=this._queue.shift();if(next){this._active++;next();}}
56
+ async fetch(url,opts={}){await this._acquire();const ctrl=new AbortController();this._controllers.add(ctrl);const signal=opts.signal?AbortSignal.any?.([opts.signal,ctrl.signal])||opts.signal:ctrl.signal;try{return await fetch(url,{...opts,signal});}finally{this._controllers.delete(ctrl);this._release();}}
57
+ destroy(){for(const c of this._controllers)c.abort();this._controllers.clear();}
58
+ };
59
+ }
60
+
61
+ export function installPrepareStackTraceHook(){
62
+ if(Error._psHooked)return;Error._psHooked=true;
63
+ const origGetStack=Object.getOwnPropertyDescriptor(Error.prototype,'stack');
64
+ const parseFrame=l=>{const m=l.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?/);return m?{getFileName:()=>m[2],getLineNumber:()=>+m[3],getColumnNumber:()=>+m[4],getFunctionName:()=>m[1]||null,isNative:()=>false,isEval:()=>false,toString:()=>l.trim()}:{getFileName:()=>null,getLineNumber:()=>0,getColumnNumber:()=>0,getFunctionName:()=>null,isNative:()=>false,toString:()=>l.trim()};};
65
+ if(!('prepareStackTrace'in Error))Error.prepareStackTrace=null;
66
+ Object.defineProperty(Error.prototype,'stack',{configurable:true,get(){const raw=origGetStack?.get?.call(this)||'';if(typeof Error.prepareStackTrace==='function'){const lines=raw.split('\n').slice(1).filter(l=>l.trim().startsWith('at '));const frames=lines.map(parseFrame);try{return Error.prepareStackTrace(this,frames);}catch{return raw;}}return raw;},set(v){Object.defineProperty(this,'stack',{value:v,writable:true,configurable:true});}});
67
+ }
68
+
69
+ export function installCaptureStackTrace(){
70
+ if(Error.captureStackTrace)return;
71
+ Error.captureStackTrace=(target,ctor)=>{const e=new Error();const lines=(e.stack||'').split('\n');target.stack=(ctor?.name?ctor.name:'Error')+(target.message?': '+target.message:'')+'\n'+lines.slice(2).join('\n');};
72
+ }
73
+
74
+ export function makeFsWatchReal(getSnap){
75
+ const watchers=[];
76
+ let lastSnap=null;
77
+ const tick=()=>{const cur=getSnap();if(!lastSnap){lastSnap={...cur};return;}const curKeys=new Set(Object.keys(cur));const prevKeys=new Set(Object.keys(lastSnap));const changed=[];for(const k of curKeys)if(!prevKeys.has(k)||cur[k]!==lastSnap[k])changed.push({type:prevKeys.has(k)?'change':'rename',path:k});for(const k of prevKeys)if(!curKeys.has(k))changed.push({type:'rename',path:k});for(const {type,path} of changed)for(const w of watchers)if(path===w.path||(w.recursive&&path.startsWith(w.path+'/')))for(const h of w.handlers.change)h(type,path.split('/').pop());lastSnap={...cur};};
78
+ setInterval(tick,500);
79
+ return (path,opts={},listener)=>{if(typeof opts==='function'){listener=opts;opts={};}const normalized=path.replace(/^\/+/,'').replace(/\/$/,'');const handlers={change:listener?[listener]:[],error:[],close:[]};const w={path:normalized,recursive:!!opts.recursive,handlers,on:(ev,fn)=>{(handlers[ev]=handlers[ev]||[]).push(fn);return w;},close:()=>{const i=watchers.indexOf(w);if(i>=0)watchers.splice(i,1);for(const h of handlers.close)h();},ref:()=>w,unref:()=>w};watchers.push(w);return w;};
80
+ }
@@ -0,0 +1,54 @@
1
+ const WORKER_SRC=`
2
+ self.addEventListener('message',async e=>{
3
+ const {id,op,path,data,flags}=e.data;
4
+ try{
5
+ const root=await navigator.storage.getDirectory();
6
+ const parts=path.replace(/^\\/+/,'').split('/');
7
+ const fname=parts.pop();
8
+ let dir=root;
9
+ for(const p of parts){if(!p)continue;try{dir=await dir.getDirectoryHandle(p,{create:op==='write'||op==='mkdir'});}catch(err){if(op==='read'||op==='stat'||op==='delete'){self.postMessage({id,error:'ENOENT: '+path});return;}throw err;}}
10
+ if(op==='mkdir'){await dir.getDirectoryHandle(fname,{create:true});self.postMessage({id,ok:true});return;}
11
+ if(op==='read'){const h=await dir.getFileHandle(fname);const f=await h.getFile();const buf=new Uint8Array(await f.arrayBuffer());self.postMessage({id,data:buf},[buf.buffer]);return;}
12
+ if(op==='write'){const h=await dir.getFileHandle(fname,{create:true});const sync=await h.createSyncAccessHandle();const bytes=data instanceof Uint8Array?data:new TextEncoder().encode(String(data));sync.truncate(0);sync.write(bytes,{at:0});sync.flush();sync.close();self.postMessage({id,ok:true});return;}
13
+ if(op==='stat'){const h=await dir.getFileHandle(fname).catch(()=>dir.getDirectoryHandle(fname));const f=await h.getFile?.();self.postMessage({id,size:f?.size||0,mtime:f?.lastModified||0,isFile:!!f,isDirectory:!f});return;}
14
+ if(op==='delete'){await dir.removeEntry(fname,{recursive:flags?.recursive||false});self.postMessage({id,ok:true});return;}
15
+ if(op==='list'){const out=[];for await(const [name,h] of dir.entries())out.push({name,kind:h.kind});self.postMessage({id,entries:out});return;}
16
+ self.postMessage({id,error:'unknown op: '+op});
17
+ }catch(err){self.postMessage({id,error:err.message});}
18
+ });
19
+ `;
20
+
21
+ export function makeOpfsBackend(Buf){
22
+ if(typeof navigator==='undefined'||!navigator.storage?.getDirectory)return null;
23
+ const blob=new Blob([WORKER_SRC],{type:'application/javascript'});
24
+ const url=URL.createObjectURL(blob);
25
+ const worker=new Worker(url);
26
+ const pending=new Map();let nextId=1;
27
+ worker.addEventListener('message',e=>{const {id,...rest}=e.data;const p=pending.get(id);if(!p)return;pending.delete(id);if(rest.error)p.reject(new Error(rest.error));else p.resolve(rest);});
28
+ const call=(op,path,data,flags)=>new Promise((resolve,reject)=>{const id=nextId++;pending.set(id,{resolve,reject});worker.postMessage({id,op,path,data,flags});});
29
+ return{
30
+ readFile:async(path,enc)=>{const r=await call('read',path);return enc?new TextDecoder(enc==='utf-8'?'utf-8':enc).decode(r.data):Buf.from(r.data);},
31
+ writeFile:async(path,data)=>{await call('write',path,data);},
32
+ mkdir:async path=>{await call('mkdir',path);},
33
+ rm:async(path,opts)=>{await call('delete',path,null,opts);},
34
+ stat:async path=>call('stat',path),
35
+ list:async path=>{const r=await call('list',path);return r.entries;},
36
+ _worker:worker,
37
+ _url:url,
38
+ };
39
+ }
40
+
41
+ export function wireOpfsIntoFs(fs,opfs,reg){
42
+ if(!opfs)return fs;
43
+ const orig={readFileSync:fs.readFileSync,writeFileSync:fs.writeFileSync,existsSync:fs.existsSync,statSync:fs.statSync,mkdirSync:fs.mkdirSync,rmSync:fs.rmSync,unlinkSync:fs.unlinkSync};
44
+ fs.promises=fs.promises||{};
45
+ fs.promises.readFile=async(p,enc)=>opfs.readFile(p,enc).catch(()=>orig.readFileSync(p,enc));
46
+ fs.promises.writeFile=async(p,d)=>{await opfs.writeFile(p,d).catch(()=>orig.writeFileSync(p,d));};
47
+ fs.promises.mkdir=async(p,o)=>{await opfs.mkdir(p).catch(()=>orig.mkdirSync(p,o));};
48
+ fs.promises.rm=async(p,o)=>{await opfs.rm(p,o).catch(()=>orig.rmSync(p,o));};
49
+ fs.promises.stat=async p=>opfs.stat(p).catch(()=>orig.statSync(p));
50
+ fs.promises.readdir=async p=>opfs.list(p).then(es=>es.map(e=>e.name)).catch(()=>fs.readdirSync(p));
51
+ reg.polyfills=reg.polyfills||{};
52
+ reg.polyfills.opfs={active:true,backing:'native',reason:'OPFS available'};
53
+ return fs;
54
+ }
@@ -0,0 +1,42 @@
1
+ export function makeProcFs(proc){
2
+ const g=globalThis;
3
+ const gen={
4
+ 'proc/self/cmdline':()=>(proc.argv||[]).join('\0')+'\0',
5
+ 'proc/self/environ':()=>Object.entries(proc.env||{}).map(([k,v])=>`${k}=${v}`).join('\0')+'\0',
6
+ 'proc/self/cwd':()=>proc.cwd?.()||'/',
7
+ 'proc/self/exe':()=>proc.execPath||'/usr/local/bin/node',
8
+ 'proc/self/status':()=>{const m=performance.memory||{usedJSHeapSize:0,totalJSHeapSize:0};return`Name:\tnode\nState:\tR (running)\nPid:\t${proc.pid||1}\nPPid:\t${proc.ppid||0}\nUid:\t0\t0\t0\t0\nGid:\t0\t0\t0\t0\nVmRSS:\t${(m.totalJSHeapSize/1024)|0} kB\nVmPeak:\t${(m.totalJSHeapSize/1024)|0} kB\n`;},
9
+ 'proc/self/stat':()=>`${proc.pid||1} (node) R ${proc.ppid||0} ${proc.pid||1} ${proc.pid||1} 0 -1 4194304 0 0 0 0 0 0 0 0 20 0 1 0 ${performance.now()|0} ${(performance.memory?.totalJSHeapSize||0)} 0 18446744073709551615 0 0 0 0 0 0 0 0 0 0 0 0 17 0 0 0 0 0 0\n`,
10
+ 'proc/self/maps':()=>'00400000-00500000 r-xp 00000000 00:00 0 [text]\n',
11
+ 'proc/self/limits':()=>'Limit Soft Limit Hard Limit\nMax open files 1024 4096\n',
12
+ 'proc/cpuinfo':()=>{const n=navigator?.hardwareConcurrency||4;let out='';for(let i=0;i<n;i++)out+=`processor\t: ${i}\nvendor_id\t: BrowserCPU\nmodel name\t: Browser JS Engine\ncpu MHz\t\t: 3000.000\ncache size\t: 8192 KB\ncores\t\t: ${n}\n\n`;return out;},
13
+ 'proc/meminfo':()=>{const m=performance.memory||{totalJSHeapSize:1e9,jsHeapSizeLimit:2e9,usedJSHeapSize:5e8};return`MemTotal: ${(m.jsHeapSizeLimit/1024)|0} kB\nMemFree: ${((m.jsHeapSizeLimit-m.usedJSHeapSize)/1024)|0} kB\nMemAvailable: ${((m.jsHeapSizeLimit-m.usedJSHeapSize)/1024)|0} kB\nBuffers: 0 kB\nCached: 0 kB\n`;},
14
+ 'proc/uptime':()=>`${(performance.now()/1000).toFixed(2)} ${(performance.now()/1000).toFixed(2)}\n`,
15
+ 'proc/loadavg':()=>'0.00 0.00 0.00 1/1 '+(proc.pid||1)+'\n',
16
+ 'proc/version':()=>`Linux version 6.0.0-browser (node@thebird) #1 SMP ${new Date().toUTCString()}\n`,
17
+ 'proc/stat':()=>'cpu 0 0 0 0 0 0 0 0 0 0\nbtime '+Math.floor(Date.now()/1000)+'\n',
18
+ 'proc/mounts':()=>'idbfs / idbfs rw,relatime 0 0\n',
19
+ 'proc/filesystems':()=>'nodev\tidbfs\nnodev\topfs\n',
20
+ 'etc/hosts':()=>'127.0.0.1 localhost\n::1 localhost\n',
21
+ 'etc/resolv.conf':()=>'nameserver 1.1.1.1\nnameserver 8.8.8.8\n',
22
+ 'etc/passwd':()=>'root:x:0:0:root:/root:/bin/sh\n',
23
+ 'etc/group':()=>'root:x:0:\n',
24
+ 'etc/os-release':()=>'NAME="thebird"\nPRETTY_NAME="thebird browser runtime"\nID=thebird\nID_LIKE=linux\nVERSION_ID="1.0"\n',
25
+ 'etc/hostname':()=>'thebird\n',
26
+ 'etc/machine-id':()=>'00000000000000000000000000000000\n',
27
+ 'etc/shells':()=>'/bin/sh\n/bin/bash\n',
28
+ };
29
+ return{
30
+ handles(path){const k=path.replace(/^\//,'').replace(/\/$/,'');return k in gen;},
31
+ read(path){const k=path.replace(/^\//,'').replace(/\/$/,'');const fn=gen[k];if(!fn)return null;try{return fn();}catch{return'';}},
32
+ list(){return Object.keys(gen).map(k=>'/'+k);},
33
+ };
34
+ }
35
+
36
+ export function wireProcFs(fs,procFs){
37
+ const origRead=fs.readFileSync, origExists=fs.existsSync, origStat=fs.statSync;
38
+ fs.readFileSync=(p,enc)=>{if(procFs.handles(p)){const s=procFs.read(p);return enc?s:new TextEncoder().encode(s);}return origRead(p,enc);};
39
+ fs.existsSync=p=>procFs.handles(p)||origExists(p);
40
+ fs.statSync=p=>{if(procFs.handles(p)){const s=procFs.read(p);return{size:s.length,mode:0o100444,isFile:()=>true,isDirectory:()=>false,isSymbolicLink:()=>false,isFIFO:()=>false,isBlockDevice:()=>false,isCharacterDevice:()=>false,isSocket:()=>false,mtimeMs:Date.now(),mtime:new Date(),atimeMs:Date.now(),ctimeMs:Date.now(),birthtimeMs:Date.now(),uid:0,gid:0,nlink:1,dev:0,ino:0,rdev:0,blksize:4096,blocks:1};}return origStat(p);};
41
+ return fs;
42
+ }
@@ -0,0 +1,50 @@
1
+ export function makeV8Profiler(debugReg){
2
+ const samples=[];let observer=null;let running=false;let startT=0;
3
+ const startObserver=()=>{if(observer||typeof PerformanceObserver==='undefined')return;try{observer=new PerformanceObserver(list=>{for(const e of list.getEntries())if(running)samples.push({name:e.name,ts:e.startTime,dur:e.duration,entryType:e.entryType});});observer.observe({entryTypes:['measure','longtask','function']});}catch{}};
4
+ const stopObserver=()=>{if(observer){observer.disconnect();observer=null;}};
5
+ return{
6
+ CPUProfile:class CPUProfile{
7
+ constructor(){this.nodes=[];this.samples=[];this.timeDeltas=[];this.startTime=0;this.endTime=0;this.title='';}
8
+ startProfiling(title){this.title=title||'';samples.length=0;startT=performance.now();running=true;startObserver();}
9
+ stopProfiling(){running=false;stopObserver();const end=performance.now();this.startTime=startT*1000;this.endTime=end*1000;this.nodes=samples.map((s,i)=>({id:i+1,callFrame:{functionName:s.name||'(anonymous)',scriptId:'0',url:'',lineNumber:0,columnNumber:0},hitCount:1,children:[]}));this.samples=samples.map((_,i)=>i+1);this.timeDeltas=samples.map(s=>Math.round(s.dur*1000));return this;}
10
+ },
11
+ startProfiling(){const p=new this.CPUProfile();p.startProfiling();return p;},
12
+ stopProfiling(p){return p?p.stopProfiling():null;},
13
+ getHeapStatistics(){const m=performance.memory||{usedJSHeapSize:5e6,totalJSHeapSize:10e6,jsHeapSizeLimit:1e9};return{total_heap_size:m.totalJSHeapSize,total_heap_size_executable:0,total_physical_size:m.totalJSHeapSize,total_available_size:m.jsHeapSizeLimit-m.usedJSHeapSize,used_heap_size:m.usedJSHeapSize,heap_size_limit:m.jsHeapSizeLimit,malloced_memory:0,peak_malloced_memory:0,does_zap_garbage:0,number_of_native_contexts:1,number_of_detached_contexts:0};},
14
+ getHeapSpaceStatistics(){return[{space_name:'new_space',space_size:1e6,space_used_size:5e5,space_available_size:5e5,physical_space_size:1e6}];},
15
+ getHeapCodeStatistics(){return{code_and_metadata_size:0,bytecode_and_metadata_size:0,external_script_source_size:0};},
16
+ cachedDataVersionTag:()=>0,
17
+ setFlagsFromString(){},
18
+ startupSnapshot:{isBuildingSnapshot:()=>false,addSerializeCallback(){},addDeserializeCallback(){}},
19
+ };
20
+ }
21
+
22
+ export function makeHeapSnapshot(){
23
+ const NODE_FIELDS=['type','name','id','self_size','edge_count','trace_node_id','detachedness'];
24
+ const NODE_TYPES=[['hidden','array','string','object','code','closure','regexp','number','native','synthetic','concatenated string','sliced string','symbol','bigint','object shape'],'string','number','number','number','number','number'];
25
+ const EDGE_FIELDS=['type','name_or_index','to_node'];
26
+ const EDGE_TYPES=[['context','element','property','internal','hidden','shortcut','weak'],'string_or_number','node'];
27
+ const META={node_fields:NODE_FIELDS,node_types:NODE_TYPES,edge_fields:EDGE_FIELDS,edge_types:EDGE_TYPES,trace_function_info_fields:[],trace_node_fields:[],sample_fields:[],location_fields:[]};
28
+ const walk=(root,maxNodes=5000)=>{
29
+ const visited=new WeakMap();const strings=[''];const stringIdx=new Map([['',0]]);
30
+ const addStr=s=>{if(stringIdx.has(s))return stringIdx.get(s);const i=strings.length;strings.push(s);stringIdx.set(s,i);return i;};
31
+ const nodes=[];const edges=[];const queue=[[root,'root']];
32
+ while(queue.length&&nodes.length<maxNodes){
33
+ const [obj,name]=queue.shift();
34
+ const isObj=obj!==null&&(typeof obj==='object'||typeof obj==='function');
35
+ if(isObj&&visited.has(obj))continue;
36
+ const id=nodes.length+1;if(isObj)visited.set(obj,id);
37
+ const t=obj===null?9:typeof obj==='string'?2:typeof obj==='number'?7:typeof obj==='bigint'?13:typeof obj==='symbol'?12:Array.isArray(obj)?1:typeof obj==='function'?5:3;
38
+ let childEdges=0;
39
+ if(isObj){try{for(const k of Object.keys(obj).slice(0,32)){queue.push([obj[k],k]);childEdges++;}}catch{}}
40
+ nodes.push([t,addStr(name),id,typeof obj==='string'?obj.length:64,childEdges,0,0]);
41
+ }
42
+ let cursor=0;
43
+ for(const n of nodes){const childCount=n[4];for(let i=0;i<childCount;i++){edges.push([2,cursor+i+1,(cursor+i+1)*NODE_FIELDS.length]);}cursor+=childCount;}
44
+ return{snapshot:{meta:META,node_count:nodes.length,edge_count:edges.length,trace_function_count:0},nodes:nodes.flat(),edges:edges.flat(),trace_function_infos:[],trace_tree:[],samples:[],locations:[],strings};
45
+ };
46
+ return{
47
+ writeHeapSnapshot(filename){const snap=walk(globalThis);const json=JSON.stringify(snap);if(typeof filename==='string'&&globalThis.window?.__debug?.idbSnapshot){globalThis.window.__debug.idbSnapshot[filename.replace(/^\/+/,'')]=json;}return filename;},
48
+ getHeapSnapshot(){const snap=walk(globalThis);return{read(){return JSON.stringify(snap);}};},
49
+ };
50
+ }
@@ -0,0 +1,24 @@
1
+ const ESM_API='https://esm.sh';
2
+ const cache=new Map();
3
+
4
+ async function esmMeta(name){
5
+ if(cache.has(name))return cache.get(name);
6
+ try{
7
+ const url=`${ESM_API}/${name}/package.json`;
8
+ const r=await fetch(url);
9
+ if(!r.ok)throw new Error('not found');
10
+ const pj=await r.json();
11
+ cache.set(name,pj);return pj;
12
+ }catch(e){throw new Error(`registry: cannot fetch ${name} — ${e.message}`);}
13
+ }
14
+
15
+ export function makeRegistry(){
16
+ return{
17
+ async view(spec){const[name,field]=spec.split(/\s+/);const pj=await esmMeta(name);if(field){const parts=field.split('.');let v=pj;for(const p of parts)v=v?.[p];return v;}return pj;},
18
+ async search(q){try{const r=await fetch(`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(q)}&size=10`);const j=await r.json();return j.objects?.map(o=>({name:o.package.name,version:o.package.version,description:o.package.description}))||[];}catch{return[];}},
19
+ async deps(name,version='latest'){try{const pj=await esmMeta(version==='latest'?name:`${name}@${version}`);return{dependencies:pj.dependencies||{},devDependencies:pj.devDependencies||{},peerDependencies:pj.peerDependencies||{}};}catch{return{dependencies:{},devDependencies:{},peerDependencies:{}};}},
20
+ async tarballUrl(name,version){const pj=await esmMeta(`${name}@${version}`);return`https://registry.npmjs.org/${name}/-/${name.split('/').pop()}-${pj.version}.tgz`;},
21
+ async fetchTarball(name,version){const url=await this.tarballUrl(name,version);const r=await fetch(url);return new Uint8Array(await r.arrayBuffer());},
22
+ clearCache(){cache.clear();},
23
+ };
24
+ }
@@ -0,0 +1,147 @@
1
+ const toKey = p => p.replace(/^\//, '');
2
+
3
+ const CONDITIONS = ['node', 'import', 'require', 'default', 'browser'];
4
+ function pickCondition(cond) {
5
+ if (typeof cond === 'string') return cond;
6
+ if (Array.isArray(cond)) { for (const c of cond) { const r = pickCondition(c); if (r) return r; } return null; }
7
+ if (!cond || typeof cond !== 'object') return null;
8
+ for (const k of CONDITIONS) if (k in cond) { const r = pickCondition(cond[k]); if (r) return r; }
9
+ return null;
10
+ }
11
+ function matchPattern(patternKey, target) {
12
+ if (!patternKey.includes('*')) return null;
13
+ const [pre, post] = patternKey.split('*');
14
+ if (target.startsWith(pre) && target.endsWith(post)) return target.slice(pre.length, target.length - post.length);
15
+ return null;
16
+ }
17
+ export function resolveExports(pkgJson, subpath) {
18
+ const exp = pkgJson.exports;
19
+ if (!exp) return null;
20
+ if (typeof exp === 'string') return subpath === '.' ? exp : null;
21
+ const key = subpath === '.' ? '.' : './' + subpath.replace(/^\.\//, '');
22
+ if (exp[key]) return pickCondition(exp[key]);
23
+ if (subpath === '.' && !('.' in exp) && !Object.keys(exp).some(k => k.startsWith('.'))) return pickCondition(exp);
24
+ for (const pk of Object.keys(exp)) { const m = matchPattern(pk, key); if (m !== null) { const t = pickCondition(exp[pk]); return t ? t.replace('*', m) : null; } }
25
+ return null;
26
+ }
27
+ export function rewriteSpecifier(id) {
28
+ if (id.startsWith('jsr:')) return 'https://esm.sh/jsr/' + id.slice(4);
29
+ if (id.startsWith('npm:')) return 'https://esm.sh/' + id.slice(4);
30
+ if (id.startsWith('https://') || id.startsWith('http://')) return id;
31
+ return null;
32
+ }
33
+
34
+ export function resolveImports(pkgJson, subpath) {
35
+ const imps = pkgJson.imports;
36
+ if (!imps || !subpath.startsWith('#')) return null;
37
+ if (imps[subpath]) return pickCondition(imps[subpath]);
38
+ for (const pk of Object.keys(imps)) { const m = matchPattern(pk, subpath); if (m !== null) { const t = pickCondition(imps[pk]); return t ? t.replace('*', m) : null; } }
39
+ return null;
40
+ }
41
+
42
+ export function walkUpNodeModules(snap, startDir, pkgName) {
43
+ let dir = startDir.replace(/\/$/, '') || '/';
44
+ while (true) {
45
+ const candidate = (dir === '/' ? '' : dir) + '/node_modules/' + pkgName;
46
+ const candKey = toKey(candidate);
47
+ if ((candKey + '/package.json') in snap || (candKey + '/index.js') in snap || (candKey + '.js') in snap) return candidate;
48
+ if (dir === '/' || dir === '') return null;
49
+ const up = dir.slice(0, dir.lastIndexOf('/')) || '/';
50
+ if (up === dir) return null;
51
+ dir = up;
52
+ }
53
+ }
54
+
55
+ export function resolvePackageEntry(snap, pkgDir) {
56
+ const pjKey = toKey(pkgDir) + '/package.json';
57
+ if (!(pjKey in snap)) return null;
58
+ let pj;
59
+ try { pj = JSON.parse(snap[pjKey]); } catch { return null; }
60
+ const resolved = resolveExports(pj, '.');
61
+ if (resolved) return pkgDir + '/' + resolved.replace(/^\.\//, '');
62
+ return pkgDir + '/' + (pj.main || 'index.js').replace(/^\.\//, '');
63
+ }
64
+
65
+ export function makeModuleModule(requireFn, MODULES) {
66
+ return {
67
+ builtinModules: Object.keys(MODULES).filter(k => !k.startsWith('node:')).sort(),
68
+ createRequire: () => requireFn,
69
+ _resolveFilename: (id, parent) => requireFn.resolve(id),
70
+ _cache: requireFn.cache,
71
+ _pathCache: {},
72
+ Module: class Module { constructor(id) { this.id = id; this.exports = {}; this.filename = id; this.loaded = false; this.children = []; this.paths = []; } },
73
+ syncBuiltinESMExports: () => {},
74
+ wrap: s => '(function (exports, require, module, __filename, __dirname) { ' + s + '\n});',
75
+ wrapper: ['(function (exports, require, module, __filename, __dirname) { ', '\n});'],
76
+ };
77
+ }
78
+
79
+ export function makeModuleNotFoundError(id, requireStack) {
80
+ const err = new Error("Cannot find module '" + id + "'" + (requireStack ? '\nRequire stack:\n- ' + requireStack.join('\n- ') : ''));
81
+ err.code = 'MODULE_NOT_FOUND';
82
+ err.requireStack = requireStack || [];
83
+ return err;
84
+ }
85
+
86
+ export function makeFsPromises(fsSync) {
87
+ const wrap = fn => async (...args) => fn(...args);
88
+ return {
89
+ readFile: async (p, enc) => fsSync.readFileSync(p, enc),
90
+ writeFile: async (p, d) => fsSync.writeFileSync(p, d),
91
+ appendFile: async (p, d) => fsSync.appendFileSync(p, d),
92
+ access: async p => fsSync.accessSync(p),
93
+ stat: async p => fsSync.statSync(p),
94
+ readdir: async p => fsSync.readdirSync(p),
95
+ mkdir: async (p, o) => fsSync.mkdirSync(p, o),
96
+ rm: async (p, o) => fsSync.rmSync(p, o),
97
+ rmdir: async (p, o) => fsSync.rmdirSync(p, o),
98
+ unlink: async p => fsSync.unlinkSync(p),
99
+ rename: async (o, n) => fsSync.renameSync(o, n),
100
+ copyFile: async (s, d) => fsSync.copyFileSync(s, d),
101
+ realpath: async p => fsSync.realpathSync(p),
102
+ open: async p => ({ close: async () => {}, readFile: async enc => fsSync.readFileSync(p, enc), writeFile: async d => fsSync.writeFileSync(p, d) }),
103
+ };
104
+ }
105
+
106
+ export function makeFsWatch() {
107
+ return (path, opts, listener) => {
108
+ if (typeof opts === 'function') { listener = opts; opts = {}; }
109
+ const handlers = { change: listener ? [listener] : [], error: [], close: [] };
110
+ const w = {
111
+ on: (ev, fn) => { (handlers[ev] = handlers[ev] || []).push(fn); return w; },
112
+ close: () => { for (const h of handlers.close) h(); },
113
+ ref: () => w, unref: () => w,
114
+ };
115
+ return w;
116
+ };
117
+ }
118
+
119
+ export function makeNetStub() {
120
+ return {
121
+ Socket: class Socket { constructor() { throw new Error('net.Socket: not supported in browser — use fetch() or WebSocket'); } },
122
+ createServer: () => { throw new Error('net.createServer: not supported in browser — use express via http builtin'); },
123
+ connect: () => { throw new Error('net.connect: not supported in browser'); },
124
+ isIP: ip => /^\d+\.\d+\.\d+\.\d+$/.test(ip) ? 4 : ip.includes(':') ? 6 : 0,
125
+ isIPv4: ip => /^\d+\.\d+\.\d+\.\d+$/.test(ip),
126
+ isIPv6: ip => ip.includes(':'),
127
+ };
128
+ }
129
+
130
+ export function makeDgramStub() {
131
+ return {
132
+ createSocket: () => { throw new Error('dgram.createSocket: UDP not available in browser'); },
133
+ Socket: class { constructor() { throw new Error('dgram.Socket: UDP not available in browser'); } },
134
+ };
135
+ }
136
+
137
+ export function makeWorkerThreadsStub() {
138
+ return {
139
+ Worker: class { constructor() { throw new Error('worker_threads.Worker: not supported — use Web Worker via new Worker(url)'); } },
140
+ isMainThread: true,
141
+ parentPort: null,
142
+ workerData: null,
143
+ threadId: 0,
144
+ MessageChannel: globalThis.MessageChannel,
145
+ MessagePort: globalThis.MessagePort,
146
+ };
147
+ }
@@ -0,0 +1,83 @@
1
+ export function makeWorkerThreads(snap,Buf){
2
+ class Worker{
3
+ constructor(scriptPath,opts={}){
4
+ const src=snap()[scriptPath.replace(/^\.?\//,'')]||scriptPath;
5
+ const preamble=`const workerData=${JSON.stringify(opts.workerData||null)};const parentPort={postMessage:(m,t)=>self.postMessage(m,t),on:(ev,fn)=>{if(ev==='message')self.addEventListener('message',e=>fn(e.data));if(ev==='close')self.addEventListener('close',fn);},close:()=>self.close()};`;
6
+ const blob=new Blob([preamble+'\n'+src],{type:'application/javascript'});
7
+ this._url=URL.createObjectURL(blob);
8
+ this._worker=new globalThis.Worker(this._url,{type:'module'});
9
+ this._handlers={message:[],error:[],exit:[],online:[]};
10
+ this._worker.addEventListener('message',e=>{for(const f of this._handlers.message)f(e.data);});
11
+ this._worker.addEventListener('error',e=>{for(const f of this._handlers.error)f(e);});
12
+ queueMicrotask(()=>{for(const f of this._handlers.online)f();});
13
+ this.threadId=Math.floor(Math.random()*1e9);
14
+ }
15
+ on(ev,fn){(this._handlers[ev]=this._handlers[ev]||[]).push(fn);return this;}
16
+ once(ev,fn){const w=(...a)=>{this.off(ev,w);fn(...a);};return this.on(ev,w);}
17
+ off(ev,fn){this._handlers[ev]=(this._handlers[ev]||[]).filter(x=>x!==fn);return this;}
18
+ postMessage(msg,transfer){this._worker.postMessage(msg,transfer);}
19
+ terminate(){this._worker.terminate();URL.revokeObjectURL(this._url);for(const f of this._handlers.exit)f(0);return Promise.resolve(0);}
20
+ ref(){return this;}
21
+ unref(){return this;}
22
+ }
23
+ return{
24
+ Worker,
25
+ isMainThread:true,
26
+ parentPort:null,
27
+ workerData:null,
28
+ threadId:0,
29
+ MessageChannel:globalThis.MessageChannel,
30
+ MessagePort:globalThis.MessagePort,
31
+ BroadcastChannel:globalThis.BroadcastChannel,
32
+ SHARE_ENV:Symbol('SHARE_ENV'),
33
+ setEnvironmentData(){},
34
+ getEnvironmentData(){},
35
+ markAsUntransferable(){},
36
+ moveMessagePortToContext(){throw new Error('moveMessagePortToContext: not supported');},
37
+ resourceLimits:{maxOldGenerationSizeMb:0,maxYoungGenerationSizeMb:0,codeRangeSizeMb:0,stackSizeMb:0},
38
+ };
39
+ }
40
+
41
+ export function makeChildProcessReal(Buf,streamMod){
42
+ const getWc=()=>globalThis.__webcontainer||window.__webcontainer||null;
43
+ const mkProc=async(cmd,args,opts={})=>{const wc=getWc();if(!wc)throw new Error('child_process: WebContainer not available — spawn requires window.__webcontainer');const p=await wc.spawn(cmd,args||[],{cwd:opts.cwd,env:opts.env});const handlers={exit:[],close:[],error:[]};const stdout=new streamMod.Readable();const stderr=new streamMod.Readable();p.output.pipeTo(new WritableStream({write(chunk){stdout.push(Buf.from(chunk));}}));const exitPromise=p.exit.then(code=>{stdout.push(null);stderr.push(null);for(const f of handlers.exit)f(code);for(const f of handlers.close)f(code);return code;});return{pid:Math.floor(Math.random()*1e6),stdout,stderr,stdin:{write:d=>p.input.getWriter().write(d),end:()=>{}},on(ev,fn){(handlers[ev]=handlers[ev]||[]).push(fn);return this;},kill(){p.kill?.();},exitPromise};};
44
+ return{
45
+ exec(cmd,opts,cb){if(typeof opts==='function'){cb=opts;opts={};}const parts=cmd.split(/\s+/);mkProc(parts[0],parts.slice(1),opts).then(p=>{const chunks=[];p.stdout.on('data',c=>chunks.push(c));p.exitPromise.then(code=>{const out=Buf.concat(chunks).toString();if(cb)code===0?cb(null,out,''):cb(Object.assign(new Error('exit '+code),{code}),out,'');});},e=>cb&&cb(e));},
46
+ spawn(cmd,args,opts){let proc=null;const emitter={on(){return this;},_pending:true};mkProc(cmd,args,opts).then(p=>{proc=p;Object.assign(emitter,p);},e=>{for(const f of emitter._errorHandlers||[])f(e);});return new Proxy(emitter,{get(t,k){return proc?proc[k]:t[k];}});},
47
+ execFile(f,args,opts,cb){if(typeof opts==='function'){cb=opts;opts={};}return this.exec([f,...(args||[])].join(' '),opts,cb);},
48
+ execSync(){throw new Error('child_process.execSync: synchronous subprocess not available in browser');},
49
+ spawnSync(){throw new Error('child_process.spawnSync: synchronous subprocess not available');},
50
+ fork(){throw new Error('child_process.fork: not supported — use Worker');},
51
+ };
52
+ }
53
+
54
+ export function makeRepl(ctx,term,nodeEval){
55
+ const history=[];
56
+ let buffer='';
57
+ let lastResult=undefined;
58
+ const commands={
59
+ '.clear':()=>{buffer='';term.write('\r\n');},
60
+ '.exit':()=>{throw Object.assign(new Error('repl exit'),{__nodeExit:true,code:0});},
61
+ '.help':()=>{term.write('Commands: .clear .exit .help .load .save .editor\r\n');},
62
+ '.load':async path=>{const snap=window.__debug?.idbSnapshot||{};const content=snap[path.replace(/^\/+/,'')];if(!content)throw new Error('file not found: '+path);return nodeEval(content);},
63
+ '.save':path=>{const snap=window.__debug?.idbSnapshot||{};window.__debug.idbSnapshot={...snap,[path.replace(/^\/+/,'')]:history.join('\n')};term.write('saved\r\n');},
64
+ '.editor':()=>{term.write('(type ^D to execute, ^C to cancel)\r\n');buffer='__editor__';},
65
+ };
66
+ const isIncomplete=code=>{let depth=0,inStr=null,inTmpl=false,prev='';for(let i=0;i<code.length;i++){const c=code[i];if(inStr){if(c==='\\'){i++;continue;}if(c===inStr)inStr=null;continue;}if(inTmpl){if(c==='\\'){i++;continue;}if(c==='`')inTmpl=false;else if(c==='$'&&code[i+1]==='{'){depth++;i++;}continue;}if(c==="'"||c==='"')inStr=c;else if(c==='`')inTmpl=true;else if(c==='('||c==='['||c==='{')depth++;else if(c===')'||c===']'||c==='}')depth--;prev=c;}return depth>0||inStr!==null||inTmpl;};
67
+ return{
68
+ commands,
69
+ isIncomplete,
70
+ async eval(line){
71
+ const trimmed=line.trim();
72
+ if(trimmed.startsWith('.')){const[cmd,...rest]=trimmed.split(/\s+/);if(commands[cmd])return commands[cmd](rest.join(' '));}
73
+ buffer=buffer?buffer+'\n'+line:line;
74
+ if(isIncomplete(buffer))return{continuation:true};
75
+ const code=buffer;buffer='';
76
+ history.unshift(code);if(history.length>1000)history.pop();
77
+ const src='const _=arguments[0];'+(code.startsWith('var ')||code.startsWith('let ')||code.startsWith('const ')||code.includes(';')||code.includes('\n')?code:'return ('+code+');');
78
+ try{const fn=new Function(src);const r=fn(lastResult);if(r!==undefined)lastResult=r;return{result:r};}catch(e){return{error:e};}
79
+ },
80
+ getHistory(){return history;},
81
+ get lastResult(){return lastResult;},
82
+ };
83
+ }
@@ -0,0 +1,52 @@
1
+ let smMod=null;let smPromise=null;const consumers=new Map();const CAP=5;
2
+
3
+ async function loadSm(){
4
+ if(!smPromise)smPromise=import('https://esm.sh/source-map-js@1.2.1/es2022/source-map-js.mjs').then(m=>m.default||m);
5
+ return smPromise;
6
+ }
7
+
8
+ export async function preloadSourceMap(){smMod=await loadSm();return smMod;}
9
+
10
+ async function consumerFor(url,snapFn){
11
+ if(consumers.has(url))return consumers.get(url);
12
+ if(consumers.size>50){const first=consumers.keys().next().value;consumers.delete(first);}
13
+ if(!smMod)await loadSm();
14
+ let src='';
15
+ try{
16
+ if(url.startsWith('data:application/json;base64,'))src=atob(url.slice(29));
17
+ else if(url.startsWith('data:application/json,'))src=decodeURIComponent(url.slice(22));
18
+ else if(url.startsWith('http'))src=await (await fetch(url)).text();
19
+ else{const snap=snapFn();const key=url.replace(/^file:\/\/\/?/,'').replace(/^\//,'');src=snap[key]||snap[key+'.map']||'';}
20
+ }catch{return null;}
21
+ if(!src)return null;
22
+ try{const raw=JSON.parse(src);const c=new smMod.SourceMapConsumer(raw);consumers.set(url,c);return c;}catch{return null;}
23
+ }
24
+
25
+ function extractMapUrl(source){
26
+ if(!source)return null;
27
+ const m=source.match(/\/\/[#@]\s*sourceMappingURL=(\S+)/);
28
+ return m?m[1]:null;
29
+ }
30
+
31
+ export function installSourceMapStacks(snapFn){
32
+ if(Error._smHooked)return;Error._smHooked=true;
33
+ const origFormatter=Error.prepareStackTrace;
34
+ Error.prepareStackTrace=(err,frames)=>{
35
+ if(!smMod)return origFormatter?origFormatter(err,frames):err.toString()+'\n'+frames.map(f=>' at '+f.toString()).join('\n');
36
+ let depth=0;
37
+ const mapped=frames.map(f=>{
38
+ if(depth>=CAP)return f;
39
+ const file=f.getFileName?.();if(!file)return f;
40
+ const snap=snapFn();const src=snap[file.replace(/^file:\/\/\/?/,'').replace(/^\//,'')]||'';
41
+ const mapUrl=extractMapUrl(src);if(!mapUrl)return f;
42
+ depth++;
43
+ const c=consumers.get(mapUrl);if(!c)return f;
44
+ const line=f.getLineNumber?.(),col=f.getColumnNumber?.();if(!line)return f;
45
+ try{const orig=c.originalPositionFor({line,column:col||0});if(!orig.source)return f;return{...f,getFileName:()=>orig.source,getLineNumber:()=>orig.line,getColumnNumber:()=>orig.column,getFunctionName:()=>orig.name||f.getFunctionName?.(),toString:()=>` at ${orig.name||'<anonymous>'} (${orig.source}:${orig.line}:${orig.column})`};}catch{return f;}
46
+ });
47
+ return origFormatter?origFormatter(err,mapped):err.toString()+'\n'+mapped.map(f=>' at '+(f.toString?.()||f)).join('\n');
48
+ };
49
+ Promise.resolve().then(async()=>{await loadSm();const snap=snapFn();for(const [key,src] of Object.entries(snap)){const mapUrl=extractMapUrl(src);if(mapUrl)await consumerFor(mapUrl,snapFn);}});
50
+ }
51
+
52
+ export function clearSourceMapCache(){consumers.clear();}