planx 20.5.3 → 20.5.4

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/blob.main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- globalThis.__PLANX_SERVICE_VERSION__="20.5.3";
1
+ globalThis.__PLANX_SERVICE_VERSION__="20.5.4";
2
2
  import { createRequire } from 'module';
3
3
  const require = createRequire(import.meta.url);
4
4
 
@@ -44,7 +44,7 @@ SELECT hash FROM object
44
44
  WHERE hash NOT IN (SELECT h FROM reach) AND created_at < ?`,YB=`
45
45
  SELECT name, hash, accessed_at FROM alias ORDER BY accessed_at ASC LIMIT ?`,HB=`
46
46
  SELECT name, hash, accessed_at FROM alias WHERE accessed_at < ? ORDER BY accessed_at ASC`;var Fg=class{constructor(g){this.db=g}link(g,I){this.run("INSERT OR IGNORE INTO edge (parent, child) VALUES (?, ?)",[g,I])}childrenOf(g){return yI(this.db,"SELECT child FROM edge WHERE parent = ?",[g])}dropEdgesOf(g){this.run("DELETE FROM edge WHERE parent = ? OR child = ?",[g,g])}pin(g,I="",E=0){this.run("INSERT OR REPLACE INTO pin (hash, reason, created) VALUES (?, ?, ?)",[g,I,E])}unpin(g){this.run("DELETE FROM pin WHERE hash = ?",[g])}setAlias(g,I,E=0){this.run("INSERT OR REPLACE INTO alias (name, hash, accessed_at) VALUES (?, ?, ?)",[g,I,E])}resolveAlias(g){let I=this.db.selectValue("SELECT hash FROM alias WHERE name = ?",[g]);return I==null?null:String(I)}touchAlias(g,I){this.run("UPDATE alias SET accessed_at = ? WHERE name = ?",[I,g])}dropAlias(g){this.run("DELETE FROM alias WHERE name = ?",[g])}oldestAliases(g){return this.selectAliasRows(YB,[g])}expiredAliases(g){return this.selectAliasRows(HB,[g])}aliasCount(){return Number(this.db.selectValue("SELECT COUNT(*) FROM alias")??0)}selectAliasRows(g,I){let E=[];return this.db.exec({sql:g,bind:I,rowMode:"array",callback:t=>{E.push({name:String(t[0]),hash:String(t[1]),accessedAt:Number(t[2])})}}),E}run(g,I){this.db.exec({sql:g,bind:I})}};var yo="ledger.db",fB="INSERT INTO object (hash, size, accessed_at, created_at) VALUES (?, ?, ?, ?) ON CONFLICT(hash) DO UPDATE SET size = excluded.size, accessed_at = excluded.accessed_at",Mo=256,Rg=class Q extends Fg{constructor(I,E){super(hB(I,Go(E,yo)));this.dir=E;this.batchDepth=0;this.pending=new Map;this.seq=Number(this.db.selectValue("SELECT COALESCE(MAX(accessed_at), 0) FROM object")??0)}static async create(I){return ro(I,{recursive:!0}),new Q(await sB("planx-blob"),I)}note(I,E,t=0){this.pending.delete(I),this.seq+=1,this.run(fB,[I,E,this.seq,t])}markAccessed(I,E){this.pending.set(I,E),this.pending.size>=Mo&&this.flush()}flush(){if(this.pending.size===0)return;let I=[...this.pending];this.pending.clear();let E=this.batchDepth===0;E&&this.db.exec("BEGIN");try{for(let[t,a]of I)this.seq+=1,this.run(fB,[t,a,this.seq,0]);E&&this.db.exec("COMMIT")}catch(t){throw E&&this.db.exec("ROLLBACK"),t}}async batch(I){this.batchDepth===0&&this.db.exec("BEGIN"),this.batchDepth+=1;try{let E=await I();return this.batchDepth-=1,this.batchDepth===0&&this.db.exec("COMMIT"),E}catch(E){throw this.batchDepth-=1,this.batchDepth===0&&this.db.exec("ROLLBACK"),E}}inTransaction(){return this.batchDepth>0}reachable(){return this.flush(),new Set(yI(this.db,JB))}oldestEvictable(I){this.flush();let E=this.db.selectValue(KB,[I]);return E==null?null:String(E)}purgeNonContentAddressed(){return UB(this.db)}collectable(I){return this.flush(),yI(this.db,lB,[I])}forget(I){this.run("DELETE FROM object WHERE hash = ?",[I])}has(I){return this.flush(),this.db.selectValue("SELECT 1 FROM object WHERE hash = ?",[I])!==void 0}sizeOf(I){return this.flush(),Number(this.db.selectValue("SELECT size FROM object WHERE hash = ?",[I])??0)}totalBytes(){return this.flush(),Number(this.db.selectValue("SELECT COALESCE(SUM(size), 0) FROM object")??0)}size(){return this.flush(),Number(this.db.selectValue("SELECT COUNT(*) FROM object")??0)}async rebuildFromDisk(){await kB(this.db,this.dir,()=>this.seq+=1)}close(){try{this.flush()}catch{}try{this.db.close()}catch{}}};import{rm as dB}from"node:fs/promises";import{join as qB}from"node:path";async function uB(Q,g){let I=new Set(Q.purgeNonContentAddressed());for(let E of await LB(g))I.add(E),await dB(qB(g,E),{force:!0});for(let E of I)E.includes("/")||await dB(qB(g,E.slice(0,2),E),{force:!0});I.size>0&&console.error(`[planx-blob] purged ${I.size} legacy (non content-addressed) objects`)}import{readdir as no,rm as So,stat as Lo}from"node:fs/promises";import{join as ko}from"node:path";var xB=3600*1e3;async function pB(Q,g){let I;try{I=await no(Q,{recursive:!0})}catch{return[]}let E=Date.now()-g,t=[];for(let a of I){if(!a.endsWith(".wip"))continue;let U=ko(Q,a);try{let r=await Lo(U);if(!r.isFile()||r.mtimeMs>=E)continue;await So(U,{force:!0}),t.push(U)}catch{continue}}return t}var ag=class{constructor(g){this.options=g;this.ledger=null;this.ready=null;this.closed=!1}async ensureReady(){if(this.closed)throw new Error("blob store is closed");let g=this.ready??=this.openLedger();try{return await g}catch(I){throw this.ready===g&&(this.ready=null),I}}async openLedger(){let g=await Rg.create(this.options.dir);this.ledger=g,await pB(this.options.dir,this.options.wipGraceMs??xB);let I=g.size()===0;return I&&await g.rebuildFromDisk(),await uB(g,this.options.dir),I||await Dg(g,E=>this.pathOf(E),this.options.gcGraceMs),g}async totalBytes(){return(await this.ensureReady()).totalBytes()}close(){this.closed=!0;let g=this.ready;if(!g)return void this.ledger?.close();g.then(I=>I.close()).catch(()=>{})}pathOf(g){return Jo(this.options.dir,jQ(g))}};var cg=class extends ag{async read(g){if(!tI(g))return null;let I=await this.ensureReady();try{let E=await Yo(this.pathOf(g));return I.markAccessed(g,E.length),E}catch{return null}}async has(g){if(!tI(g))return!1;let I=await this.ensureReady();try{let E=await bB(this.pathOf(g));return I.markAccessed(g,E.size),!0}catch{return I.forget(g),!1}}async write(g,I){if(!tI(g))throw new Error(`invalid blob key: ${g}`);let E=await this.ensureReady(),t=this.pathOf(g),a=await vQ(t);if(a&&(!Buffer.isBuffer(I)||a.size===I.length)){E.markAccessed(g,a.size),Buffer.isBuffer(I)||await I.cancel();return}a&&console.warn(`[planx-blob] size-divergent rewrite, replacing ${g} (${a.size} -> ${I.length})`),await lo(uo(t),{recursive:!0});let U=`${t}.${xo()}.wip`;Buffer.isBuffer(I)?await qo(U,I):await bo(po.fromWeb(I),Ko(U)),await Ho(U,t),E.note(g,(await bB(t)).size,Date.now())}async discard(g){if(!tI(g))return;(await this.ensureReady()).forget(g),await fo(this.pathOf(g),{force:!0})}async batch(g){return(await this.ensureReady()).batch(g)}async setAlias(g,I,E=Date.now()){(await this.ensureReady()).setAlias(g,I,E)}async resolveAlias(g){return(await this.ensureReady()).resolveAlias(g)}async touchAlias(g,I){(await this.ensureReady()).touchAlias(g,I)}async dropAlias(g){(await this.ensureReady()).dropAlias(g)}async oldestAliases(g){return(await this.ensureReady()).oldestAliases(g)}async expiredAliases(g){return(await this.ensureReady()).expiredAliases(g)}async aliasCount(){return(await this.ensureReady()).aliasCount()}async reachable(){return(await this.ensureReady()).reachable()}async dropTree(g,I){return _Q(await this.ensureReady(),E=>this.pathOf(E),g,I)}async treeSizeEstimate(g){return zQ(await this.ensureReady(),g)}async pin(g,I=""){(await this.ensureReady()).pin(g,I,Date.now())}async unpin(g){(await this.ensureReady()).unpin(g)}async link(g,I){(await this.ensureReady()).link(g,I)}async childrenOf(g){return(await this.ensureReady()).childrenOf(g)}async gc(g=Og){return Dg(await this.ensureReady(),I=>this.pathOf(I),g)}};var uI=class{constructor(g={}){this.options=g;this.localHit=0;this.relayHit=0;this.miss=0;this.put=0;this.replicaFailures=0;this.lastReplicaFailure=null;this.retainRuns=0;this.expiredAliases=0;this.evictedAliases=0;this.evictedBytes=0;this.samples=[]}recordLocalHit(g){this.localHit+=1,this.addSample(g)}recordRelayHit(g){this.relayHit+=1,this.addSample(g)}recordMiss(g){this.miss+=1,this.addSample(g)}recordPut(g){this.put+=1,this.addSample(g)}recordReplicaFailure(g,I){this.lastReplicaFailure={peer:g,reason:I},this.replicaFailures+=1}recordRetain(g){this.retainRuns+=1,this.expiredAliases+=g.expiredAliases,this.evictedAliases+=g.evictedAliases,this.evictedBytes+=g.freedBytes}sampleCount(){return this.samples.length}snapshot(){let g=this.localHit+this.relayHit+this.miss,I=[...this.samples].sort((E,t)=>E-t);return{retainRuns:this.retainRuns,expiredAliases:this.expiredAliases,evictedAliases:this.evictedAliases,evictedBytes:this.evictedBytes,localHit:this.localHit,relayHit:this.relayHit,miss:this.miss,put:this.put,hitRate:g===0?0:(this.localHit+this.relayHit)/g,replicaFailures:this.replicaFailures,lastReplicaFailure:this.lastReplicaFailure,getLatencyMs:{p50:VB(I,.5),p99:VB(I,.99)}}}addSample(g){let I=this.options.maxSamples??1024;this.samples.push(g),this.samples.length>I&&this.samples.shift()}};function VB(Q,g){if(Q.length===0)return 0;let I=Math.min(Q.length-1,Math.ceil(g*Q.length)-1);return Q[Math.max(0,I)]}var _g={maxBytes:10737418240,highWaterRatio:.9,lowWaterRatio:.8,aliasTtlMs:12096e5,retainIntervalMs:6e5,wipGraceMs:36e5,evictBatch:64};function _I(Q){return{high:Math.floor(Q.maxBytes*Q.highWaterRatio),low:Math.floor(Q.maxBytes*Q.lowWaterRatio)}}var Vo=1024*1024,hg=class{constructor(g,I,E,t={}){this.store=g;this.policy=I;this.metrics=E;this.options=t;this.inFlight=null;this.lastRetainAt=null;this.lastRetain=null}retain(){return this.inFlight??=this.run().finally(()=>{this.inFlight=null}),this.inFlight}async afterPut(){let{high:g}=_I(this.policy);return await this.store.totalBytes()<=g?null:this.retain()}async status(){return{status:this.inFlight?"retaining":"ok",totalBytes:await this.store.totalBytes(),maxBytes:this.policy.maxBytes,highWaterBytes:_I(this.policy).high,aliases:await this.store.aliasCount(),lastRetainAt:this.lastRetainAt,lastRetain:this.lastRetain}}async run(){let g=this.now(),I=await this.expire(g),{evicted:E,freed:t}=await this.evictToLowWater(),a=await this.store.totalBytes()>_I(this.policy).high,U=I.count+E>0||a?(await this.store.gc()).length:0,r={expiredAliases:I.count,evictedAliases:E,freedBytes:I.freed+t,collected:U,tookMs:this.now()-g};return this.lastRetainAt=this.now(),this.lastRetain=r,this.metrics.recordRetain(r),this.report(r),r}async expire(g){let I=await this.store.expiredAliases(g-this.policy.aliasTtlMs);for(let a of I)await this.store.dropAlias(a.name);if(I.length===0)return{count:0,freed:0};let E=await this.store.reachable(),t=0;for(let a of I)t+=await this.store.dropTree(a.hash,E);return{count:I.length,freed:t}}async evictToLowWater(){let{high:g,low:I}=_I(this.policy),E=0,t=0,a=await this.store.totalBytes();for(;a>g;){let U=await this.selectVictims(a,I);if(U.length===0)break;for(let Y of U)await this.store.dropAlias(Y.name);let r=await this.store.reachable();for(let Y of U)t+=await this.store.dropTree(Y.hash,r),E+=1;a=await this.store.totalBytes()}return{evicted:E,freed:t}}async selectVictims(g,I){let E=await this.store.oldestAliases(this.policy.evictBatch),t=[],a=g;for(let U of E)if(t.push(U),a-=await this.store.treeSizeEstimate(U.hash),a<=I)break;return t}report(g){if(g.expiredAliases+g.evictedAliases===0&&g.tookMs<=1e3)return;let E=`${(g.freedBytes/Vo).toFixed(1)} MB freed`;this.log(`[planx-blob] retain: expired=${g.expiredAliases} evicted=${g.evictedAliases} aliases, ${E}, collected=${g.collected}, took=${g.tookMs} ms`)}log(g){(this.options.log??console.error)(g)}now(){return(this.options.now??(()=>Date.now()))()}};function TB(Q,g){let I=setInterval(()=>{Q.retain().catch(E=>{Q.log(`[planx-blob] retain failed: ${String(E)}`)})},g);return I.unref?.(),()=>clearInterval(I)}var Ug=class{constructor(g){this.options=g}async get(g,I,E={}){let t=await this.request(g,I,"GET",void 0,E);return t instanceof Error?null:!t.ok||!t.body?(await t.body?.cancel().catch(()=>{}),null):t.body}async head(g,I,E={}){let t=await this.request(g,I,"HEAD",void 0,E);return t instanceof Error?!1:(await t.body?.cancel().catch(()=>{}),t.ok)}async put(g,I,E,t={}){let a=await this.request(g,I,"PUT",E,t);return a instanceof Error?{ok:!1,reason:`error ${a.name}: ${a.message}`}:(await a.body?.cancel().catch(()=>{}),a.ok?{ok:!0}:{ok:!1,reason:`status ${a.status}`})}async have(g,I){try{let E=await fetch(`${g.baseUrl}/blob/have`,{method:"POST",headers:{authorization:`Bearer ${this.options.token}`,"content-type":"application/json"},body:JSON.stringify(I),signal:AbortSignal.timeout(this.options.timeoutMs??3e3)});if(!E.ok)return null;let t=await E.json();return Array.isArray(t.missing)?t.missing:null}catch{return null}}async getAlias(g,I){let E=await this.aliasRequest(g,I,"GET");return E?.ok?(await E.text()).trim()||null:(await E?.body?.cancel(),null)}async putAlias(g,I,E){let t=await this.aliasRequest(g,I,"PUT",E);return await t?.body?.cancel(),t?.ok??!1}async aliasRequest(g,I,E,t){try{return await fetch(`${g.baseUrl}/blob/aliases/${encodeURIComponent(I)}`,{method:E,headers:{authorization:`Bearer ${this.options.token}`},body:t,signal:AbortSignal.timeout(this.options.timeoutMs??3e3)})}catch{return null}}async request(g,I,E,t,a={}){let U=AbortSignal.timeout(this.options.timeoutMs??3e3),r=a.signal?To([U,a.signal]):U;try{return await fetch(`${g.baseUrl}/blob/objects/${I}?noRelay=1&raw=1`,{method:E,headers:{authorization:`Bearer ${this.options.token}`},body:t?new Uint8Array(t):void 0,signal:r})}catch(Y){return Y instanceof Error?Y:new Error(String(Y))}}};function To(Q){let g=AbortSignal.any;if(typeof g=="function")return g(Q);let I=new AbortController;for(let E of Q){if(E.aborted){I.abort(E.reason);break}E.addEventListener("abort",()=>I.abort(E.reason),{once:!0})}return I.signal}import{createWriteStream as ZB,createReadStream as jo}from"node:fs";import{rm as vo,stat as _o}from"node:fs/promises";import{tmpdir as zo}from"node:os";import{join as $o}from"node:path";import{randomUUID as AD}from"node:crypto";import{Readable as PB}from"node:stream";import{pipeline as OB}from"node:stream/promises";var mB=mo();function mo(){let Q=new Uint32Array(256),g=2654435769;for(let I=0;I<256;I+=1)g^=g<<13,g>>>=0,g^=g>>>17,g^=g<<5,g>>>=0,Q[I]=g;return Q}var Wo=16*1024,Zo=64*1024,Po=256*1024;function WB(Q,g={}){let I=g.minSize??Wo,E=g.avgSize??Zo,t=g.maxSize??Po,a=Xo(E),U=[],r=0;for(;r<Q.length;){let Y=Oo(Q,r,I,t,a);U.push(Q.subarray(r,Y)),r=Y}return U}function Oo(Q,g,I,E,t){let a=Math.min(g+E,Q.length);if(a-g<=I)return a;let U=0;for(let r=g+I;r<a;r+=1)if(U=(U<<1>>>0)+mB[Q[r]],U>>>=0,(U&t)===0)return r+1;return a}function Xo(Q){return 2**Math.max(1,Math.round(Math.log2(Math.max(2,Q))))-1>>>0}var ID=8*1024*1024;async function XB(Q){let g=$o(zo(),`planx-blob-spool-${AD()}`);Buffer.isBuffer(Q)?await OB(PB.from(Q),ZB(g)):await OB(PB.fromWeb(Q),ZB(g));let I=await _o(g);return{path:g,size:I.size,discard:()=>vo(g,{force:!0})}}async function*jB(Q){let g=Buffer.alloc(0);for await(let I of jo(Q,{highWaterMark:ID})){let E=I;g=g.length===0?E:Buffer.concat([g,E]);let t=WB(g);for(let a of t.slice(0,-1))yield a;g=t.length>0?Buffer.from(t[t.length-1]):Buffer.alloc(0)}g.length>0&&(yield g)}var gD=64,QD=256,BD=1024,zg=`
47
- `,vB=" ";function CD(Q){let g=Q.map(I=>`${I.hash}${vB}${I.subtreeBytes}`).join(zg);return Buffer.from(`v2${zg}${g}`,"utf-8")}function Ng(Q){let g=Q.toString("utf-8").split(zg);if(g[0]!=="v2")throw new Error(`unsupported manifest version: ${g[0]}`);return g.slice(1).filter(I=>I.length>0).map(I=>{let[E,t]=I.split(vB);return{hash:E,subtreeBytes:Number(t)}})}function _B(Q,g={}){let I=[],E=Q.map(a=>({hash:a.hash,subtreeBytes:a.size})),t=E.reduce((a,U)=>a+U.subtreeBytes,0);if(E.length===1)return{rootHash:E[0].hash,totalBytes:t,objects:I};for(;;){let U=ED(E,g).map(r=>{let Y=CD(r),j=OI(1,Y);return I.push({hash:j,type:1,payload:Y}),{hash:j,subtreeBytes:r.reduce((BA,QA)=>BA+QA.subtreeBytes,0)}});if(U.length===1)return{rootHash:U[0].hash,totalBytes:t,objects:I};E=U}}function ED(Q,g){let I=g.minEntries??gD,E=g.avgEntries??QD,t=g.maxEntries??BD;if(Q.length<=t)return[Q];let a=(1<<Math.round(Math.log2(Math.max(2,E))))-1,U=[],r=0;for(;r<Q.length;){let Y=Math.min(r+t,Q.length);for(let j=r+I;j<Y;j+=1)if((iD(Q[j].hash)&a)===0){Y=j+1;break}U.push(Q.slice(r,Y)),r=Y}return U}function iD(Q){return parseInt(Q.slice(-8),16)>>>0}async function zB(Q,g){return Q.batch(async()=>{let I=[];for await(let t of jB(g)){let a=OI(0,t);await Q.write(a,t),I.push({hash:a,size:t.length})}let E=_B(I);for(let t of E.objects){await Q.write(t.hash,t.payload);for(let a of Ng(t.payload))await Q.link(t.hash,a.hash)}return E.rootHash})}function oD(Q,g){return XI(Q,1,g)}function MI(Q,g){if(!oD(Q,g))return null;try{return Ng(g)}catch{throw console.error(`[planx-blob] malformed manifest, rejecting ${Q}`),new Error(`malformed manifest: ${Q}`)}}async function $B(Q,g){let I=await g(Q);if(!I)return null;let E=MI(Q,I);return E?E.reduce((t,a)=>t+a.subtreeBytes,0):I.length}async function*AQ(Q,g){let I=await g(Q);if(!I)throw new Error(`missing object: ${Q}`);let E=MI(Q,I);if(!E){yield I;return}for(let t of E)yield*AQ(t.hash,g)}async function AC(Q,g,I){let E;try{E=MI(g,I)}catch{return}if(E)for(let t of E)await Q.link(g,t.hash)}async function IC(Q,g){let I=[Q];for(;I.length>0;){let E=[];for(let a of I)await g.has(a)||E.push(a);if(E.length>0&&!await g.fetchMissing(E))return!1;let t=[];for(let a of I){let U=await g.read(a);if(!U)return!1;try{t.push(...(MI(a,U)??[]).map(r=>r.hash))}catch{return!1}}I=t}return!0}import{createHash as DD}from"node:crypto";function nI(Q,g){return Q.map(I=>({peer:I,score:sD(I.id,g)})).sort((I,E)=>I.score<E.score?1:I.score>E.score?-1:0).map(I=>I.peer)}function sD(Q,g){return DD("sha256").update(`${Q}:${g}`).digest("hex")}function gC(Q,g){let I=new Map;for(let t of g.keys())I.set(t,[]);let E=[];for(let t of Q){let a=[...g.entries()].filter(([,U])=>U.has(t));if(a.length===0){E.push(t);continue}a.sort(([U],[r])=>(I.get(U)?.length??0)-(I.get(r)?.length??0)),I.get(a[0][0])?.push(t)}return{queues:I,unclaimed:E}}async function QC(Q,g){if(g.length===0)return!0;let I=await wD(Q,g),{queues:E,unclaimed:t}=gC(g,I),a={ownedBy:I,queues:E,started:new Set,done:new Set,tried:new Map,retry:[]};await Promise.all(Q.peers.map(U=>eD(Q,a,U)));for(let U of[...t,...g.filter(r=>!a.done.has(r))])if(!a.done.has(U)){if(!await Q.fallback(U))return!1;a.done.add(U)}return!0}async function wD(Q,g){let I=new Map;return await Promise.all(Q.peers.map(async E=>{let t=await Q.have(E,g);if(t===null)return;let a=new Set(t);I.set(E.id,new Set(g.filter(U=>!a.has(U))))})),I}async function eD(Q,g,I){for(;;){let E=tD(g,I.id);if(E===null)return;g.started.add(E),CC(g,E).add(I.id),!g.done.has(E)&&(await Q.fetchFrom(I,E)?g.done.add(E):FD(g,E)&&g.retry.push(E))}}function tD(Q,g){let I=Q.queues.get(g)??[];for(;I.length>0;){let t=I.shift();if(!Q.started.has(t))return t}let E=Q.retry.findIndex(t=>!Q.done.has(t)&&BC(Q,t,g));if(E>=0)return Q.retry.splice(E,1)[0];for(let[t,a]of Q.queues){if(t===g)continue;let U=a.findIndex(r=>!Q.started.has(r)&&Q.ownedBy.get(g)?.has(r));if(U>=0)return a.splice(U,1)[0]}return null}function BC(Q,g,I){return(Q.ownedBy.get(I)?.has(g)??!1)&&!CC(Q,g).has(I)}function FD(Q,g){return[...Q.ownedBy.keys()].some(I=>BC(Q,g,I))}function CC(Q,g){let I=Q.tried.get(g);return I||Q.tried.set(g,I=new Set),I}async function IQ(Q,g=()=>{}){return Q.length===0?null:new Promise(I=>{let E=Q.length,t=!1,a=()=>{E-=1,E===0&&!t&&(t=!0,I(null))};for(let U of Q)U.then(r=>{if(r===null)return a();if(t)return g(r);t=!0,I(r)},a)})}async function EC(Q,g,I){let{client:E,hash:t}=I,a=new Map,U=BA=>{let QA=new AbortController;return a.set(BA.id,QA),QA.signal},r=BA=>QA=>QA?{peer:BA,stream:QA}:null,Y=[...Q.slice(0,g).map(BA=>E.get(BA,t,{signal:U(BA)}).then(r(BA)).catch(()=>null)),...Q.slice(g).map(BA=>{let QA=U(BA);return E.head(BA,t,{signal:QA}).then(DA=>DA?E.get(BA,t,{signal:QA}):null).then(r(BA)).catch(()=>null)})],j=await IQ(Y,BA=>{BA.stream.cancel().catch(()=>{})});for(let[BA,QA]of a)BA!==j?.peer.id&&QA.abort();return j?.stream??null}function iC(Q,g){return async I=>{let E=await oC(Q,I);return E||(g?(Q.onRemote(),sC(Q,I)):null)}}async function oC(Q,g){let I=await Q.store.read(g);return I?Q.accepts(g,I)?I:(console.warn(`[planx-blob] local chunk failed verification, discarding ${g}`),await Q.store.discard(g),null):null}function DC(Q,g){return{has:I=>Q.store.has(I),read:I=>oC(Q,I),fetchMissing:async I=>g?(Q.onRemote(),QC({peers:await Q.livePeers(),have:(E,t)=>Q.client.have(E,t),fetchFrom:(E,t)=>RD(Q,E,t),fallback:async E=>await sC(Q,E)!==null},I)):!1}}async function sC(Q,g){let I=nI(await Q.livePeers(),g),E=await EC(I,Q.replication,{client:Q.client,hash:g});return E?wC(Q,g,E):null}async function RD(Q,g,I){let E=await Q.client.get(g,I);return E?await wC(Q,I,E)!==null:!1}async function wC(Q,g,I){let E;try{E=Buffer.from(await new Response(I).arrayBuffer())}catch{return null}return Q.accepts(g,E)?(await Q.store.write(g,E),await AC(Q.store,g,E),E):null}function eC(Q=g=>console.error(g)){let g=new Set;return(I,E)=>{let t=`${I.id} ${E}`;g.has(t)||(g.size>=64&&g.clear(),g.add(t),Q(`[planx-blob] replica put failed peer=${I.id} reason=${E}`))}}async function gQ(Q,g){let I=await Q.store.read(g);if(!I)return;await aD(Q,g,I);let E;try{E=MI(g,I)}catch{return}if(E)for(let t of E)await gQ(Q,t.hash)}async function aD(Q,g,I){let t=nI(await Q.livePeers(),g).slice(0,Q.replication);(await Promise.all(t.map(U=>Q.client.put(U,g,I).catch(r=>({ok:!1,reason:`error ${String(r)}`}))))).forEach((U,r)=>{U.ok||Q.onFailure(t[r],U.reason)})}function tC(Q){return new ReadableStream({async pull(g){try{let I=await Q.next();if(I.done)return g.close();g.enqueue(new Uint8Array(I.value))}catch(I){g.error(I)}},cancel:()=>{Q.return(void 0)}})}async function FC(Q,g,I){let E=nI(await Q.livePeers(),g);await Promise.all(E.slice(0,Q.replication).map(t=>Q.client.putAlias(t,g,I)))}async function RC(Q,g){if(eI(g))return null;let I=nI(await Q.livePeers(),g);return IQ(I.map(async E=>{let t=await Q.client.getAlias(E,g);return t&&eI(t)?t:null}))}var cD=2,Gg=class{constructor(g,I,E,t={}){this.store=g;this.peers=I;this.client=E;this.options=t;this.reportReplicaFailure=eC();this.metrics=t.metrics??new uI}async get(g,I){let E=this.now(),t=await this.rootOf(g,I.relay),a={value:!1},U={store:this.store,client:this.client,replication:this.replication(),livePeers:()=>this.peers.livePeers(),accepts:(j,BA)=>this.accepts(j,BA),onRemote:()=>{a.value=!0}},r=iC(U,I.relay),Y;try{Y=await $B(t,r)}catch{Y=null}return Y===null||!await IC(t,DC(U,I.relay))?(this.metrics.recordMiss(this.now()-E),null):(a.value?this.metrics.recordRelayHit(this.now()-E):this.metrics.recordLocalHit(this.now()-E),{size:Y,stream:tC(AQ(t,r))})}async rootOf(g,I){let E=await this.store.resolveAlias(g);if(E)return await this.store.touchAlias(g,this.now()),E;if(!I)return g;let t=await RC(await this.aliasDeps(),g);return t?(await this.store.setAlias(g,t),t):g}async aliasDeps(){return{client:this.client,livePeers:()=>this.peers.livePeers(),replication:this.replication()}}now(){return(this.options.now??(()=>Date.now()))()}accepts(g,I){return XI(g,0,I)||XI(g,1,I)?!0:(console.error(`[planx-blob] hash mismatch, rejecting ${g}`),!1)}async put(g){let I=this.now(),E=await XB(g),t;try{t=await zB(this.store,E.path),gQ(this.replicationDeps(),t).catch(()=>{})}finally{await E.discard()}return this.metrics.recordPut(this.now()-I),await this.options.retention?.afterPut(),t}async bind(g,I){await this.store.setAlias(g,I,this.now()),this.aliasDeps().then(E=>FC(E,g,I)).catch(()=>{})}replicationDeps(){return{store:this.store,client:this.client,livePeers:()=>this.peers.livePeers(),replication:this.replication(),onFailure:(g,I)=>{this.metrics.recordReplicaFailure(g.id,I),this.reportReplicaFailure(g,I)}}}replication(){return this.options.replication??cD}};var QQ=(Q,g,I)=>(E,t)=>{let a=-1;return U(0);async function U(r){if(r<=a)throw new Error("next() called multiple times");a=r;let Y,j=!1,BA;if(Q[r]?(BA=Q[r][0][0],E.req.routeIndex=r):BA=r===Q.length&&t||void 0,BA)try{Y=await BA(E,()=>U(r+1))}catch(QA){if(QA instanceof Error&&g)E.error=QA,Y=await g(QA,E),j=!0;else throw QA}else E.finalized===!1&&I&&(Y=await I(E));return Y&&(E.finalized===!1||j)&&(E.res=Y),E}};var aC=Symbol();var cC=async(Q,g=Object.create(null))=>{let{all:I=!1,dot:E=!1}=g,a=(Q instanceof rg?Q.raw.headers:Q.headers).get("Content-Type");return a?.startsWith("multipart/form-data")||a?.startsWith("application/x-www-form-urlencoded")?hD(Q,{all:I,dot:E}):{}};async function hD(Q,g){let I=await Q.formData();return I?UD(I,g):{}}function UD(Q,g){let I=Object.create(null);return Q.forEach((E,t)=>{g.all||t.endsWith("[]")?ND(I,t,E):I[t]=E}),g.dot&&Object.entries(I).forEach(([E,t])=>{E.includes(".")&&(GD(I,E,t),delete I[E])}),I}var ND=(Q,g,I)=>{Q[g]!==void 0?Array.isArray(Q[g])?Q[g].push(I):Q[g]=[Q[g],I]:g.endsWith("[]")?Q[g]=[I]:Q[g]=I},GD=(Q,g,I)=>{let E=Q,t=g.split(".");t.forEach((a,U)=>{U===t.length-1?E[a]=I:((!E[a]||typeof E[a]!="object"||Array.isArray(E[a])||E[a]instanceof File)&&(E[a]=Object.create(null)),E=E[a])})};var CQ=Q=>{let g=Q.split("/");return g[0]===""&&g.shift(),g},hC=Q=>{let{groups:g,path:I}=rD(Q),E=CQ(I);return yD(E,g)},rD=Q=>{let g=[];return Q=Q.replace(/\{[^}]+\}/g,(I,E)=>{let t=`@${E}`;return g.push([t,I]),t}),{groups:g,path:Q}},yD=(Q,g)=>{for(let I=g.length-1;I>=0;I--){let[E]=g[I];for(let t=Q.length-1;t>=0;t--)if(Q[t].includes(E)){Q[t]=Q[t].replace(E,g[I][1]);break}}return Q},yg={},UC=(Q,g)=>{if(Q==="*")return"*";let I=Q.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(I){let E=`${Q}#${g}`;return yg[E]||(I[2]?yg[E]=g&&g[0]!==":"&&g[0]!=="*"?[E,I[1],new RegExp(`^${I[2]}(?=/${g})`)]:[Q,I[1],new RegExp(`^${I[2]}$`)]:yg[E]=[Q,I[1],!0]),yg[E]}return null},Mg=(Q,g)=>{try{return g(Q)}catch{return Q.replace(/(?:%[0-9A-Fa-f]{2})+/g,I=>{try{return g(I)}catch{return I}})}},MD=Q=>Mg(Q,decodeURI),EQ=Q=>{let g=Q.url,I=g.indexOf("/",g.indexOf(":")+4),E=I;for(;E<g.length;E++){let t=g.charCodeAt(E);if(t===37){let a=g.indexOf("?",E),U=g.slice(I,a===-1?void 0:a);return MD(U.includes("%25")?U.replace(/%25/g,"%2525"):U)}else if(t===63)break}return g.slice(I,E)};var NC=Q=>{let g=EQ(Q);return g.length>1&&g.at(-1)==="/"?g.slice(0,-1):g},SI=(Q,g,...I)=>(I.length&&(g=SI(g,...I)),`${Q?.[0]==="/"?"":"/"}${Q}${g==="/"?"":`${Q?.at(-1)==="/"?"":"/"}${g?.[0]==="/"?g.slice(1):g}`}`),ng=Q=>{if(Q.charCodeAt(Q.length-1)!==63||!Q.includes(":"))return null;let g=Q.split("/"),I=[],E="";return g.forEach(t=>{if(t!==""&&!/\:/.test(t))E+="/"+t;else if(/\:/.test(t))if(/\?/.test(t)){I.length===0&&E===""?I.push("/"):I.push(E);let a=t.replace("?","");E+="/"+a,I.push(E)}else E+="/"+t}),I.filter((t,a,U)=>U.indexOf(t)===a)},BQ=Q=>/[%+]/.test(Q)?(Q.indexOf("+")!==-1&&(Q=Q.replace(/\+/g," ")),Q.indexOf("%")!==-1?Mg(Q,iQ):Q):Q,GC=(Q,g,I)=>{let E;if(!I&&g&&!/[%+]/.test(g)){let U=Q.indexOf(`?${g}`,8);for(U===-1&&(U=Q.indexOf(`&${g}`,8));U!==-1;){let r=Q.charCodeAt(U+g.length+1);if(r===61){let Y=U+g.length+2,j=Q.indexOf("&",Y);return BQ(Q.slice(Y,j===-1?void 0:j))}else if(r==38||isNaN(r))return"";U=Q.indexOf(`&${g}`,U+1)}if(E=/[%+]/.test(Q),!E)return}let t={};E??=/[%+]/.test(Q);let a=Q.indexOf("?",8);for(;a!==-1;){let U=Q.indexOf("&",a+1),r=Q.indexOf("=",a);r>U&&U!==-1&&(r=-1);let Y=Q.slice(a+1,r===-1?U===-1?void 0:U:r);if(E&&(Y=BQ(Y)),a=U,Y==="")continue;let j;r===-1?j="":(j=Q.slice(r+1,U===-1?void 0:U),E&&(j=BQ(j))),I?(t[Y]&&Array.isArray(t[Y])||(t[Y]=[]),t[Y].push(j)):t[Y]??=j}return g?t[g]:t},rC=GC,yC=(Q,g)=>GC(Q,g,!0),iQ=decodeURIComponent;var MC=Q=>Mg(Q,iQ),rg=class{raw;#I;#A;routeIndex=0;path;bodyCache={};constructor(Q,g="/",I=[[]]){this.raw=Q,this.path=g,this.#A=I,this.#I={}}param(Q){return Q?this.#g(Q):this.#C()}#g(Q){let g=this.#A[0][this.routeIndex][1][Q],I=this.#B(g);return I&&/\%/.test(I)?MC(I):I}#C(){let Q={},g=Object.keys(this.#A[0][this.routeIndex][1]);for(let I of g){let E=this.#B(this.#A[0][this.routeIndex][1][I]);E!==void 0&&(Q[I]=/\%/.test(E)?MC(E):E)}return Q}#B(Q){return this.#A[1]?this.#A[1][Q]:Q}query(Q){return rC(this.url,Q)}queries(Q){return yC(this.url,Q)}header(Q){if(Q)return this.raw.headers.get(Q)??void 0;let g={};return this.raw.headers.forEach((I,E)=>{g[E]=I}),g}async parseBody(Q){return this.bodyCache.parsedBody??=await cC(this,Q)}#Q=Q=>{let{bodyCache:g,raw:I}=this,E=g[Q];if(E)return E;let t=Object.keys(g)[0];return t?g[t].then(a=>(t==="json"&&(a=JSON.stringify(a)),new Response(a)[Q]())):g[Q]=I[Q]()};json(){return this.#Q("text").then(Q=>JSON.parse(Q))}text(){return this.#Q("text")}arrayBuffer(){return this.#Q("arrayBuffer")}blob(){return this.#Q("blob")}formData(){return this.#Q("formData")}addValidatedData(Q,g){this.#I[Q]=g}valid(Q){return this.#I[Q]}get url(){return this.raw.url}get method(){return this.raw.method}get[aC](){return this.#A}get matchedRoutes(){return this.#A[0].map(([[,Q]])=>Q)}get routePath(){return this.#A[0].map(([[,Q]])=>Q)[this.routeIndex].path}};var nC={Stringify:1,BeforeStream:2,Stream:3},nD=(Q,g)=>{let I=new String(Q);return I.isEscaped=!0,I.callbacks=g,I};var oQ=async(Q,g,I,E,t)=>{typeof Q=="object"&&!(Q instanceof String)&&(Q instanceof Promise||(Q=Q.toString()),Q instanceof Promise&&(Q=await Q));let a=Q.callbacks;if(!a?.length)return Promise.resolve(Q);t?t[0]+=Q:t=[Q];let U=Promise.all(a.map(r=>r({phase:g,buffer:t,context:E}))).then(r=>Promise.all(r.filter(Boolean).map(Y=>oQ(Y,g,!1,E,t))).then(()=>t[0]));return I?nD(await U,a):U};var SD="text/plain; charset=UTF-8",DQ=(Q,g)=>({"Content-Type":Q,...g}),SC=class{#I;#A;env={};#g;finalized=!1;error;#C;#B;#Q;#s;#o;#D;#i;#w;#e;constructor(Q,g){this.#I=Q,g&&(this.#B=g.executionCtx,this.env=g.env,this.#D=g.notFoundHandler,this.#e=g.path,this.#w=g.matchResult)}get req(){return this.#A??=new rg(this.#I,this.#e,this.#w),this.#A}get event(){if(this.#B&&"respondWith"in this.#B)return this.#B;throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#B)return this.#B;throw Error("This context has no ExecutionContext")}get res(){return this.#Q||=new Response(null,{headers:this.#i??=new Headers})}set res(Q){if(this.#Q&&Q){Q=new Response(Q.body,Q);for(let[g,I]of this.#Q.headers.entries())if(g!=="content-type")if(g==="set-cookie"){let E=this.#Q.headers.getSetCookie();Q.headers.delete("set-cookie");for(let t of E)Q.headers.append("set-cookie",t)}else Q.headers.set(g,I)}this.#Q=Q,this.finalized=!0}render=(...Q)=>(this.#o??=g=>this.html(g),this.#o(...Q));setLayout=Q=>this.#s=Q;getLayout=()=>this.#s;setRenderer=Q=>{this.#o=Q};header=(Q,g,I)=>{this.finalized&&(this.#Q=new Response(this.#Q.body,this.#Q));let E=this.#Q?this.#Q.headers:this.#i??=new Headers;g===void 0?E.delete(Q):I?.append?E.append(Q,g):E.set(Q,g)};status=Q=>{this.#C=Q};set=(Q,g)=>{this.#g??=new Map,this.#g.set(Q,g)};get=Q=>this.#g?this.#g.get(Q):void 0;get var(){return this.#g?Object.fromEntries(this.#g):{}}#E(Q,g,I){let E=this.#Q?new Headers(this.#Q.headers):this.#i??new Headers;if(typeof g=="object"&&"headers"in g){let a=g.headers instanceof Headers?g.headers:new Headers(g.headers);for(let[U,r]of a)U.toLowerCase()==="set-cookie"?E.append(U,r):E.set(U,r)}if(I)for(let[a,U]of Object.entries(I))if(typeof U=="string")E.set(a,U);else{E.delete(a);for(let r of U)E.append(a,r)}let t=typeof g=="number"?g:g?.status??this.#C;return new Response(Q,{status:t,headers:E})}newResponse=(...Q)=>this.#E(...Q);body=(Q,g,I)=>this.#E(Q,g,I);text=(Q,g,I)=>!this.#i&&!this.#C&&!g&&!I&&!this.finalized?new Response(Q):this.#E(Q,g,DQ(SD,I));json=(Q,g,I)=>this.#E(JSON.stringify(Q),g,DQ("application/json",I));html=(Q,g,I)=>{let E=t=>this.#E(t,g,DQ("text/html; charset=UTF-8",I));return typeof Q=="object"?oQ(Q,nC.Stringify,!1,{}).then(E):E(Q)};redirect=(Q,g)=>{let I=String(Q);return this.header("Location",/[^\x00-\xFF]/.test(I)?encodeURI(I):I),this.newResponse(null,g??302)};notFound=()=>(this.#D??=()=>new Response,this.#D(this))};var qA="ALL",LC="all",kC=["get","post","put","delete","options","patch"],Sg="Can not add a route since the matcher is already built.",Lg=class extends Error{};var JC="__COMPOSED_HANDLER";var LD=Q=>Q.text("404 Not Found",404),KC=(Q,g)=>{if("getResponse"in Q){let I=Q.getResponse();return g.newResponse(I.body,I)}return console.error(Q),g.text("Internal Server Error",500)},sQ=class{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#I="/";routes=[];constructor(Q={}){[...kC,LC].forEach(t=>{this[t]=(a,...U)=>(typeof a=="string"?this.#I=a:this.#C(t,this.#I,a),U.forEach(r=>{this.#C(t,this.#I,r)}),this)}),this.on=(t,a,...U)=>{for(let r of[a].flat()){this.#I=r;for(let Y of[t].flat())U.map(j=>{this.#C(Y.toUpperCase(),this.#I,j)})}return this},this.use=(t,...a)=>(typeof t=="string"?this.#I=t:(this.#I="*",a.unshift(t)),a.forEach(U=>{this.#C(qA,this.#I,U)}),this);let{strict:I,...E}=Q;Object.assign(this,E),this.getPath=I??!0?Q.getPath??EQ:NC}#A(){let Q=new sQ({router:this.router,getPath:this.getPath});return Q.errorHandler=this.errorHandler,Q.#g=this.#g,Q.routes=this.routes,Q}#g=LD;errorHandler=KC;route(Q,g){let I=this.basePath(Q);return g.routes.map(E=>{let t;g.errorHandler===KC?t=E.handler:(t=async(a,U)=>(await QQ([],g.errorHandler)(a,()=>E.handler(a,U))).res,t[JC]=E.handler),I.#C(E.method,E.path,t)}),this}basePath(Q){let g=this.#A();return g._basePath=SI(this._basePath,Q),g}onError=Q=>(this.errorHandler=Q,this);notFound=Q=>(this.#g=Q,this);mount(Q,g,I){let E,t;I&&(typeof I=="function"?t=I:(t=I.optionHandler,I.replaceRequest===!1?E=r=>r:E=I.replaceRequest));let a=t?r=>{let Y=t(r);return Array.isArray(Y)?Y:[Y]}:r=>{let Y;try{Y=r.executionCtx}catch{}return[r.env,Y]};E||=(()=>{let r=SI(this._basePath,Q),Y=r==="/"?0:r.length;return j=>{let BA=new URL(j.url);return BA.pathname=BA.pathname.slice(Y)||"/",new Request(BA,j)}})();let U=async(r,Y)=>{let j=await g(E(r.req.raw),...a(r));if(j)return j;await Y()};return this.#C(qA,SI(Q,"*"),U),this}#C(Q,g,I){Q=Q.toUpperCase(),g=SI(this._basePath,g);let E={basePath:this._basePath,path:g,method:Q,handler:I};this.router.add(Q,g,[I,E]),this.routes.push(E)}#B(Q,g){if(Q instanceof Error)return this.errorHandler(Q,g);throw Q}#Q(Q,g,I,E){if(E==="HEAD")return(async()=>new Response(null,await this.#Q(Q,g,I,"GET")))();let t=this.getPath(Q,{env:I}),a=this.router.match(E,t),U=new SC(Q,{path:t,matchResult:a,env:I,executionCtx:g,notFoundHandler:this.#g});if(a[0].length===1){let Y;try{Y=a[0][0][0][0](U,async()=>{U.res=await this.#g(U)})}catch(j){return this.#B(j,U)}return Y instanceof Promise?Y.then(j=>j||(U.finalized?U.res:this.#g(U))).catch(j=>this.#B(j,U)):Y??this.#g(U)}let r=QQ(a[0],this.errorHandler,this.#g);return(async()=>{try{let Y=await r(U);if(!Y.finalized)throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return Y.res}catch(Y){return this.#B(Y,U)}})()}fetch=(Q,...g)=>this.#Q(Q,g[1],g[0],Q.method);request=(Q,g,I,E)=>Q instanceof Request?this.fetch(g?new Request(Q,g):Q,I,E):(Q=Q.toString(),this.fetch(new Request(/^https?:\/\//.test(Q)?Q:`http://localhost${SI("/",Q)}`,g),I,E));fire=()=>{addEventListener("fetch",Q=>{Q.respondWith(this.#Q(Q.request,Q,void 0,Q.request.method))})}};var kg=[];function wQ(Q,g){let I=this.buildAllMatchers(),E=(t,a)=>{let U=I[t]||I[qA],r=U[2][a];if(r)return r;let Y=a.match(U[0]);if(!Y)return[[],kg];let j=Y.indexOf("",1);return[U[1][j],Y]};return this.match=E,E(Q,g)}var Jg="[^/]+",zI=".*",$I="(?:|/.*)",LI=Symbol(),kD=new Set(".\\+*[^]$()");function JD(Q,g){return Q.length===1?g.length===1?Q<g?-1:1:-1:g.length===1||Q===zI||Q===$I?1:g===zI||g===$I?-1:Q===Jg?1:g===Jg?-1:Q.length===g.length?Q<g?-1:1:g.length-Q.length}var Kg=class{#I;#A;#g=Object.create(null);insert(Q,g,I,E,t){if(Q.length===0){if(this.#I!==void 0)throw LI;if(t)return;this.#I=g;return}let[a,...U]=Q,r=a==="*"?U.length===0?["","",zI]:["","",Jg]:a==="/*"?["","",$I]:a.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),Y;if(r){let j=r[1],BA=r[2]||Jg;if(j&&r[2]&&(BA===".*"||(BA=BA.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(BA))))throw LI;if(Y=this.#g[BA],!Y){if(Object.keys(this.#g).some(QA=>QA!==zI&&QA!==$I))throw LI;if(t)return;Y=this.#g[BA]=new Kg,j!==""&&(Y.#A=E.varIndex++)}!t&&j!==""&&I.push([j,Y.#A])}else if(Y=this.#g[a],!Y){if(Object.keys(this.#g).some(j=>j.length>1&&j!==zI&&j!==$I))throw LI;if(t)return;Y=this.#g[a]=new Kg}Y.insert(U,g,I,E,t)}buildRegExpStr(){let g=Object.keys(this.#g).sort(JD).map(I=>{let E=this.#g[I];return(typeof E.#A=="number"?`(${I})@${E.#A}`:kD.has(I)?`\\${I}`:I)+E.buildRegExpStr()});return typeof this.#I=="number"&&g.unshift(`#${this.#I}`),g.length===0?"":g.length===1?g[0]:"(?:"+g.join("|")+")"}};var lC=class{#I={varIndex:0};#A=new Kg;insert(Q,g,I){let E=[],t=[];for(let U=0;;){let r=!1;if(Q=Q.replace(/\{[^}]+\}/g,Y=>{let j=`@\\${U}`;return t[U]=[j,Y],U++,r=!0,j}),!r)break}let a=Q.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let U=t.length-1;U>=0;U--){let[r]=t[U];for(let Y=a.length-1;Y>=0;Y--)if(a[Y].indexOf(r)!==-1){a[Y]=a[Y].replace(r,t[U][1]);break}}return this.#A.insert(a,g,E,this.#I,I),E}buildRegExp(){let Q=this.#A.buildRegExpStr();if(Q==="")return[/^$/,[],[]];let g=0,I=[],E=[];return Q=Q.replace(/#(\d+)|@(\d+)|\.\*\$/g,(t,a,U)=>a!==void 0?(I[++g]=Number(a),"$()"):(U!==void 0&&(E[Number(U)]=++g),"")),[new RegExp(`^${Q}`),I,E]}};var KD=[/^$/,[],Object.create(null)],YC=Object.create(null);function HC(Q){return YC[Q]??=new RegExp(Q==="*"?"":`^${Q.replace(/\/\*$|([.\\+*[^\]$()])/g,(g,I)=>I?`\\${I}`:"(?:|/.*)")}$`)}function lD(){YC=Object.create(null)}function YD(Q){let g=new lC,I=[];if(Q.length===0)return KD;let E=Q.map(j=>[!/\*|\/:/.test(j[0]),...j]).sort(([j,BA],[QA,DA])=>j?1:QA?-1:BA.length-DA.length),t=Object.create(null);for(let j=0,BA=-1,QA=E.length;j<QA;j++){let[DA,MA,UA]=E[j];DA?t[MA]=[UA.map(([fA])=>[fA,Object.create(null)]),kg]:BA++;let kA;try{kA=g.insert(MA,BA,DA)}catch(fA){throw fA===LI?new Lg(MA):fA}DA||(I[BA]=UA.map(([fA,uA])=>{let OA=Object.create(null);for(uA-=1;uA>=0;uA--){let[WA,iI]=kA[uA];OA[WA]=iI}return[fA,OA]}))}let[a,U,r]=g.buildRegExp();for(let j=0,BA=I.length;j<BA;j++)for(let QA=0,DA=I[j].length;QA<DA;QA++){let MA=I[j][QA]?.[1];if(!MA)continue;let UA=Object.keys(MA);for(let kA=0,fA=UA.length;kA<fA;kA++)MA[UA[kA]]=r[MA[UA[kA]]]}let Y=[];for(let j in U)Y[j]=I[U[j]];return[a,Y,t]}function xI(Q,g){if(Q){for(let I of Object.keys(Q).sort((E,t)=>t.length-E.length))if(HC(I).test(g))return[...Q[I]]}}var lg=class{name="RegExpRouter";#I;#A;constructor(){this.#I={[qA]:Object.create(null)},this.#A={[qA]:Object.create(null)}}add(Q,g,I){let E=this.#I,t=this.#A;if(!E||!t)throw new Error(Sg);E[Q]||[E,t].forEach(r=>{r[Q]=Object.create(null),Object.keys(r[qA]).forEach(Y=>{r[Q][Y]=[...r[qA][Y]]})}),g==="/*"&&(g="*");let a=(g.match(/\/:/g)||[]).length;if(/\*$/.test(g)){let r=HC(g);Q===qA?Object.keys(E).forEach(Y=>{E[Y][g]||=xI(E[Y],g)||xI(E[qA],g)||[]}):E[Q][g]||=xI(E[Q],g)||xI(E[qA],g)||[],Object.keys(E).forEach(Y=>{(Q===qA||Q===Y)&&Object.keys(E[Y]).forEach(j=>{r.test(j)&&E[Y][j].push([I,a])})}),Object.keys(t).forEach(Y=>{(Q===qA||Q===Y)&&Object.keys(t[Y]).forEach(j=>r.test(j)&&t[Y][j].push([I,a]))});return}let U=ng(g)||[g];for(let r=0,Y=U.length;r<Y;r++){let j=U[r];Object.keys(t).forEach(BA=>{(Q===qA||Q===BA)&&(t[BA][j]||=[...xI(E[BA],j)||xI(E[qA],j)||[]],t[BA][j].push([I,a-Y+r+1]))})}}match=wQ;buildAllMatchers(){let Q=Object.create(null);return Object.keys(this.#A).concat(Object.keys(this.#I)).forEach(g=>{Q[g]||=this.#g(g)}),this.#I=this.#A=void 0,lD(),Q}#g(Q){let g=[],I=Q===qA;return[this.#I,this.#A].forEach(E=>{let t=E[Q]?Object.keys(E[Q]).map(a=>[a,E[Q][a]]):[];t.length!==0?(I||=!0,g.push(...t)):Q!==qA&&g.push(...Object.keys(E[qA]).map(a=>[a,E[qA][a]]))}),I?YD(g):null}};var eQ=class{name="SmartRouter";#I=[];#A=[];constructor(Q){this.#I=Q.routers}add(Q,g,I){if(!this.#A)throw new Error(Sg);this.#A.push([Q,g,I])}match(Q,g){if(!this.#A)throw new Error("Fatal error");let I=this.#I,E=this.#A,t=I.length,a=0,U;for(;a<t;a++){let r=I[a];try{for(let Y=0,j=E.length;Y<j;Y++)r.add(...E[Y]);U=r.match(Q,g)}catch(Y){if(Y instanceof Lg)continue;throw Y}this.match=r.match.bind(r),this.#I=[r],this.#A=void 0;break}if(a===t)throw new Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,U}get activeRouter(){if(this.#A||this.#I.length!==1)throw new Error("No active router has been determined yet.");return this.#I[0]}};var Ag=Object.create(null),tQ=class{#I;#A;#g;#C=0;#B=Ag;constructor(Q,g,I){if(this.#A=I||Object.create(null),this.#I=[],Q&&g){let E=Object.create(null);E[Q]={handler:g,possibleKeys:[],score:0},this.#I=[E]}this.#g=[]}insert(Q,g,I){this.#C=++this.#C;let E=this,t=hC(g),a=[];for(let U=0,r=t.length;U<r;U++){let Y=t[U],j=t[U+1],BA=UC(Y,j),QA=Array.isArray(BA)?BA[0]:Y;if(QA in E.#A){E=E.#A[QA],BA&&a.push(BA[1]);continue}E.#A[QA]=new tQ,BA&&(E.#g.push(BA),a.push(BA[1])),E=E.#A[QA]}return E.#I.push({[Q]:{handler:I,possibleKeys:a.filter((U,r,Y)=>Y.indexOf(U)===r),score:this.#C}}),E}#Q(Q,g,I,E){let t=[];for(let a=0,U=Q.#I.length;a<U;a++){let r=Q.#I[a],Y=r[g]||r[qA],j={};if(Y!==void 0&&(Y.params=Object.create(null),t.push(Y),I!==Ag||E&&E!==Ag))for(let BA=0,QA=Y.possibleKeys.length;BA<QA;BA++){let DA=Y.possibleKeys[BA],MA=j[Y.score];Y.params[DA]=E?.[DA]&&!MA?E[DA]:I[DA]??E?.[DA],j[Y.score]=!0}}return t}search(Q,g){let I=[];this.#B=Ag;let t=[this],a=CQ(g),U=[];for(let r=0,Y=a.length;r<Y;r++){let j=a[r],BA=r===Y-1,QA=[];for(let DA=0,MA=t.length;DA<MA;DA++){let UA=t[DA],kA=UA.#A[j];kA&&(kA.#B=UA.#B,BA?(kA.#A["*"]&&I.push(...this.#Q(kA.#A["*"],Q,UA.#B)),I.push(...this.#Q(kA,Q,UA.#B))):QA.push(kA));for(let fA=0,uA=UA.#g.length;fA<uA;fA++){let OA=UA.#g[fA],WA=UA.#B===Ag?{}:{...UA.#B};if(OA==="*"){let CI=UA.#A["*"];CI&&(I.push(...this.#Q(CI,Q,UA.#B)),CI.#B=WA,QA.push(CI));continue}let[iI,pI,FI]=OA;if(!j&&!(FI instanceof RegExp))continue;let II=UA.#A[iI],qg=a.slice(r).join("/");if(FI instanceof RegExp){let CI=FI.exec(qg);if(CI){if(WA[pI]=CI[0],I.push(...this.#Q(II,Q,UA.#B,WA)),Object.keys(II.#A).length){II.#B=WA;let gI=CI[0].match(/\//)?.length??0;(U[gI]||=[]).push(II)}continue}}(FI===!0||FI.test(j))&&(WA[pI]=j,BA?(I.push(...this.#Q(II,Q,WA,UA.#B)),II.#A["*"]&&I.push(...this.#Q(II.#A["*"],Q,WA,UA.#B))):(II.#B=WA,QA.push(II)))}}t=QA.concat(U.shift()??[])}return I.length>1&&I.sort((r,Y)=>r.score-Y.score),[I.map(({handler:r,params:Y})=>[r,Y])]}};var FQ=class{name="TrieRouter";#I;constructor(){this.#I=new tQ}add(Q,g,I){let E=ng(g);if(E){for(let t=0,a=E.length;t<a;t++)this.#I.insert(Q,E[t],I);return}this.#I.insert(Q,g,I)}match(Q,g){return this.#I.search(Q,g)}};var zA=class extends sQ{constructor(Q={}){super(Q),this.router=Q.router??new eQ({routers:[new lg,new FQ]})}};var HD=8e3,dC=Symbol("nx-cache-get-deadline");function fD(Q,g){return g>0?new Promise((I,E)=>{let t=setTimeout(()=>I(dC),g);Q.then(a=>{clearTimeout(t),I(a)},a=>{clearTimeout(t),E(a)})}):Q}function fC(Q){return Q?`hit size=${Q.size}`:"miss"}function dD(Q){return Q instanceof Error?Q.message:String(Q)}function RQ(Q){let g=new zA,I=Q.now??(()=>Date.now()),E=Q.getDeadlineMs??HD,t=(a,U,r)=>{a.then(Y=>{Y?.stream.cancel().catch(()=>{}),Q.log?.(`nx get ${U} relay settled after deadline -> ${fC(Y)} (${I()-r}ms)`)},Y=>Q.log?.(`nx get ${U} relay failed after deadline: ${dD(Y)}`))};return g.get("/blob/nx/v1/cache/:hash",async a=>{let U=a.req.param("hash"),r=I();Q.log?.(`nx get ${U} start`);let Y=Q.blob.get(U,{relay:!0}),j=await fD(Y,E);return j===dC?(Q.log?.(`nx get ${U} -> miss deadline=${E}ms (${I()-r}ms, relay continues)`),t(Y,U,r),Q.respond(a,null)):(Q.log?.(`nx get ${U} -> ${fC(j)} (${I()-r}ms)`),Q.respond(a,j))}),g.put("/blob/nx/v1/cache/:hash",async a=>{let U=a.req.param("hash"),r=I(),Y=await Q.blob.put(a.req.raw.body??Buffer.alloc(0));return await Q.blob.bind(U,Y),Q.log?.(`nx put ${U} -> root=${Y} (${I()-r}ms)`),a.body(null,200)}),g}function qC(Q){return async(g,I)=>{if(g.req.header("authorization")!==`Bearer ${Q}`)return g.body(null,401);await I()}}function Yg(Q,g){return g?Q.body(g.stream,200,{"content-type":"application/octet-stream","content-length":String(g.size)}):Q.body(null,404)}function uC(Q){let g=new zA;return g.on("HEAD","/blob/objects/:hash",async I=>{let E=await Q.get(I.req.param("hash"),{relay:!1});return E?(await E.stream.cancel(),I.body(null,200)):I.body(null,404)}),g.get("/blob/objects/:hash",async I=>{if(I.req.query("raw")==="1"){let t=await Q.store.read(I.req.param("hash"));return t?I.body(new Uint8Array(t),200,{"content-type":"application/octet-stream","content-length":String(t.length)}):I.body(null,404)}let E=I.req.query("noRelay")!=="1";return Yg(I,await Q.get(I.req.param("hash"),{relay:E}))}),g.put("/blob/objects/:hash",async I=>(await Q.store.write(I.req.param("hash"),I.req.raw.body??Buffer.alloc(0)),I.body(null,200))),g}function xC(Q){let g=new zA;return g.get("/blob/metrics",async I=>{let E=Q.metrics.snapshot();return I.json({...E,totalBytes:await Q.store.totalBytes()})}),g}var qD=4096;function bC(Q){let g=new zA;return g.post("/blob/have",async I=>{let E=await pC(I);if(!E)return I.body(null,400);let t=[];for(let a of E)await Q.store.has(a)||t.push(a);return I.json({missing:t})}),g.post("/blob/batch",async I=>{let E=await pC(I);if(!E)return I.body(null,400);let t={},a=[];for(let U of E){let r=await Q.store.read(U);r?t[U]=r.toString("base64"):a.push(U)}return I.json({blobs:t,missing:a})}),g}async function pC(Q){try{let g=await Q.req.json();return!Array.isArray(g)||g.length>qD?null:g.filter(I=>typeof I=="string")}catch{return null}}function VC(Q){let g=new zA;return g.get("/blob/aliases/:name",async I=>{let E=await Q.store.resolveAlias(I.req.param("name"));return E?I.text(E,200):I.body(null,404)}),g.put("/blob/aliases/:name",async I=>{let E=(await I.req.text()).trim();return eI(E)?(await Q.store.setAlias(I.req.param("name"),E),I.body(null,200)):I.body(null,400)}),g}var uD="20.5.3";function TC(Q){let g=new zA,I=async()=>{let E=await Q.retention.status(),{status:t,...a}=E;return{status:t,store:a,service:"blob",version:uD}};return g.get("/blob/healthz",async E=>E.json(await I())),g.get("/health",async E=>E.json(await I())),g.use("*",qC(Q.token)),g.route("/",RQ({blob:Q.usecase,respond:Yg,log:E=>console.log(`[planx-blob] ${E}`),getDeadlineMs:Q.nxGetDeadlineMs})),g.route("/",uC(Q.usecase)),g.route("/",xC(Q.usecase)),g.route("/",bC(Q.usecase)),g.route("/",VC(Q.usecase)),g}var mC="planx-blob";function WC(Q,g){let I={},E=Q.PLANX_SERVER_NAME;if(E){I.serverName=E;let r=g(`/tmp/planx/${E}/transport.port`),Y=r===null?NaN:parseInt(r.trim(),10);Number.isInteger(Y)&&Y>0&&(I.transportPort=Y)}let t=aQ(Q,"PLANX_BLOB_TRANSPORT_PORT");t!==void 0&&(I.transportPort=t);let a=aQ(Q,"PLANX_BLOB_PORT",{allowZero:!0});a!==void 0&&(I.port=a),Q.PLANX_BLOB_STORE&&(I.storeDir=Q.PLANX_BLOB_STORE),Q.PLANX_BLOB_TOKEN&&(I.token=Q.PLANX_BLOB_TOKEN);let U=aQ(Q,"PLANX_BLOB_MAX_BYTES");return U!==void 0&&(I.maxBytes=U),I}function ZC(Q,g){return[`/tmp/planx/${Q}/blob.port`,`${g}/.planx/${Q}/blob.port`]}function aQ(Q,g,I={}){let E=Q[g];if(!E)return;let t=parseInt(E,10),a=I.allowZero?0:1;if(!Number.isInteger(t)||t<a)throw new Error(`${g} must be an integer >= ${a}: ${E}`);return t}var Hg=class{constructor(g){this.peers=g}setPeers(g){this.peers=g}async livePeers(){return this.peers}};var xD="blob",fg=class{constructor(g){this.options=g;this.selfId=null;this.warned=!1}async livePeers(){try{let g=await this.resolveSelfId();return(await this.fetchJson("/servers")).filter(E=>typeof E.id=="string"&&E.id.length>0).filter(E=>E.id!==g).map(E=>({id:E.id,baseUrl:`${this.options.transportBaseUrl}/servers/${E.id}/${xD}`}))}catch(g){if(!this.warned){this.warned=!0;let I=g instanceof Error?g.message:String(g);console.error(`[blob] transport peers unavailable (${this.options.transportBaseUrl}): ${I}`)}return[]}}async resolveSelfId(){if(this.selfId!==null)return this.selfId;let g=await this.fetchJson("/peer");return this.selfId=g.peerId??"",this.selfId}async fetchJson(g){let I=await fetch(`${this.options.transportBaseUrl}${g}`,{signal:AbortSignal.timeout(this.options.timeoutMs??1500)});if(!I.ok)throw new Error(`GET ${g} -> ${I.status}`);return await I.json()}};var dg=class{constructor(g,I={}){this.upstream=g;this.options=I;this.cached=null;this.fetchedAt=0;this.inflight=null}async livePeers(){return this.cached!==null&&!this.isExpired()?this.cached:this.cached!==null?(this.refresh(),this.cached):(await this.refresh(),this.cached??[])}isExpired(){let g=this.options.ttlMs??5e3;return this.now()-this.fetchedAt>=g}now(){return(this.options.now??Date.now)()}refresh(){return this.inflight?this.inflight:(this.inflight=this.upstream.livePeers().then(g=>{this.cached=g,this.fetchedAt=this.now()}).catch(()=>{}).finally(()=>{this.inflight=null}),this.inflight)}};function PC(Q){return Q.transportPort?new dg(new fg({transportBaseUrl:`http://127.0.0.1:${Q.transportPort}`})):new Hg(Q.peers)}function OC(Q){let g={};for(let I=0;I<Q.length;I+=1){let E=Q[I],t=Q[I+1];if(!(t===void 0||t.startsWith("--"))&&(E==="--name"&&(g.name=t),E==="--store"&&(g.storeDir=t),E==="--port")){let a=Number(t);if(!Number.isInteger(a)||a<0)throw new Error(`invalid --port: ${t}`);g.port=a}}return g}var ZD=_g.maxBytes;function PD(Q,g){for(let I of ZC(Q,XC()))try{VD(pD(I),{recursive:!0});let E=`${I}.${process.pid}.wip`;WD(E,String(g)),mD(E,I)}catch(E){console.error(`[planx-blob] blob.port write failed (${I}): ${String(E)}`)}}async function jC(Q){let g=WC(Q.env,DA=>{try{return TD(DA,"utf-8")}catch{return null}}),I=OC(Q.argv),E=g.serverName??I.name,t={port:I.port??g.port??0,host:"127.0.0.1",storeDir:I.storeDir??g.storeDir??bD(XC(),".cache","planx-blob"),token:g.token??mC,peers:[],transportPort:g.transportPort,maxBytes:g.maxBytes??ZD},a={..._g,maxBytes:t.maxBytes},U=new cg({dir:t.storeDir,wipGraceMs:a.wipGraceMs}),r=new uI,Y=new hg(U,a,r),j=new Gg(U,PC(t),new Ug({token:t.token}),{metrics:r,retention:Y}),BA=TB(Y,a.retainIntervalMs),QA=TC({usecase:j,retention:Y,token:t.token});return await new Promise((DA,MA)=>{(kA=>{let fA=PQ({fetch:QA.fetch,port:kA,hostname:t.host},uA=>{E&&PD(E,uA.port),Q.emitLine(JSON.stringify({service:"blob",port:uA.port,pid:process.pid})),DA({storeDir:t.storeDir,port:uA.port,maxBytes:t.maxBytes,close:()=>new Promise(OA=>{BA(),fA.closeAllConnections?.(),U.close(),fA.close(()=>OA())})})});fA.on("error",uA=>{MA(uA instanceof Error?uA:new Error(String(uA)))})})(t.port)})}jC({argv:process.argv.slice(2),env:process.env,emitLine:Q=>process.stdout.write(`${Q}
47
+ `,vB=" ";function CD(Q){let g=Q.map(I=>`${I.hash}${vB}${I.subtreeBytes}`).join(zg);return Buffer.from(`v2${zg}${g}`,"utf-8")}function Ng(Q){let g=Q.toString("utf-8").split(zg);if(g[0]!=="v2")throw new Error(`unsupported manifest version: ${g[0]}`);return g.slice(1).filter(I=>I.length>0).map(I=>{let[E,t]=I.split(vB);return{hash:E,subtreeBytes:Number(t)}})}function _B(Q,g={}){let I=[],E=Q.map(a=>({hash:a.hash,subtreeBytes:a.size})),t=E.reduce((a,U)=>a+U.subtreeBytes,0);if(E.length===1)return{rootHash:E[0].hash,totalBytes:t,objects:I};for(;;){let U=ED(E,g).map(r=>{let Y=CD(r),j=OI(1,Y);return I.push({hash:j,type:1,payload:Y}),{hash:j,subtreeBytes:r.reduce((BA,QA)=>BA+QA.subtreeBytes,0)}});if(U.length===1)return{rootHash:U[0].hash,totalBytes:t,objects:I};E=U}}function ED(Q,g){let I=g.minEntries??gD,E=g.avgEntries??QD,t=g.maxEntries??BD;if(Q.length<=t)return[Q];let a=(1<<Math.round(Math.log2(Math.max(2,E))))-1,U=[],r=0;for(;r<Q.length;){let Y=Math.min(r+t,Q.length);for(let j=r+I;j<Y;j+=1)if((iD(Q[j].hash)&a)===0){Y=j+1;break}U.push(Q.slice(r,Y)),r=Y}return U}function iD(Q){return parseInt(Q.slice(-8),16)>>>0}async function zB(Q,g){return Q.batch(async()=>{let I=[];for await(let t of jB(g)){let a=OI(0,t);await Q.write(a,t),I.push({hash:a,size:t.length})}let E=_B(I);for(let t of E.objects){await Q.write(t.hash,t.payload);for(let a of Ng(t.payload))await Q.link(t.hash,a.hash)}return E.rootHash})}function oD(Q,g){return XI(Q,1,g)}function MI(Q,g){if(!oD(Q,g))return null;try{return Ng(g)}catch{throw console.error(`[planx-blob] malformed manifest, rejecting ${Q}`),new Error(`malformed manifest: ${Q}`)}}async function $B(Q,g){let I=await g(Q);if(!I)return null;let E=MI(Q,I);return E?E.reduce((t,a)=>t+a.subtreeBytes,0):I.length}async function*AQ(Q,g){let I=await g(Q);if(!I)throw new Error(`missing object: ${Q}`);let E=MI(Q,I);if(!E){yield I;return}for(let t of E)yield*AQ(t.hash,g)}async function AC(Q,g,I){let E;try{E=MI(g,I)}catch{return}if(E)for(let t of E)await Q.link(g,t.hash)}async function IC(Q,g){let I=[Q];for(;I.length>0;){let E=[];for(let a of I)await g.has(a)||E.push(a);if(E.length>0&&!await g.fetchMissing(E))return!1;let t=[];for(let a of I){let U=await g.read(a);if(!U)return!1;try{t.push(...(MI(a,U)??[]).map(r=>r.hash))}catch{return!1}}I=t}return!0}import{createHash as DD}from"node:crypto";function nI(Q,g){return Q.map(I=>({peer:I,score:sD(I.id,g)})).sort((I,E)=>I.score<E.score?1:I.score>E.score?-1:0).map(I=>I.peer)}function sD(Q,g){return DD("sha256").update(`${Q}:${g}`).digest("hex")}function gC(Q,g){let I=new Map;for(let t of g.keys())I.set(t,[]);let E=[];for(let t of Q){let a=[...g.entries()].filter(([,U])=>U.has(t));if(a.length===0){E.push(t);continue}a.sort(([U],[r])=>(I.get(U)?.length??0)-(I.get(r)?.length??0)),I.get(a[0][0])?.push(t)}return{queues:I,unclaimed:E}}async function QC(Q,g){if(g.length===0)return!0;let I=await wD(Q,g),{queues:E,unclaimed:t}=gC(g,I),a={ownedBy:I,queues:E,started:new Set,done:new Set,tried:new Map,retry:[]};await Promise.all(Q.peers.map(U=>eD(Q,a,U)));for(let U of[...t,...g.filter(r=>!a.done.has(r))])if(!a.done.has(U)){if(!await Q.fallback(U))return!1;a.done.add(U)}return!0}async function wD(Q,g){let I=new Map;return await Promise.all(Q.peers.map(async E=>{let t=await Q.have(E,g);if(t===null)return;let a=new Set(t);I.set(E.id,new Set(g.filter(U=>!a.has(U))))})),I}async function eD(Q,g,I){for(;;){let E=tD(g,I.id);if(E===null)return;g.started.add(E),CC(g,E).add(I.id),!g.done.has(E)&&(await Q.fetchFrom(I,E)?g.done.add(E):FD(g,E)&&g.retry.push(E))}}function tD(Q,g){let I=Q.queues.get(g)??[];for(;I.length>0;){let t=I.shift();if(!Q.started.has(t))return t}let E=Q.retry.findIndex(t=>!Q.done.has(t)&&BC(Q,t,g));if(E>=0)return Q.retry.splice(E,1)[0];for(let[t,a]of Q.queues){if(t===g)continue;let U=a.findIndex(r=>!Q.started.has(r)&&Q.ownedBy.get(g)?.has(r));if(U>=0)return a.splice(U,1)[0]}return null}function BC(Q,g,I){return(Q.ownedBy.get(I)?.has(g)??!1)&&!CC(Q,g).has(I)}function FD(Q,g){return[...Q.ownedBy.keys()].some(I=>BC(Q,g,I))}function CC(Q,g){let I=Q.tried.get(g);return I||Q.tried.set(g,I=new Set),I}async function IQ(Q,g=()=>{}){return Q.length===0?null:new Promise(I=>{let E=Q.length,t=!1,a=()=>{E-=1,E===0&&!t&&(t=!0,I(null))};for(let U of Q)U.then(r=>{if(r===null)return a();if(t)return g(r);t=!0,I(r)},a)})}async function EC(Q,g,I){let{client:E,hash:t}=I,a=new Map,U=BA=>{let QA=new AbortController;return a.set(BA.id,QA),QA.signal},r=BA=>QA=>QA?{peer:BA,stream:QA}:null,Y=[...Q.slice(0,g).map(BA=>E.get(BA,t,{signal:U(BA)}).then(r(BA)).catch(()=>null)),...Q.slice(g).map(BA=>{let QA=U(BA);return E.head(BA,t,{signal:QA}).then(DA=>DA?E.get(BA,t,{signal:QA}):null).then(r(BA)).catch(()=>null)})],j=await IQ(Y,BA=>{BA.stream.cancel().catch(()=>{})});for(let[BA,QA]of a)BA!==j?.peer.id&&QA.abort();return j?.stream??null}function iC(Q,g){return async I=>{let E=await oC(Q,I);return E||(g?(Q.onRemote(),sC(Q,I)):null)}}async function oC(Q,g){let I=await Q.store.read(g);return I?Q.accepts(g,I)?I:(console.warn(`[planx-blob] local chunk failed verification, discarding ${g}`),await Q.store.discard(g),null):null}function DC(Q,g){return{has:I=>Q.store.has(I),read:I=>oC(Q,I),fetchMissing:async I=>g?(Q.onRemote(),QC({peers:await Q.livePeers(),have:(E,t)=>Q.client.have(E,t),fetchFrom:(E,t)=>RD(Q,E,t),fallback:async E=>await sC(Q,E)!==null},I)):!1}}async function sC(Q,g){let I=nI(await Q.livePeers(),g),E=await EC(I,Q.replication,{client:Q.client,hash:g});return E?wC(Q,g,E):null}async function RD(Q,g,I){let E=await Q.client.get(g,I);return E?await wC(Q,I,E)!==null:!1}async function wC(Q,g,I){let E;try{E=Buffer.from(await new Response(I).arrayBuffer())}catch{return null}return Q.accepts(g,E)?(await Q.store.write(g,E),await AC(Q.store,g,E),E):null}function eC(Q=g=>console.error(g)){let g=new Set;return(I,E)=>{let t=`${I.id} ${E}`;g.has(t)||(g.size>=64&&g.clear(),g.add(t),Q(`[planx-blob] replica put failed peer=${I.id} reason=${E}`))}}async function gQ(Q,g){let I=await Q.store.read(g);if(!I)return;await aD(Q,g,I);let E;try{E=MI(g,I)}catch{return}if(E)for(let t of E)await gQ(Q,t.hash)}async function aD(Q,g,I){let t=nI(await Q.livePeers(),g).slice(0,Q.replication);(await Promise.all(t.map(U=>Q.client.put(U,g,I).catch(r=>({ok:!1,reason:`error ${String(r)}`}))))).forEach((U,r)=>{U.ok||Q.onFailure(t[r],U.reason)})}function tC(Q){return new ReadableStream({async pull(g){try{let I=await Q.next();if(I.done)return g.close();g.enqueue(new Uint8Array(I.value))}catch(I){g.error(I)}},cancel:()=>{Q.return(void 0)}})}async function FC(Q,g,I){let E=nI(await Q.livePeers(),g);await Promise.all(E.slice(0,Q.replication).map(t=>Q.client.putAlias(t,g,I)))}async function RC(Q,g){if(eI(g))return null;let I=nI(await Q.livePeers(),g);return IQ(I.map(async E=>{let t=await Q.client.getAlias(E,g);return t&&eI(t)?t:null}))}var cD=2,Gg=class{constructor(g,I,E,t={}){this.store=g;this.peers=I;this.client=E;this.options=t;this.reportReplicaFailure=eC();this.metrics=t.metrics??new uI}async get(g,I){let E=this.now(),t=await this.rootOf(g,I.relay),a={value:!1},U={store:this.store,client:this.client,replication:this.replication(),livePeers:()=>this.peers.livePeers(),accepts:(j,BA)=>this.accepts(j,BA),onRemote:()=>{a.value=!0}},r=iC(U,I.relay),Y;try{Y=await $B(t,r)}catch{Y=null}return Y===null||!await IC(t,DC(U,I.relay))?(this.metrics.recordMiss(this.now()-E),null):(a.value?this.metrics.recordRelayHit(this.now()-E):this.metrics.recordLocalHit(this.now()-E),{size:Y,stream:tC(AQ(t,r))})}async rootOf(g,I){let E=await this.store.resolveAlias(g);if(E)return await this.store.touchAlias(g,this.now()),E;if(!I)return g;let t=await RC(await this.aliasDeps(),g);return t?(await this.store.setAlias(g,t),t):g}async aliasDeps(){return{client:this.client,livePeers:()=>this.peers.livePeers(),replication:this.replication()}}now(){return(this.options.now??(()=>Date.now()))()}accepts(g,I){return XI(g,0,I)||XI(g,1,I)?!0:(console.error(`[planx-blob] hash mismatch, rejecting ${g}`),!1)}async put(g){let I=this.now(),E=await XB(g),t;try{t=await zB(this.store,E.path),gQ(this.replicationDeps(),t).catch(()=>{})}finally{await E.discard()}return this.metrics.recordPut(this.now()-I),await this.options.retention?.afterPut(),t}async bind(g,I){await this.store.setAlias(g,I,this.now()),this.aliasDeps().then(E=>FC(E,g,I)).catch(()=>{})}replicationDeps(){return{store:this.store,client:this.client,livePeers:()=>this.peers.livePeers(),replication:this.replication(),onFailure:(g,I)=>{this.metrics.recordReplicaFailure(g.id,I),this.reportReplicaFailure(g,I)}}}replication(){return this.options.replication??cD}};var QQ=(Q,g,I)=>(E,t)=>{let a=-1;return U(0);async function U(r){if(r<=a)throw new Error("next() called multiple times");a=r;let Y,j=!1,BA;if(Q[r]?(BA=Q[r][0][0],E.req.routeIndex=r):BA=r===Q.length&&t||void 0,BA)try{Y=await BA(E,()=>U(r+1))}catch(QA){if(QA instanceof Error&&g)E.error=QA,Y=await g(QA,E),j=!0;else throw QA}else E.finalized===!1&&I&&(Y=await I(E));return Y&&(E.finalized===!1||j)&&(E.res=Y),E}};var aC=Symbol();var cC=async(Q,g=Object.create(null))=>{let{all:I=!1,dot:E=!1}=g,a=(Q instanceof rg?Q.raw.headers:Q.headers).get("Content-Type");return a?.startsWith("multipart/form-data")||a?.startsWith("application/x-www-form-urlencoded")?hD(Q,{all:I,dot:E}):{}};async function hD(Q,g){let I=await Q.formData();return I?UD(I,g):{}}function UD(Q,g){let I=Object.create(null);return Q.forEach((E,t)=>{g.all||t.endsWith("[]")?ND(I,t,E):I[t]=E}),g.dot&&Object.entries(I).forEach(([E,t])=>{E.includes(".")&&(GD(I,E,t),delete I[E])}),I}var ND=(Q,g,I)=>{Q[g]!==void 0?Array.isArray(Q[g])?Q[g].push(I):Q[g]=[Q[g],I]:g.endsWith("[]")?Q[g]=[I]:Q[g]=I},GD=(Q,g,I)=>{let E=Q,t=g.split(".");t.forEach((a,U)=>{U===t.length-1?E[a]=I:((!E[a]||typeof E[a]!="object"||Array.isArray(E[a])||E[a]instanceof File)&&(E[a]=Object.create(null)),E=E[a])})};var CQ=Q=>{let g=Q.split("/");return g[0]===""&&g.shift(),g},hC=Q=>{let{groups:g,path:I}=rD(Q),E=CQ(I);return yD(E,g)},rD=Q=>{let g=[];return Q=Q.replace(/\{[^}]+\}/g,(I,E)=>{let t=`@${E}`;return g.push([t,I]),t}),{groups:g,path:Q}},yD=(Q,g)=>{for(let I=g.length-1;I>=0;I--){let[E]=g[I];for(let t=Q.length-1;t>=0;t--)if(Q[t].includes(E)){Q[t]=Q[t].replace(E,g[I][1]);break}}return Q},yg={},UC=(Q,g)=>{if(Q==="*")return"*";let I=Q.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(I){let E=`${Q}#${g}`;return yg[E]||(I[2]?yg[E]=g&&g[0]!==":"&&g[0]!=="*"?[E,I[1],new RegExp(`^${I[2]}(?=/${g})`)]:[Q,I[1],new RegExp(`^${I[2]}$`)]:yg[E]=[Q,I[1],!0]),yg[E]}return null},Mg=(Q,g)=>{try{return g(Q)}catch{return Q.replace(/(?:%[0-9A-Fa-f]{2})+/g,I=>{try{return g(I)}catch{return I}})}},MD=Q=>Mg(Q,decodeURI),EQ=Q=>{let g=Q.url,I=g.indexOf("/",g.indexOf(":")+4),E=I;for(;E<g.length;E++){let t=g.charCodeAt(E);if(t===37){let a=g.indexOf("?",E),U=g.slice(I,a===-1?void 0:a);return MD(U.includes("%25")?U.replace(/%25/g,"%2525"):U)}else if(t===63)break}return g.slice(I,E)};var NC=Q=>{let g=EQ(Q);return g.length>1&&g.at(-1)==="/"?g.slice(0,-1):g},SI=(Q,g,...I)=>(I.length&&(g=SI(g,...I)),`${Q?.[0]==="/"?"":"/"}${Q}${g==="/"?"":`${Q?.at(-1)==="/"?"":"/"}${g?.[0]==="/"?g.slice(1):g}`}`),ng=Q=>{if(Q.charCodeAt(Q.length-1)!==63||!Q.includes(":"))return null;let g=Q.split("/"),I=[],E="";return g.forEach(t=>{if(t!==""&&!/\:/.test(t))E+="/"+t;else if(/\:/.test(t))if(/\?/.test(t)){I.length===0&&E===""?I.push("/"):I.push(E);let a=t.replace("?","");E+="/"+a,I.push(E)}else E+="/"+t}),I.filter((t,a,U)=>U.indexOf(t)===a)},BQ=Q=>/[%+]/.test(Q)?(Q.indexOf("+")!==-1&&(Q=Q.replace(/\+/g," ")),Q.indexOf("%")!==-1?Mg(Q,iQ):Q):Q,GC=(Q,g,I)=>{let E;if(!I&&g&&!/[%+]/.test(g)){let U=Q.indexOf(`?${g}`,8);for(U===-1&&(U=Q.indexOf(`&${g}`,8));U!==-1;){let r=Q.charCodeAt(U+g.length+1);if(r===61){let Y=U+g.length+2,j=Q.indexOf("&",Y);return BQ(Q.slice(Y,j===-1?void 0:j))}else if(r==38||isNaN(r))return"";U=Q.indexOf(`&${g}`,U+1)}if(E=/[%+]/.test(Q),!E)return}let t={};E??=/[%+]/.test(Q);let a=Q.indexOf("?",8);for(;a!==-1;){let U=Q.indexOf("&",a+1),r=Q.indexOf("=",a);r>U&&U!==-1&&(r=-1);let Y=Q.slice(a+1,r===-1?U===-1?void 0:U:r);if(E&&(Y=BQ(Y)),a=U,Y==="")continue;let j;r===-1?j="":(j=Q.slice(r+1,U===-1?void 0:U),E&&(j=BQ(j))),I?(t[Y]&&Array.isArray(t[Y])||(t[Y]=[]),t[Y].push(j)):t[Y]??=j}return g?t[g]:t},rC=GC,yC=(Q,g)=>GC(Q,g,!0),iQ=decodeURIComponent;var MC=Q=>Mg(Q,iQ),rg=class{raw;#I;#A;routeIndex=0;path;bodyCache={};constructor(Q,g="/",I=[[]]){this.raw=Q,this.path=g,this.#A=I,this.#I={}}param(Q){return Q?this.#g(Q):this.#C()}#g(Q){let g=this.#A[0][this.routeIndex][1][Q],I=this.#B(g);return I&&/\%/.test(I)?MC(I):I}#C(){let Q={},g=Object.keys(this.#A[0][this.routeIndex][1]);for(let I of g){let E=this.#B(this.#A[0][this.routeIndex][1][I]);E!==void 0&&(Q[I]=/\%/.test(E)?MC(E):E)}return Q}#B(Q){return this.#A[1]?this.#A[1][Q]:Q}query(Q){return rC(this.url,Q)}queries(Q){return yC(this.url,Q)}header(Q){if(Q)return this.raw.headers.get(Q)??void 0;let g={};return this.raw.headers.forEach((I,E)=>{g[E]=I}),g}async parseBody(Q){return this.bodyCache.parsedBody??=await cC(this,Q)}#Q=Q=>{let{bodyCache:g,raw:I}=this,E=g[Q];if(E)return E;let t=Object.keys(g)[0];return t?g[t].then(a=>(t==="json"&&(a=JSON.stringify(a)),new Response(a)[Q]())):g[Q]=I[Q]()};json(){return this.#Q("text").then(Q=>JSON.parse(Q))}text(){return this.#Q("text")}arrayBuffer(){return this.#Q("arrayBuffer")}blob(){return this.#Q("blob")}formData(){return this.#Q("formData")}addValidatedData(Q,g){this.#I[Q]=g}valid(Q){return this.#I[Q]}get url(){return this.raw.url}get method(){return this.raw.method}get[aC](){return this.#A}get matchedRoutes(){return this.#A[0].map(([[,Q]])=>Q)}get routePath(){return this.#A[0].map(([[,Q]])=>Q)[this.routeIndex].path}};var nC={Stringify:1,BeforeStream:2,Stream:3},nD=(Q,g)=>{let I=new String(Q);return I.isEscaped=!0,I.callbacks=g,I};var oQ=async(Q,g,I,E,t)=>{typeof Q=="object"&&!(Q instanceof String)&&(Q instanceof Promise||(Q=Q.toString()),Q instanceof Promise&&(Q=await Q));let a=Q.callbacks;if(!a?.length)return Promise.resolve(Q);t?t[0]+=Q:t=[Q];let U=Promise.all(a.map(r=>r({phase:g,buffer:t,context:E}))).then(r=>Promise.all(r.filter(Boolean).map(Y=>oQ(Y,g,!1,E,t))).then(()=>t[0]));return I?nD(await U,a):U};var SD="text/plain; charset=UTF-8",DQ=(Q,g)=>({"Content-Type":Q,...g}),SC=class{#I;#A;env={};#g;finalized=!1;error;#C;#B;#Q;#s;#o;#D;#i;#w;#e;constructor(Q,g){this.#I=Q,g&&(this.#B=g.executionCtx,this.env=g.env,this.#D=g.notFoundHandler,this.#e=g.path,this.#w=g.matchResult)}get req(){return this.#A??=new rg(this.#I,this.#e,this.#w),this.#A}get event(){if(this.#B&&"respondWith"in this.#B)return this.#B;throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#B)return this.#B;throw Error("This context has no ExecutionContext")}get res(){return this.#Q||=new Response(null,{headers:this.#i??=new Headers})}set res(Q){if(this.#Q&&Q){Q=new Response(Q.body,Q);for(let[g,I]of this.#Q.headers.entries())if(g!=="content-type")if(g==="set-cookie"){let E=this.#Q.headers.getSetCookie();Q.headers.delete("set-cookie");for(let t of E)Q.headers.append("set-cookie",t)}else Q.headers.set(g,I)}this.#Q=Q,this.finalized=!0}render=(...Q)=>(this.#o??=g=>this.html(g),this.#o(...Q));setLayout=Q=>this.#s=Q;getLayout=()=>this.#s;setRenderer=Q=>{this.#o=Q};header=(Q,g,I)=>{this.finalized&&(this.#Q=new Response(this.#Q.body,this.#Q));let E=this.#Q?this.#Q.headers:this.#i??=new Headers;g===void 0?E.delete(Q):I?.append?E.append(Q,g):E.set(Q,g)};status=Q=>{this.#C=Q};set=(Q,g)=>{this.#g??=new Map,this.#g.set(Q,g)};get=Q=>this.#g?this.#g.get(Q):void 0;get var(){return this.#g?Object.fromEntries(this.#g):{}}#E(Q,g,I){let E=this.#Q?new Headers(this.#Q.headers):this.#i??new Headers;if(typeof g=="object"&&"headers"in g){let a=g.headers instanceof Headers?g.headers:new Headers(g.headers);for(let[U,r]of a)U.toLowerCase()==="set-cookie"?E.append(U,r):E.set(U,r)}if(I)for(let[a,U]of Object.entries(I))if(typeof U=="string")E.set(a,U);else{E.delete(a);for(let r of U)E.append(a,r)}let t=typeof g=="number"?g:g?.status??this.#C;return new Response(Q,{status:t,headers:E})}newResponse=(...Q)=>this.#E(...Q);body=(Q,g,I)=>this.#E(Q,g,I);text=(Q,g,I)=>!this.#i&&!this.#C&&!g&&!I&&!this.finalized?new Response(Q):this.#E(Q,g,DQ(SD,I));json=(Q,g,I)=>this.#E(JSON.stringify(Q),g,DQ("application/json",I));html=(Q,g,I)=>{let E=t=>this.#E(t,g,DQ("text/html; charset=UTF-8",I));return typeof Q=="object"?oQ(Q,nC.Stringify,!1,{}).then(E):E(Q)};redirect=(Q,g)=>{let I=String(Q);return this.header("Location",/[^\x00-\xFF]/.test(I)?encodeURI(I):I),this.newResponse(null,g??302)};notFound=()=>(this.#D??=()=>new Response,this.#D(this))};var qA="ALL",LC="all",kC=["get","post","put","delete","options","patch"],Sg="Can not add a route since the matcher is already built.",Lg=class extends Error{};var JC="__COMPOSED_HANDLER";var LD=Q=>Q.text("404 Not Found",404),KC=(Q,g)=>{if("getResponse"in Q){let I=Q.getResponse();return g.newResponse(I.body,I)}return console.error(Q),g.text("Internal Server Error",500)},sQ=class{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#I="/";routes=[];constructor(Q={}){[...kC,LC].forEach(t=>{this[t]=(a,...U)=>(typeof a=="string"?this.#I=a:this.#C(t,this.#I,a),U.forEach(r=>{this.#C(t,this.#I,r)}),this)}),this.on=(t,a,...U)=>{for(let r of[a].flat()){this.#I=r;for(let Y of[t].flat())U.map(j=>{this.#C(Y.toUpperCase(),this.#I,j)})}return this},this.use=(t,...a)=>(typeof t=="string"?this.#I=t:(this.#I="*",a.unshift(t)),a.forEach(U=>{this.#C(qA,this.#I,U)}),this);let{strict:I,...E}=Q;Object.assign(this,E),this.getPath=I??!0?Q.getPath??EQ:NC}#A(){let Q=new sQ({router:this.router,getPath:this.getPath});return Q.errorHandler=this.errorHandler,Q.#g=this.#g,Q.routes=this.routes,Q}#g=LD;errorHandler=KC;route(Q,g){let I=this.basePath(Q);return g.routes.map(E=>{let t;g.errorHandler===KC?t=E.handler:(t=async(a,U)=>(await QQ([],g.errorHandler)(a,()=>E.handler(a,U))).res,t[JC]=E.handler),I.#C(E.method,E.path,t)}),this}basePath(Q){let g=this.#A();return g._basePath=SI(this._basePath,Q),g}onError=Q=>(this.errorHandler=Q,this);notFound=Q=>(this.#g=Q,this);mount(Q,g,I){let E,t;I&&(typeof I=="function"?t=I:(t=I.optionHandler,I.replaceRequest===!1?E=r=>r:E=I.replaceRequest));let a=t?r=>{let Y=t(r);return Array.isArray(Y)?Y:[Y]}:r=>{let Y;try{Y=r.executionCtx}catch{}return[r.env,Y]};E||=(()=>{let r=SI(this._basePath,Q),Y=r==="/"?0:r.length;return j=>{let BA=new URL(j.url);return BA.pathname=BA.pathname.slice(Y)||"/",new Request(BA,j)}})();let U=async(r,Y)=>{let j=await g(E(r.req.raw),...a(r));if(j)return j;await Y()};return this.#C(qA,SI(Q,"*"),U),this}#C(Q,g,I){Q=Q.toUpperCase(),g=SI(this._basePath,g);let E={basePath:this._basePath,path:g,method:Q,handler:I};this.router.add(Q,g,[I,E]),this.routes.push(E)}#B(Q,g){if(Q instanceof Error)return this.errorHandler(Q,g);throw Q}#Q(Q,g,I,E){if(E==="HEAD")return(async()=>new Response(null,await this.#Q(Q,g,I,"GET")))();let t=this.getPath(Q,{env:I}),a=this.router.match(E,t),U=new SC(Q,{path:t,matchResult:a,env:I,executionCtx:g,notFoundHandler:this.#g});if(a[0].length===1){let Y;try{Y=a[0][0][0][0](U,async()=>{U.res=await this.#g(U)})}catch(j){return this.#B(j,U)}return Y instanceof Promise?Y.then(j=>j||(U.finalized?U.res:this.#g(U))).catch(j=>this.#B(j,U)):Y??this.#g(U)}let r=QQ(a[0],this.errorHandler,this.#g);return(async()=>{try{let Y=await r(U);if(!Y.finalized)throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return Y.res}catch(Y){return this.#B(Y,U)}})()}fetch=(Q,...g)=>this.#Q(Q,g[1],g[0],Q.method);request=(Q,g,I,E)=>Q instanceof Request?this.fetch(g?new Request(Q,g):Q,I,E):(Q=Q.toString(),this.fetch(new Request(/^https?:\/\//.test(Q)?Q:`http://localhost${SI("/",Q)}`,g),I,E));fire=()=>{addEventListener("fetch",Q=>{Q.respondWith(this.#Q(Q.request,Q,void 0,Q.request.method))})}};var kg=[];function wQ(Q,g){let I=this.buildAllMatchers(),E=(t,a)=>{let U=I[t]||I[qA],r=U[2][a];if(r)return r;let Y=a.match(U[0]);if(!Y)return[[],kg];let j=Y.indexOf("",1);return[U[1][j],Y]};return this.match=E,E(Q,g)}var Jg="[^/]+",zI=".*",$I="(?:|/.*)",LI=Symbol(),kD=new Set(".\\+*[^]$()");function JD(Q,g){return Q.length===1?g.length===1?Q<g?-1:1:-1:g.length===1||Q===zI||Q===$I?1:g===zI||g===$I?-1:Q===Jg?1:g===Jg?-1:Q.length===g.length?Q<g?-1:1:g.length-Q.length}var Kg=class{#I;#A;#g=Object.create(null);insert(Q,g,I,E,t){if(Q.length===0){if(this.#I!==void 0)throw LI;if(t)return;this.#I=g;return}let[a,...U]=Q,r=a==="*"?U.length===0?["","",zI]:["","",Jg]:a==="/*"?["","",$I]:a.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),Y;if(r){let j=r[1],BA=r[2]||Jg;if(j&&r[2]&&(BA===".*"||(BA=BA.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(BA))))throw LI;if(Y=this.#g[BA],!Y){if(Object.keys(this.#g).some(QA=>QA!==zI&&QA!==$I))throw LI;if(t)return;Y=this.#g[BA]=new Kg,j!==""&&(Y.#A=E.varIndex++)}!t&&j!==""&&I.push([j,Y.#A])}else if(Y=this.#g[a],!Y){if(Object.keys(this.#g).some(j=>j.length>1&&j!==zI&&j!==$I))throw LI;if(t)return;Y=this.#g[a]=new Kg}Y.insert(U,g,I,E,t)}buildRegExpStr(){let g=Object.keys(this.#g).sort(JD).map(I=>{let E=this.#g[I];return(typeof E.#A=="number"?`(${I})@${E.#A}`:kD.has(I)?`\\${I}`:I)+E.buildRegExpStr()});return typeof this.#I=="number"&&g.unshift(`#${this.#I}`),g.length===0?"":g.length===1?g[0]:"(?:"+g.join("|")+")"}};var lC=class{#I={varIndex:0};#A=new Kg;insert(Q,g,I){let E=[],t=[];for(let U=0;;){let r=!1;if(Q=Q.replace(/\{[^}]+\}/g,Y=>{let j=`@\\${U}`;return t[U]=[j,Y],U++,r=!0,j}),!r)break}let a=Q.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let U=t.length-1;U>=0;U--){let[r]=t[U];for(let Y=a.length-1;Y>=0;Y--)if(a[Y].indexOf(r)!==-1){a[Y]=a[Y].replace(r,t[U][1]);break}}return this.#A.insert(a,g,E,this.#I,I),E}buildRegExp(){let Q=this.#A.buildRegExpStr();if(Q==="")return[/^$/,[],[]];let g=0,I=[],E=[];return Q=Q.replace(/#(\d+)|@(\d+)|\.\*\$/g,(t,a,U)=>a!==void 0?(I[++g]=Number(a),"$()"):(U!==void 0&&(E[Number(U)]=++g),"")),[new RegExp(`^${Q}`),I,E]}};var KD=[/^$/,[],Object.create(null)],YC=Object.create(null);function HC(Q){return YC[Q]??=new RegExp(Q==="*"?"":`^${Q.replace(/\/\*$|([.\\+*[^\]$()])/g,(g,I)=>I?`\\${I}`:"(?:|/.*)")}$`)}function lD(){YC=Object.create(null)}function YD(Q){let g=new lC,I=[];if(Q.length===0)return KD;let E=Q.map(j=>[!/\*|\/:/.test(j[0]),...j]).sort(([j,BA],[QA,DA])=>j?1:QA?-1:BA.length-DA.length),t=Object.create(null);for(let j=0,BA=-1,QA=E.length;j<QA;j++){let[DA,MA,UA]=E[j];DA?t[MA]=[UA.map(([fA])=>[fA,Object.create(null)]),kg]:BA++;let kA;try{kA=g.insert(MA,BA,DA)}catch(fA){throw fA===LI?new Lg(MA):fA}DA||(I[BA]=UA.map(([fA,uA])=>{let OA=Object.create(null);for(uA-=1;uA>=0;uA--){let[WA,iI]=kA[uA];OA[WA]=iI}return[fA,OA]}))}let[a,U,r]=g.buildRegExp();for(let j=0,BA=I.length;j<BA;j++)for(let QA=0,DA=I[j].length;QA<DA;QA++){let MA=I[j][QA]?.[1];if(!MA)continue;let UA=Object.keys(MA);for(let kA=0,fA=UA.length;kA<fA;kA++)MA[UA[kA]]=r[MA[UA[kA]]]}let Y=[];for(let j in U)Y[j]=I[U[j]];return[a,Y,t]}function xI(Q,g){if(Q){for(let I of Object.keys(Q).sort((E,t)=>t.length-E.length))if(HC(I).test(g))return[...Q[I]]}}var lg=class{name="RegExpRouter";#I;#A;constructor(){this.#I={[qA]:Object.create(null)},this.#A={[qA]:Object.create(null)}}add(Q,g,I){let E=this.#I,t=this.#A;if(!E||!t)throw new Error(Sg);E[Q]||[E,t].forEach(r=>{r[Q]=Object.create(null),Object.keys(r[qA]).forEach(Y=>{r[Q][Y]=[...r[qA][Y]]})}),g==="/*"&&(g="*");let a=(g.match(/\/:/g)||[]).length;if(/\*$/.test(g)){let r=HC(g);Q===qA?Object.keys(E).forEach(Y=>{E[Y][g]||=xI(E[Y],g)||xI(E[qA],g)||[]}):E[Q][g]||=xI(E[Q],g)||xI(E[qA],g)||[],Object.keys(E).forEach(Y=>{(Q===qA||Q===Y)&&Object.keys(E[Y]).forEach(j=>{r.test(j)&&E[Y][j].push([I,a])})}),Object.keys(t).forEach(Y=>{(Q===qA||Q===Y)&&Object.keys(t[Y]).forEach(j=>r.test(j)&&t[Y][j].push([I,a]))});return}let U=ng(g)||[g];for(let r=0,Y=U.length;r<Y;r++){let j=U[r];Object.keys(t).forEach(BA=>{(Q===qA||Q===BA)&&(t[BA][j]||=[...xI(E[BA],j)||xI(E[qA],j)||[]],t[BA][j].push([I,a-Y+r+1]))})}}match=wQ;buildAllMatchers(){let Q=Object.create(null);return Object.keys(this.#A).concat(Object.keys(this.#I)).forEach(g=>{Q[g]||=this.#g(g)}),this.#I=this.#A=void 0,lD(),Q}#g(Q){let g=[],I=Q===qA;return[this.#I,this.#A].forEach(E=>{let t=E[Q]?Object.keys(E[Q]).map(a=>[a,E[Q][a]]):[];t.length!==0?(I||=!0,g.push(...t)):Q!==qA&&g.push(...Object.keys(E[qA]).map(a=>[a,E[qA][a]]))}),I?YD(g):null}};var eQ=class{name="SmartRouter";#I=[];#A=[];constructor(Q){this.#I=Q.routers}add(Q,g,I){if(!this.#A)throw new Error(Sg);this.#A.push([Q,g,I])}match(Q,g){if(!this.#A)throw new Error("Fatal error");let I=this.#I,E=this.#A,t=I.length,a=0,U;for(;a<t;a++){let r=I[a];try{for(let Y=0,j=E.length;Y<j;Y++)r.add(...E[Y]);U=r.match(Q,g)}catch(Y){if(Y instanceof Lg)continue;throw Y}this.match=r.match.bind(r),this.#I=[r],this.#A=void 0;break}if(a===t)throw new Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,U}get activeRouter(){if(this.#A||this.#I.length!==1)throw new Error("No active router has been determined yet.");return this.#I[0]}};var Ag=Object.create(null),tQ=class{#I;#A;#g;#C=0;#B=Ag;constructor(Q,g,I){if(this.#A=I||Object.create(null),this.#I=[],Q&&g){let E=Object.create(null);E[Q]={handler:g,possibleKeys:[],score:0},this.#I=[E]}this.#g=[]}insert(Q,g,I){this.#C=++this.#C;let E=this,t=hC(g),a=[];for(let U=0,r=t.length;U<r;U++){let Y=t[U],j=t[U+1],BA=UC(Y,j),QA=Array.isArray(BA)?BA[0]:Y;if(QA in E.#A){E=E.#A[QA],BA&&a.push(BA[1]);continue}E.#A[QA]=new tQ,BA&&(E.#g.push(BA),a.push(BA[1])),E=E.#A[QA]}return E.#I.push({[Q]:{handler:I,possibleKeys:a.filter((U,r,Y)=>Y.indexOf(U)===r),score:this.#C}}),E}#Q(Q,g,I,E){let t=[];for(let a=0,U=Q.#I.length;a<U;a++){let r=Q.#I[a],Y=r[g]||r[qA],j={};if(Y!==void 0&&(Y.params=Object.create(null),t.push(Y),I!==Ag||E&&E!==Ag))for(let BA=0,QA=Y.possibleKeys.length;BA<QA;BA++){let DA=Y.possibleKeys[BA],MA=j[Y.score];Y.params[DA]=E?.[DA]&&!MA?E[DA]:I[DA]??E?.[DA],j[Y.score]=!0}}return t}search(Q,g){let I=[];this.#B=Ag;let t=[this],a=CQ(g),U=[];for(let r=0,Y=a.length;r<Y;r++){let j=a[r],BA=r===Y-1,QA=[];for(let DA=0,MA=t.length;DA<MA;DA++){let UA=t[DA],kA=UA.#A[j];kA&&(kA.#B=UA.#B,BA?(kA.#A["*"]&&I.push(...this.#Q(kA.#A["*"],Q,UA.#B)),I.push(...this.#Q(kA,Q,UA.#B))):QA.push(kA));for(let fA=0,uA=UA.#g.length;fA<uA;fA++){let OA=UA.#g[fA],WA=UA.#B===Ag?{}:{...UA.#B};if(OA==="*"){let CI=UA.#A["*"];CI&&(I.push(...this.#Q(CI,Q,UA.#B)),CI.#B=WA,QA.push(CI));continue}let[iI,pI,FI]=OA;if(!j&&!(FI instanceof RegExp))continue;let II=UA.#A[iI],qg=a.slice(r).join("/");if(FI instanceof RegExp){let CI=FI.exec(qg);if(CI){if(WA[pI]=CI[0],I.push(...this.#Q(II,Q,UA.#B,WA)),Object.keys(II.#A).length){II.#B=WA;let gI=CI[0].match(/\//)?.length??0;(U[gI]||=[]).push(II)}continue}}(FI===!0||FI.test(j))&&(WA[pI]=j,BA?(I.push(...this.#Q(II,Q,WA,UA.#B)),II.#A["*"]&&I.push(...this.#Q(II.#A["*"],Q,WA,UA.#B))):(II.#B=WA,QA.push(II)))}}t=QA.concat(U.shift()??[])}return I.length>1&&I.sort((r,Y)=>r.score-Y.score),[I.map(({handler:r,params:Y})=>[r,Y])]}};var FQ=class{name="TrieRouter";#I;constructor(){this.#I=new tQ}add(Q,g,I){let E=ng(g);if(E){for(let t=0,a=E.length;t<a;t++)this.#I.insert(Q,E[t],I);return}this.#I.insert(Q,g,I)}match(Q,g){return this.#I.search(Q,g)}};var zA=class extends sQ{constructor(Q={}){super(Q),this.router=Q.router??new eQ({routers:[new lg,new FQ]})}};var HD=8e3,dC=Symbol("nx-cache-get-deadline");function fD(Q,g){return g>0?new Promise((I,E)=>{let t=setTimeout(()=>I(dC),g);Q.then(a=>{clearTimeout(t),I(a)},a=>{clearTimeout(t),E(a)})}):Q}function fC(Q){return Q?`hit size=${Q.size}`:"miss"}function dD(Q){return Q instanceof Error?Q.message:String(Q)}function RQ(Q){let g=new zA,I=Q.now??(()=>Date.now()),E=Q.getDeadlineMs??HD,t=(a,U,r)=>{a.then(Y=>{Y?.stream.cancel().catch(()=>{}),Q.log?.(`nx get ${U} relay settled after deadline -> ${fC(Y)} (${I()-r}ms)`)},Y=>Q.log?.(`nx get ${U} relay failed after deadline: ${dD(Y)}`))};return g.get("/blob/nx/v1/cache/:hash",async a=>{let U=a.req.param("hash"),r=I();Q.log?.(`nx get ${U} start`);let Y=Q.blob.get(U,{relay:!0}),j=await fD(Y,E);return j===dC?(Q.log?.(`nx get ${U} -> miss deadline=${E}ms (${I()-r}ms, relay continues)`),t(Y,U,r),Q.respond(a,null)):(Q.log?.(`nx get ${U} -> ${fC(j)} (${I()-r}ms)`),Q.respond(a,j))}),g.put("/blob/nx/v1/cache/:hash",async a=>{let U=a.req.param("hash"),r=I(),Y=await Q.blob.put(a.req.raw.body??Buffer.alloc(0));return await Q.blob.bind(U,Y),Q.log?.(`nx put ${U} -> root=${Y} (${I()-r}ms)`),a.body(null,200)}),g}function qC(Q){return async(g,I)=>{if(g.req.header("authorization")!==`Bearer ${Q}`)return g.body(null,401);await I()}}function Yg(Q,g){return g?Q.body(g.stream,200,{"content-type":"application/octet-stream","content-length":String(g.size)}):Q.body(null,404)}function uC(Q){let g=new zA;return g.on("HEAD","/blob/objects/:hash",async I=>{let E=await Q.get(I.req.param("hash"),{relay:!1});return E?(await E.stream.cancel(),I.body(null,200)):I.body(null,404)}),g.get("/blob/objects/:hash",async I=>{if(I.req.query("raw")==="1"){let t=await Q.store.read(I.req.param("hash"));return t?I.body(new Uint8Array(t),200,{"content-type":"application/octet-stream","content-length":String(t.length)}):I.body(null,404)}let E=I.req.query("noRelay")!=="1";return Yg(I,await Q.get(I.req.param("hash"),{relay:E}))}),g.put("/blob/objects/:hash",async I=>(await Q.store.write(I.req.param("hash"),I.req.raw.body??Buffer.alloc(0)),I.body(null,200))),g}function xC(Q){let g=new zA;return g.get("/blob/metrics",async I=>{let E=Q.metrics.snapshot();return I.json({...E,totalBytes:await Q.store.totalBytes()})}),g}var qD=4096;function bC(Q){let g=new zA;return g.post("/blob/have",async I=>{let E=await pC(I);if(!E)return I.body(null,400);let t=[];for(let a of E)await Q.store.has(a)||t.push(a);return I.json({missing:t})}),g.post("/blob/batch",async I=>{let E=await pC(I);if(!E)return I.body(null,400);let t={},a=[];for(let U of E){let r=await Q.store.read(U);r?t[U]=r.toString("base64"):a.push(U)}return I.json({blobs:t,missing:a})}),g}async function pC(Q){try{let g=await Q.req.json();return!Array.isArray(g)||g.length>qD?null:g.filter(I=>typeof I=="string")}catch{return null}}function VC(Q){let g=new zA;return g.get("/blob/aliases/:name",async I=>{let E=await Q.store.resolveAlias(I.req.param("name"));return E?I.text(E,200):I.body(null,404)}),g.put("/blob/aliases/:name",async I=>{let E=(await I.req.text()).trim();return eI(E)?(await Q.store.setAlias(I.req.param("name"),E),I.body(null,200)):I.body(null,400)}),g}var uD="20.5.4";function TC(Q){let g=new zA,I=async()=>{let E=await Q.retention.status(),{status:t,...a}=E;return{status:t,store:a,service:"blob",version:uD}};return g.get("/blob/healthz",async E=>E.json(await I())),g.get("/health",async E=>E.json(await I())),g.use("*",qC(Q.token)),g.route("/",RQ({blob:Q.usecase,respond:Yg,log:E=>console.log(`[planx-blob] ${E}`),getDeadlineMs:Q.nxGetDeadlineMs})),g.route("/",uC(Q.usecase)),g.route("/",xC(Q.usecase)),g.route("/",bC(Q.usecase)),g.route("/",VC(Q.usecase)),g}var mC="planx-blob";function WC(Q,g){let I={},E=Q.PLANX_SERVER_NAME;if(E){I.serverName=E;let r=g(`/tmp/planx/${E}/transport.port`),Y=r===null?NaN:parseInt(r.trim(),10);Number.isInteger(Y)&&Y>0&&(I.transportPort=Y)}let t=aQ(Q,"PLANX_BLOB_TRANSPORT_PORT");t!==void 0&&(I.transportPort=t);let a=aQ(Q,"PLANX_BLOB_PORT",{allowZero:!0});a!==void 0&&(I.port=a),Q.PLANX_BLOB_STORE&&(I.storeDir=Q.PLANX_BLOB_STORE),Q.PLANX_BLOB_TOKEN&&(I.token=Q.PLANX_BLOB_TOKEN);let U=aQ(Q,"PLANX_BLOB_MAX_BYTES");return U!==void 0&&(I.maxBytes=U),I}function ZC(Q,g){return[`/tmp/planx/${Q}/blob.port`,`${g}/.planx/${Q}/blob.port`]}function aQ(Q,g,I={}){let E=Q[g];if(!E)return;let t=parseInt(E,10),a=I.allowZero?0:1;if(!Number.isInteger(t)||t<a)throw new Error(`${g} must be an integer >= ${a}: ${E}`);return t}var Hg=class{constructor(g){this.peers=g}setPeers(g){this.peers=g}async livePeers(){return this.peers}};var xD="blob",fg=class{constructor(g){this.options=g;this.selfId=null;this.warned=!1}async livePeers(){try{let g=await this.resolveSelfId();return(await this.fetchJson("/servers")).filter(E=>typeof E.id=="string"&&E.id.length>0).filter(E=>E.id!==g).map(E=>({id:E.id,baseUrl:`${this.options.transportBaseUrl}/servers/${E.id}/${xD}`}))}catch(g){if(!this.warned){this.warned=!0;let I=g instanceof Error?g.message:String(g);console.error(`[blob] transport peers unavailable (${this.options.transportBaseUrl}): ${I}`)}return[]}}async resolveSelfId(){if(this.selfId!==null)return this.selfId;let g=await this.fetchJson("/peer");return this.selfId=g.peerId??"",this.selfId}async fetchJson(g){let I=await fetch(`${this.options.transportBaseUrl}${g}`,{signal:AbortSignal.timeout(this.options.timeoutMs??1500)});if(!I.ok)throw new Error(`GET ${g} -> ${I.status}`);return await I.json()}};var dg=class{constructor(g,I={}){this.upstream=g;this.options=I;this.cached=null;this.fetchedAt=0;this.inflight=null}async livePeers(){return this.cached!==null&&!this.isExpired()?this.cached:this.cached!==null?(this.refresh(),this.cached):(await this.refresh(),this.cached??[])}isExpired(){let g=this.options.ttlMs??5e3;return this.now()-this.fetchedAt>=g}now(){return(this.options.now??Date.now)()}refresh(){return this.inflight?this.inflight:(this.inflight=this.upstream.livePeers().then(g=>{this.cached=g,this.fetchedAt=this.now()}).catch(()=>{}).finally(()=>{this.inflight=null}),this.inflight)}};function PC(Q){return Q.transportPort?new dg(new fg({transportBaseUrl:`http://127.0.0.1:${Q.transportPort}`})):new Hg(Q.peers)}function OC(Q){let g={};for(let I=0;I<Q.length;I+=1){let E=Q[I],t=Q[I+1];if(!(t===void 0||t.startsWith("--"))&&(E==="--name"&&(g.name=t),E==="--store"&&(g.storeDir=t),E==="--port")){let a=Number(t);if(!Number.isInteger(a)||a<0)throw new Error(`invalid --port: ${t}`);g.port=a}}return g}var ZD=_g.maxBytes;function PD(Q,g){for(let I of ZC(Q,XC()))try{VD(pD(I),{recursive:!0});let E=`${I}.${process.pid}.wip`;WD(E,String(g)),mD(E,I)}catch(E){console.error(`[planx-blob] blob.port write failed (${I}): ${String(E)}`)}}async function jC(Q){let g=WC(Q.env,DA=>{try{return TD(DA,"utf-8")}catch{return null}}),I=OC(Q.argv),E=g.serverName??I.name,t={port:I.port??g.port??0,host:"127.0.0.1",storeDir:I.storeDir??g.storeDir??bD(XC(),".cache","planx-blob"),token:g.token??mC,peers:[],transportPort:g.transportPort,maxBytes:g.maxBytes??ZD},a={..._g,maxBytes:t.maxBytes},U=new cg({dir:t.storeDir,wipGraceMs:a.wipGraceMs}),r=new uI,Y=new hg(U,a,r),j=new Gg(U,PC(t),new Ug({token:t.token}),{metrics:r,retention:Y}),BA=TB(Y,a.retainIntervalMs),QA=TC({usecase:j,retention:Y,token:t.token});return await new Promise((DA,MA)=>{(kA=>{let fA=PQ({fetch:QA.fetch,port:kA,hostname:t.host},uA=>{E&&PD(E,uA.port),Q.emitLine(JSON.stringify({service:"blob",port:uA.port,pid:process.pid})),DA({storeDir:t.storeDir,port:uA.port,maxBytes:t.maxBytes,close:()=>new Promise(OA=>{BA(),fA.closeAllConnections?.(),U.close(),fA.close(()=>OA())})})});fA.on("error",uA=>{MA(uA instanceof Error?uA:new Error(String(uA)))})})(t.port)})}jC({argv:process.argv.slice(2),env:process.env,emitLine:Q=>process.stdout.write(`${Q}
48
48
  `)}).then(Q=>{let g=()=>{Q.close().finally(()=>process.exit(0))};process.on("SIGTERM",g),process.on("SIGINT",g),process.stdin.resume(),process.stdin.on("end",()=>process.exit(1)),process.on("uncaughtException",(I,E)=>{try{process.stderr.write(`[planx-blob] Uncaught exception (${E}): ${I instanceof Error?I.message:String(I)}
49
49
  `)}catch{}process.exit(1)})}).catch(Q=>{console.error(`[planx-blob] child boot failed: ${String(Q)}`),process.exit(1)});
50
50
  /*! Bundled license information: