@artemjs/vfskit 1.2.0 → 1.2.1

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/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <h1 align="center">vfskit</h1>
6
6
 
7
7
  <p align="center">
8
- <img src="https://img.shields.io/badge/version-1.2.0-7c8cff?style=flat-square" alt="version">
8
+ <img src="https://img.shields.io/badge/version-1.2.1-7c8cff?style=flat-square" alt="version">
9
9
  <img src="https://img.shields.io/badge/license-MIT-56e6c4?style=flat-square" alt="license">
10
10
  <img src="https://img.shields.io/badge/TypeScript-strict-3178c6?style=flat-square" alt="typescript">
11
11
  <img src="https://img.shields.io/badge/module-ESM-f0db4f?style=flat-square" alt="esm">
@@ -1 +1 @@
1
- var h=new TextEncoder,b=new TextDecoder;function w(e){return typeof e=="string"?h.encode(e):e instanceof Uint8Array?e:new Uint8Array(e)}function s(e){return b.decode(e)}function d(e){let t=0;for(let i of e)t+=i.length;let a=new Uint8Array(t),n=0;for(let i of e)a.set(i,n),n+=i.length;return a}var m=Symbol.for("vfskit.VfsError"),f=class extends Error{code;path;[m]=!0;constructor(t,a,n){super(a),this.name="VfsError",this.code=t,this.path=n}};function u(e){return typeof e=="object"&&e!==null&&e[m]===!0}async function y(e,t,a){if(e.readStream)return e.readStream(t,a);let n=await e.read(t,a);return new ReadableStream({start(i){i.enqueue(n),i.close()}})}async function p(e,t,a){if(e.writeStream)return e.writeStream(t,a);let n=[];return new WritableStream({write(i){n.push(i)},async close(){await e.write(t,d(n),a)}})}async function l(e){let t=[],a=e.getReader();for(;;){let{done:n,value:i}=await a.read();if(n)break;i&&t.push(i)}return d(t)}function x(e){throw new Error("conformance: "+e)}function c(e,t="expected truthy"){e||x(t)}function r(e,t,a){e!==t&&x(a??`expected ${JSON.stringify(t)}, got ${JSON.stringify(e)}`)}async function o(e,t){let a;try{await e()}catch(n){a=n}c(u(a)&&a.code===t,`expected error ${t}, got ${u(a)?a.code:a}`)}async function S(e){let t;try{await e()}catch(a){t=a}c(t,"expected throw")}async function E(e,t=2e3){for(let n=0;n<t;n+=10){if(e())return;await new Promise(i=>setTimeout(i,10))}}var g=[{name:"writes and reads a file",async run(e){let t=e();await t.write("/a.txt","hello"),r(s(await t.read("/a.txt")),"hello")}},{name:"reports existence",async run(e){let t=e();r(await t.exists("/a.txt"),!1),await t.write("/a.txt","x"),r(await t.exists("/a.txt"),!0)}},{name:"stats a file",async run(e){let t=e();await t.write("/a.txt","hello");let a=await t.stat("/a.txt");r(a.type,"file"),c(a.size>0)}},{name:"throws NOT_FOUND for missing read",async run(e){let t=e();await o(()=>t.read("/nope"),"NOT_FOUND")}},{name:"lists directory children",async run(e){let t=e();await t.mkdir("/d"),await t.write("/d/a","1"),await t.write("/d/b","2"),r((await t.list("/d")).map(a=>a.name).sort().join(","),"a,b")}},{name:"lists recursively",async run(e){let t=e();await t.mkdir("/d"),await t.mkdir("/d/sub"),await t.write("/d/sub/a","1"),c((await t.list("/d",{recursive:!0})).some(a=>a.path==="/d/sub/a"))}},{name:"removes a file",async run(e){let t=e();await t.write("/a","1"),await t.remove("/a"),r(await t.exists("/a"),!1)}},{name:"requires recursive to remove a non-empty dir",async run(e){let t=e();await t.mkdir("/d"),await t.write("/d/a","1"),await S(()=>t.remove("/d")),await t.remove("/d",{recursive:!0}),r(await t.exists("/d"),!1)}},{name:"moves a file",async run(e){let t=e();await t.write("/a","1"),await t.move("/a","/b"),r(await t.exists("/a"),!1),r(s(await t.read("/b")),"1")}},{name:"copies a file",async run(e){let t=e();await t.write("/a","1"),await t.copy("/a","/b"),r(s(await t.read("/a")),"1"),r(s(await t.read("/b")),"1")}},{name:"stores and reads metadata",async run(e){let t=e();await t.write("/a","1",{meta:{tag:"x"}}),r((await t.getMeta("/a")).tag,"x"),await t.setMeta("/a",{tag:"y"}),r((await t.getMeta("/a")).tag,"y")}},{name:"emits watch events when supported",async run(e){let t=e();if(!t.capabilities().watch)return;let a=[],n=t.watch("/",i=>a.push(i.type+":"+i.path));await new Promise(i=>setTimeout(i,60)),await t.write("/a","1"),await E(()=>a.includes("create:/a")),n(),c(a.includes("create:/a"))}},{name:"moves a directory subtree",async run(e){let t=e();await t.mkdir("/d"),await t.mkdir("/d/sub"),await t.write("/d/sub/a","1"),await t.move("/d","/e"),r(await t.exists("/d"),!1),r(s(await t.read("/e/sub/a")),"1")}},{name:"copies a directory subtree deeply",async run(e){let t=e();await t.mkdir("/d"),await t.write("/d/a","1"),await t.copy("/d","/e"),await t.write("/e/a","2"),r(s(await t.read("/d/a")),"1"),r(s(await t.read("/e/a")),"2")}},{name:"isolates returned read buffers from the store",async run(e){let t=e();await t.write("/a","abc");let a=await t.read("/a");a[0]=0,r(s(await t.read("/a")),"abc")}},{name:"does not confuse sibling prefixes",async run(e){let t=e();await t.mkdir("/d"),await t.mkdir("/dx"),await t.write("/dx/a","1"),c(!(await t.list("/d")).some(a=>a.name==="a"))}},{name:"reports byte size matching written content",async run(e){let t=e();await t.write("/a","hello"),r((await t.stat("/a")).size,5)}},{name:"throws ALREADY_EXISTS creating an existing dir without recursive",async run(e){let t=e();await t.mkdir("/d"),await o(()=>t.mkdir("/d"),"ALREADY_EXISTS")}},{name:"preserves metadata when overwriting content without new meta",async run(e){let t=e();await t.write("/a","1",{meta:{tag:"x"}}),await t.write("/a","2"),r((await t.getMeta("/a")).tag,"x")}},{name:"throws NOT_A_DIRECTORY creating a directory under a file",async run(e){let t=e();await t.write("/f","1"),await o(()=>t.mkdir("/f/sub",{recursive:!0}),"NOT_A_DIRECTORY")}},{name:"throws ALREADY_EXISTS moving or copying onto an existing path",async run(e){let t=e();await t.write("/a","1"),await t.write("/b","2"),await o(()=>t.move("/a","/b"),"ALREADY_EXISTS"),await o(()=>t.copy("/a","/b"),"ALREADY_EXISTS")}},{name:"conditional write succeeds on matching version and CONFLICTs on stale (when capable)",async run(e){let t=e();if(!t.capabilities().conditionalWrite)return;await t.write("/a","1");let a=(await t.stat("/a")).version;c(typeof a=="string"&&a.length>0,"expected a version token"),await t.write("/a","2",{ifMatch:a}),r(s(await t.read("/a")),"2"),await o(()=>t.write("/a","3",{ifMatch:a}),"CONFLICT"),r(s(await t.read("/a")),"2")}},{name:"ifAbsent rejects overwriting an existing file (when capable)",async run(e){let t=e();t.capabilities().conditionalWrite&&(await t.write("/a","1"),await o(()=>t.write("/a","2",{ifAbsent:!0}),"ALREADY_EXISTS"),r(s(await t.read("/a")),"1"))}},{name:"streams content in and back out (helper, native or buffered)",async run(e){let t=e(),n=(await p(t,"/s.bin")).getWriter();await n.write(w("chunk-one;")),await n.write(w("chunk-two")),await n.close(),r(s(await l(await y(t,"/s.bin"))),"chunk-one;chunk-two"),r(s(await t.read("/s.bin")),"chunk-one;chunk-two")}}];function A(e){let t=globalThis;t.describe("vfs conformance",()=>{for(let a of g)t.it(a.name,()=>a.run(e))})}export{g as conformanceCases,A as runConformance};
1
+ var h=new TextEncoder,v=new TextDecoder;function w(a){return typeof a=="string"?h.encode(a):a instanceof Uint8Array?a:new Uint8Array(a)}function o(a){return v.decode(a)}function d(a){let t=0;for(let i of a)t+=i.length;let e=new Uint8Array(t),n=0;for(let i of a)e.set(i,n),n+=i.length;return e}var m=Symbol.for("vfskit.VfsError"),u=class extends Error{code;path;[m]=!0;constructor(t,e,n){super(e),this.name="VfsError",this.code=t,this.path=n}};function f(a){return typeof a=="object"&&a!==null&&a[m]===!0}async function y(a,t,e){if(a.readStream)return a.readStream(t,e);let n=await a.read(t,e);return new ReadableStream({start(i){i.enqueue(n),i.close()}})}async function p(a,t,e){if(a.writeStream)return a.writeStream(t,e);let n=[];return new WritableStream({write(i){n.push(i)},async close(){await a.write(t,d(n),e)}})}async function l(a){let t=[],e=a.getReader();for(;;){let{done:n,value:i}=await e.read();if(n)break;i&&t.push(i)}return d(t)}function x(a){throw new Error("conformance: "+a)}function c(a,t="expected truthy"){a||x(t)}function r(a,t,e){a!==t&&x(e??`expected ${JSON.stringify(t)}, got ${JSON.stringify(a)}`)}async function s(a,t){let e;try{await a()}catch(n){e=n}c(f(e)&&e.code===t,`expected error ${t}, got ${f(e)?e.code:e}`)}async function b(a){let t;try{await a()}catch(e){t=e}c(t,"expected throw")}async function S(a,t=2e3){for(let n=0;n<t;n+=10){if(a())return;await new Promise(i=>setTimeout(i,10))}}var g=[{name:"writes and reads a file",async run(a){let t=a();await t.write("/a.txt","hello"),r(o(await t.read("/a.txt")),"hello")}},{name:"reports existence",async run(a){let t=a();r(await t.exists("/a.txt"),!1),await t.write("/a.txt","x"),r(await t.exists("/a.txt"),!0)}},{name:"stats a file",async run(a){let t=a();await t.write("/a.txt","hello");let e=await t.stat("/a.txt");r(e.type,"file"),c(e.size>0)}},{name:"throws NOT_FOUND for missing read",async run(a){let t=a();await s(()=>t.read("/nope"),"NOT_FOUND")}},{name:"lists directory children",async run(a){let t=a();await t.mkdir("/d"),await t.write("/d/a","1"),await t.write("/d/b","2"),r((await t.list("/d")).map(e=>e.name).sort().join(","),"a,b")}},{name:"lists recursively",async run(a){let t=a();await t.mkdir("/d"),await t.mkdir("/d/sub"),await t.write("/d/sub/a","1"),c((await t.list("/d",{recursive:!0})).some(e=>e.path==="/d/sub/a"))}},{name:"removes a file",async run(a){let t=a();await t.write("/a","1"),await t.remove("/a"),r(await t.exists("/a"),!1)}},{name:"requires recursive to remove a non-empty dir",async run(a){let t=a();await t.mkdir("/d"),await t.write("/d/a","1"),await b(()=>t.remove("/d")),await t.remove("/d",{recursive:!0}),r(await t.exists("/d"),!1)}},{name:"moves a file",async run(a){let t=a();await t.write("/a","1"),await t.move("/a","/b"),r(await t.exists("/a"),!1),r(o(await t.read("/b")),"1")}},{name:"copies a file",async run(a){let t=a();await t.write("/a","1"),await t.copy("/a","/b"),r(o(await t.read("/a")),"1"),r(o(await t.read("/b")),"1")}},{name:"stores and reads metadata",async run(a){let t=a();await t.write("/a","1",{meta:{tag:"x"}}),r((await t.getMeta("/a")).tag,"x"),await t.setMeta("/a",{tag:"y"}),r((await t.getMeta("/a")).tag,"y")}},{name:"emits watch events when supported",async run(a){let t=a();if(!t.capabilities().watch)return;let e=[],n=t.watch("/",i=>e.push(i.type+":"+i.path));await new Promise(i=>setTimeout(i,60)),await t.write("/a","1"),await S(()=>e.includes("create:/a")),n(),c(e.includes("create:/a"))}},{name:"moves a directory subtree",async run(a){let t=a();await t.mkdir("/d"),await t.mkdir("/d/sub"),await t.write("/d/sub/a","1"),await t.move("/d","/e"),r(await t.exists("/d"),!1),r(o(await t.read("/e/sub/a")),"1")}},{name:"copies a directory subtree deeply",async run(a){let t=a();await t.mkdir("/d"),await t.write("/d/a","1"),await t.copy("/d","/e"),await t.write("/e/a","2"),r(o(await t.read("/d/a")),"1"),r(o(await t.read("/e/a")),"2")}},{name:"isolates returned read buffers from the store",async run(a){let t=a();await t.write("/a","abc");let e=await t.read("/a");e[0]=0,r(o(await t.read("/a")),"abc")}},{name:"does not confuse sibling prefixes",async run(a){let t=a();await t.mkdir("/d"),await t.mkdir("/dx"),await t.write("/dx/a","1"),c(!(await t.list("/d")).some(e=>e.name==="a"))}},{name:"reports byte size matching written content",async run(a){let t=a();await t.write("/a","hello"),r((await t.stat("/a")).size,5)}},{name:"throws ALREADY_EXISTS creating an existing dir without recursive",async run(a){let t=a();await t.mkdir("/d"),await s(()=>t.mkdir("/d"),"ALREADY_EXISTS")}},{name:"preserves metadata when overwriting content without new meta",async run(a){let t=a();await t.write("/a","1",{meta:{tag:"x"}}),await t.write("/a","2"),r((await t.getMeta("/a")).tag,"x")}},{name:"throws NOT_A_DIRECTORY creating a directory under a file",async run(a){let t=a();await t.write("/f","1"),await s(()=>t.mkdir("/f/sub",{recursive:!0}),"NOT_A_DIRECTORY")}},{name:"throws ALREADY_EXISTS moving or copying onto an existing path",async run(a){let t=a();await t.write("/a","1"),await t.write("/b","2"),await s(()=>t.move("/a","/b"),"ALREADY_EXISTS"),await s(()=>t.copy("/a","/b"),"ALREADY_EXISTS")}},{name:"conditional write succeeds on matching version and CONFLICTs on stale (when capable)",async run(a){let t=a();if(!t.capabilities().conditionalWrite)return;await t.write("/a","1");let e=(await t.stat("/a")).version;c(typeof e=="string"&&e.length>0,"expected a version token"),await t.write("/a","2",{ifMatch:e}),r(o(await t.read("/a")),"2"),await s(()=>t.write("/a","3",{ifMatch:e}),"CONFLICT"),r(o(await t.read("/a")),"2")}},{name:"ifAbsent rejects overwriting an existing file (when capable)",async run(a){let t=a();t.capabilities().conditionalWrite&&(await t.write("/a","1"),await s(()=>t.write("/a","2",{ifAbsent:!0}),"ALREADY_EXISTS"),r(o(await t.read("/a")),"1"))}},{name:"rejects removing the root",async run(a){let t=a();await s(()=>t.remove("/"),"IO"),await s(()=>t.remove("/",{recursive:!0}),"IO")}},{name:"mkdir over an existing file throws ALREADY_EXISTS",async run(a){let t=a();await t.write("/f","1"),await s(()=>t.mkdir("/f"),"ALREADY_EXISTS"),await s(()=>t.mkdir("/f",{recursive:!0}),"ALREADY_EXISTS")}},{name:"ifMatch on a missing file always conflicts (when capable)",async run(a){let t=a();t.capabilities().conditionalWrite&&(await s(()=>t.write("/a","x",{ifMatch:"0"}),"CONFLICT"),await s(()=>t.write("/a","x",{ifMatch:""}),"CONFLICT"))}},{name:"setMeta assigns a new version (when capable)",async run(a){let t=a();if(!t.capabilities().conditionalWrite)return;await t.write("/a","1");let e=(await t.stat("/a")).version;await t.setMeta("/a",{x:1});let n=(await t.stat("/a")).version;c(typeof n=="string"&&n.length>0&&n!==e,"expected a new version after setMeta")}},{name:"copy assigns a new version to the copy (when capable)",async run(a){let t=a();if(!t.capabilities().conditionalWrite)return;await t.write("/a","1");let e=(await t.stat("/a")).version;await t.copy("/a","/b");let n=(await t.stat("/b")).version;c(typeof n=="string"&&n.length>0&&n!==e,"expected a new version on copy")}},{name:"rejects copy or move into its own subtree",async run(a){let t=a();await t.mkdir("/d"),await t.write("/d/a","1"),await s(()=>t.copy("/d","/d/x"),"IO"),await s(()=>t.move("/d","/d/x"),"IO")}},{name:"throws NOT_A_DIRECTORY copying under a file",async run(a){let t=a();await t.write("/f","1"),await t.write("/src","2"),await s(()=>t.copy("/src","/f/x"),"NOT_A_DIRECTORY")}},{name:"changes the version token on move (when capable)",async run(a){let t=a();if(!t.capabilities().conditionalWrite)return;await t.write("/a","1");let e=(await t.stat("/a")).version;await t.move("/a","/b");let n=(await t.stat("/b")).version;c(typeof n=="string"&&n.length>0&&n!==e,"expected a new version after move")}},{name:"streams content in and back out (helper, native or buffered)",async run(a){let t=a(),n=(await p(t,"/s.bin")).getWriter();await n.write(w("chunk-one;")),await n.write(w("chunk-two")),await n.close(),r(o(await l(await y(t,"/s.bin"))),"chunk-one;chunk-two"),r(o(await t.read("/s.bin")),"chunk-one;chunk-two")}}];function E(a){let t=globalThis;t.describe("vfs conformance",()=>{for(let e of g)t.it(e.name,()=>e.run(a))})}export{g as conformanceCases,E as runConformance};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- function u(i){let e=[];for(let p of i.split("/"))if(!(p===""||p===".")){if(p===".."){e.pop();continue}e.push(p)}return"/"+e.join("/")}function It(...i){return u(i.join("/"))}function F(i){let e=u(i),p=e.lastIndexOf("/");return p<=0?"/":e.slice(0,p)}function Vt(i){let e=u(i);return e.slice(e.lastIndexOf("/")+1)}function Bt(i){return u(i).split("/").filter(Boolean)}var Y=Symbol.for("vfskit.VfsError"),A=class extends Error{code;path;[Y]=!0;constructor(e,p,c){super(p),this.name="VfsError",this.code=e,this.path=c}},S=i=>new A("NOT_FOUND",`not found: ${i}`,i),k=i=>new A("ALREADY_EXISTS",`already exists: ${i}`,i),O=i=>new A("NOT_A_DIRECTORY",`not a directory: ${i}`,i),E=i=>new A("IS_A_DIRECTORY",`is a directory: ${i}`,i),Kt=i=>new A("PERMISSION_DENIED",`permission denied: ${i}`,i),z=i=>new A("UNSUPPORTED",`unsupported: ${i}`),C=i=>new A("CONFLICT",`version conflict: ${i}`,i),x=(i,e)=>new A("IO",i,e);function qt(i){return typeof i=="object"&&i!==null&&i[Y]===!0}var rt=new TextEncoder,nt=new TextDecoder;function U(i){return typeof i=="string"?rt.encode(i):i instanceof Uint8Array?i:new Uint8Array(i)}function jt(i){return nt.decode(i)}function I(i){let e=0;for(let f of i)e+=f.length;let p=new Uint8Array(e),c=0;for(let f of i)p.set(f,c),c+=f.length;return p}async function Gt(i,e,p){if(i.readStream)return i.readStream(e,p);let c=await i.read(e,p);return new ReadableStream({start(f){f.enqueue(c),f.close()}})}async function Xt(i,e,p){if(i.writeStream)return i.writeStream(e,p);let c=[];return new WritableStream({write(f){c.push(f)},async close(){await i.write(e,I(c),p)}})}async function $t(i){let e=[],p=i.getReader();for(;;){let{done:c,value:f}=await p.read();if(c)break;f&&e.push(f)}return I(e)}var it={streaming:!1,watch:!0,atomicMove:!0,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0};function at(){let i=()=>Date.now(),e=0,p=()=>String(++e),c=new Map([["/",{type:"dir",meta:{},mtime:i(),ctime:i()}]]),f=new Set,d=(n,s)=>s===n||s.startsWith(n==="/"?"/":n+"/"),h=(n,s)=>{for(let t of f)d(t.base,s)&&t.cb({type:n,path:s})},m=n=>{let s=c.get(n);if(!s)throw S(n);return s},w=n=>{let s=F(n),t=c.get(s);if(!t)throw S(s);if(t.type!=="dir")throw O(s)};return{capabilities:()=>it,async read(n){let s=u(n),t=m(s);if(t.type==="dir")throw E(s);return t.data.slice()},async write(n,s,t){let r=u(n);w(r);let a=c.get(r);if(a&&a.type==="dir")throw E(r);if(t?.ifAbsent&&a)throw k(r);if(t?.ifMatch!==void 0&&a?.version!==t.ifMatch)throw C(r);let o=a?a.ctime:i();c.set(r,{type:"file",data:U(s).slice(),meta:t?.meta?{...t.meta}:a?.meta??{},ctime:o,mtime:i(),version:p()}),h(a?"update":"create",r)},async list(n,s){let t=u(n);if(m(t).type!=="dir")throw O(t);let a=[];for(let[o,y]of c)o===t||!d(t,o)||!s?.recursive&&F(o)!==t||a.push({name:o.slice(o.lastIndexOf("/")+1),path:o,type:y.type});return a},async stat(n){let s=u(n),t=m(s);return{type:t.type,size:t.type==="file"?t.data.length:0,mtime:t.mtime,ctime:t.ctime,meta:{...t.meta},version:t.type==="file"?t.version:void 0}},async exists(n){return c.has(u(n))},async mkdir(n,s){let t=u(n);if(c.has(t)){if(s?.recursive)return;throw k(t)}if(s?.recursive){let r="";for(let a of t.split("/").filter(Boolean)){r+="/"+a;let o=c.get(r);if(o){if(o.type!=="dir")throw O(r);continue}c.set(r,{type:"dir",meta:{},mtime:i(),ctime:i()}),h("create",r)}return}w(t),c.set(t,{type:"dir",meta:{},mtime:i(),ctime:i()}),h("create",t)},async remove(n,s){let t=u(n);m(t);let r=[...c.keys()].filter(a=>a!==t&&d(t,a));if(r.length&&!s?.recursive)throw x("directory not empty",t);for(let a of[...r,t])c.delete(a),h("remove",a)},async move(n,s){let t=u(n),r=u(s);if(m(t),w(r),c.has(r))throw k(r);if(d(t,r))throw x("cannot move into itself",r);for(let a of[...c.keys()].filter(o=>o===t||d(t,o))){let o=c.get(a);c.delete(a),c.set(r+a.slice(t.length),o)}h("remove",t),h("create",r)},async copy(n,s){let t=u(n),r=u(s);if(m(t),w(r),c.has(r))throw k(r);for(let a of[...c.keys()].filter(o=>o===t||d(t,o))){let o=c.get(a);c.set(r+a.slice(t.length),o.type==="file"?{type:"file",data:o.data.slice(),meta:{...o.meta},mtime:o.mtime,ctime:o.ctime,version:p()}:{type:"dir",meta:{...o.meta},mtime:o.mtime,ctime:o.ctime})}h("create",r)},async getMeta(n){return{...m(u(n)).meta}},async setMeta(n,s){let t=m(u(n));t.meta={...s},t.mtime=i()},watch(n,s){let t={base:u(n),cb:s};return f.add(t),()=>{f.delete(t)}}}}import{promises as b,watch as G,createReadStream as st}from"fs";import{Readable as ot}from"stream";import{join as ct,dirname as N}from"path";var pt={streaming:!0,watch:!0,atomicMove:!0,nativeMeta:!1,randomAccess:!1,conditionalWrite:!0},j="/.vfskit/meta.json",_="/.vfskit/ver.json";function yt(i){let e=n=>ct(i,u(n)),p=n=>n==="/.vfskit"||n.startsWith("/.vfskit/"),c=async()=>{try{return JSON.parse(new TextDecoder().decode(await b.readFile(e(j))))}catch{return{}}},f=async n=>{await b.mkdir(N(e(j)),{recursive:!0}),await b.writeFile(e(j),new TextEncoder().encode(JSON.stringify(n)))},d=async()=>{try{return JSON.parse(new TextDecoder().decode(await b.readFile(e(_))))}catch{return{}}},h=async n=>{await b.mkdir(N(e(_)),{recursive:!0}),await b.writeFile(e(_),new TextEncoder().encode(JSON.stringify(n)))},m=(n,s,t,r)=>{let a=!1;for(let o of Object.keys(n))(o===s||o.startsWith(s+"/"))&&(n[t+o.slice(s.length)]=n[o],r||delete n[o],a=!0);return a},w=async(n,s)=>{try{return await s()}catch(t){if(t instanceof A)throw t;let r=t.code;throw r==="ENOENT"?S(n):r==="EEXIST"?k(n):r==="ENOTDIR"?O(n):r==="EISDIR"?E(n):x(String(t.message??t),n)}};return{capabilities:()=>pt,async read(n){let s=u(n);return w(s,async()=>{if((await b.stat(e(s))).isDirectory())throw E(s);return new Uint8Array(await b.readFile(e(s)))})},async write(n,s,t){let r=u(n);await w(r,()=>b.access(N(e(r))).then(()=>{}));let a=await d();if(t?.ifAbsent||t?.ifMatch!==void 0){let o=await b.stat(e(r)).then(()=>!0,()=>!1);if(t.ifAbsent&&o)throw k(r);if(t.ifMatch!==void 0&&String(a[r]??"")!==t.ifMatch)throw C(r)}if(await w(r,()=>b.writeFile(e(r),U(s)).then(()=>{})),a[r]=(a[r]??0)+1,await h(a),t?.meta){let o=await c();o[r]=t.meta,await f(o)}},async list(n,s){let t=u(n),r=[],a=async o=>{for(let y of await b.readdir(e(o),{withFileTypes:!0})){let l=u(o+"/"+y.name);p(l)||(r.push({name:y.name,path:l,type:y.isDirectory()?"dir":"file"}),s?.recursive&&y.isDirectory()&&await a(l))}};return await w(t,async()=>{if(!(await b.stat(e(t))).isDirectory())throw O(t);await a(t)}),r},async stat(n){let s=u(n);return w(s,async()=>{let t=await b.stat(e(s)),r=t.isDirectory(),a=r?void 0:(await d())[s];return{type:r?"dir":"file",size:r?0:t.size,mtime:t.mtimeMs,ctime:t.ctimeMs,meta:(await c())[s]??{},version:a!=null?String(a):void 0}})},async exists(n){try{return await b.stat(e(u(n))),!0}catch{return!1}},async mkdir(n,s){let t=u(n);await w(t,()=>b.mkdir(e(t),{recursive:s?.recursive}).then(()=>{}))},async remove(n,s){let t=u(n);await w(t,async()=>{if((await b.stat(e(t))).isDirectory()){if((await b.readdir(e(t))).length&&!s?.recursive)throw x("directory not empty",t);await b.rm(e(t),{recursive:!0,force:!0})}else await b.rm(e(t))});let r=await c(),a=!1;for(let l of Object.keys(r))(l===t||l.startsWith(t+"/"))&&(delete r[l],a=!0);a&&await f(r);let o=await d(),y=!1;for(let l of Object.keys(o))(l===t||l.startsWith(t+"/"))&&(delete o[l],y=!0);y&&await h(o)},async move(n,s){let t=u(n),r=u(s);await w(t,async()=>{if(await b.access(N(e(r))),await b.stat(e(r)).then(()=>!0,()=>!1))throw k(r);await b.rename(e(t),e(r))});let a=await c();m(a,t,r,!1)&&await f(a);let o=await d();m(o,t,r,!1)&&await h(o)},async copy(n,s){let t=u(n),r=u(s);await w(t,async()=>{if(await b.access(N(e(r))),await b.stat(e(r)).then(()=>!0,()=>!1))throw k(r);await b.cp(e(t),e(r),{recursive:!0})});let a=await c();m(a,t,r,!0)&&await f(a);let o=await d();m(o,t,r,!0)&&await h(o)},async getMeta(n){let s=u(n);return await w(s,()=>b.stat(e(s)).then(()=>{})),(await c())[s]??{}},async setMeta(n,s){let t=u(n);await w(t,()=>b.stat(e(t)).then(()=>{}));let r=await c();r[t]=s,await f(r)},watch(n,s){let t=u(n),r=(o,y)=>{if(!y)return;let l=u(t+"/"+y.toString());p(l)||b.stat(e(l)).then(()=>s({type:o==="change"?"update":"create",path:l}),()=>s({type:"remove",path:l}))},a;try{a=G(e(t),{recursive:!0},r)}catch{try{a=G(e(t),r)}catch{return()=>{}}}return()=>a.close()},async readStream(n,s){let t=u(n);await w(t,async()=>{if((await b.stat(e(t))).isDirectory())throw E(t)});let r=st(e(t),s?.signal?{signal:s.signal}:{});return ot.toWeb(r)},async writeStream(n,s){let t=u(n),r=await w(t,async()=>(await b.access(N(e(t))),b.open(e(t),"w")));return new WritableStream({async write(a){try{await r.write(a)}catch(o){throw await r.close().catch(()=>{}),o}},close:async()=>{await r.close();let a=await d();if(a[t]=(a[t]??0)+1,await h(a),s?.meta){let o=await c();o[t]=s.meta,await f(o)}},abort:async()=>{await r.close()}})}}}var ft={streaming:!1,watch:!0,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},L=new Uint8Array(0);function ut(){let i=new Map,e=0;return{async get(p){let c=i.get(p);return c?{body:c.body.slice(),meta:{...c.meta},size:c.body.length,mtime:c.mtime,version:c.version}:null},async put(p,c,f){i.set(p,{body:c.slice(),meta:{...f},mtime:Date.now(),version:String(++e)})},async del(p){i.delete(p)},async head(p){let c=i.get(p);return c?{size:c.body.length,mtime:c.mtime,meta:{...c.meta},version:c.version}:null},async list(p){let c=[];for(let[f,d]of i)f.startsWith(p)&&c.push({key:f,size:d.body.length,mtime:d.mtime});return c}}}function lt(i){let e=i.client,p=i.prefix?u("/"+i.prefix).slice(1):"",c=n=>{let s=u(n).slice(1);return p?s?p+"/"+s:p:s},f=n=>c(n)+"/",d=n=>{let s=c(n);return s?s+"/":""},h=(n,s)=>s===n||s.startsWith(n==="/"?"/":n+"/"),m=async n=>u(n)==="/"?"dir":await e.head(c(n))?"file":await e.head(f(n))||(await e.list(d(n))).length?"dir":null,w=async n=>{let s=F(n),t=await m(s);if(t===null)throw S(s);if(t!=="dir")throw O(s)};return{capabilities:()=>ft,async read(n){let s=u(n),t=await e.get(c(s));if(!t)throw await m(s)==="dir"?E(s):S(s);return t.body.slice()},async write(n,s,t){let r=u(n);if(await m(r)==="dir")throw E(r);await w(r);let a=await e.head(c(r));if(t?.ifAbsent&&a)throw k(r);if(t?.ifMatch!==void 0&&(a?.version??"")!==t.ifMatch)throw C(r);await e.put(c(r),U(s),t?.meta??a?.meta??{})},async list(n,s){let t=u(n),r=await m(t);if(r===null)throw S(t);if(r!=="dir")throw O(t);let a=d(t),o=new Map;for(let y of await e.list(a)){let l=y.key.slice(a.length),g=l.endsWith("/");if(g&&(l=l.slice(0,-1)),l!=="")if(s?.recursive){let v=u(t+"/"+l),T=g?"dir":"file";(!o.has(v)||T==="dir")&&o.set(v,{name:l.split("/").pop(),path:v,type:T})}else{let v=l.split("/")[0],T=u(t+"/"+v),W=g||l.includes("/")?"dir":"file";(!o.has(T)||W==="dir")&&o.set(T,{name:v,path:T,type:W})}}return[...o.values()]},async stat(n){let s=u(n),t=await m(s);if(t===null)throw S(s);if(t==="file"){let a=await e.head(c(s));return{type:"file",size:a?.size??0,mtime:a?.mtime??0,ctime:a?.mtime??0,meta:a?.meta??{},version:a?.version}}let r=await e.head(f(s));return{type:"dir",size:0,mtime:r?.mtime??0,ctime:r?.mtime??0,meta:r?.meta??{}}},async exists(n){return await m(n)!==null},async mkdir(n,s){let t=u(n);if(await m(t)!==null){if(s?.recursive)return;throw k(t)}if(s?.recursive){let r=t.split("/").filter(Boolean),a="";for(let o of r){a+="/"+o;let y=await m(a);if(y==="file")throw O(a);y===null&&await e.put(f(a),L,{})}return}await w(t),await e.put(f(t),L,{})},async remove(n,s){let t=u(n),r=await m(t);if(r===null)throw S(t);if(r==="file"){await e.del(c(t));return}let a=await e.list(d(t));if(a.filter(y=>y.key!==f(t)).length&&!s?.recursive)throw x("directory not empty",t);for(let y of a)await e.del(y.key);await e.del(f(t))},async copy(n,s){let t=u(n),r=u(s);if(h(t,r))throw x("cannot copy into itself",r);let a=await m(t);if(a===null)throw S(t);if(await m(r)!==null)throw k(r);if(await w(r),a==="file"){let y=await e.get(c(t));y&&await e.put(c(r),y.body,y.meta);return}await e.put(f(r),L,{});let o=d(t);for(let y of await e.list(o)){let l=y.key.slice(o.length);if(l==="")continue;let g=d(r)+l;if(l.endsWith("/"))await e.put(g,L,{});else{let v=await e.get(y.key);v&&await e.put(g,v.body,v.meta)}}},async move(n,s){await this.copy(n,s),await this.remove(n,{recursive:!0})},async getMeta(n){let s=u(n),t=await m(s);if(t===null)throw S(s);return(await e.head(t==="file"?c(s):f(s)))?.meta??{}},async setMeta(n,s){let t=u(n),r=await m(t);if(r===null)throw S(t);if(r==="file"){let a=await e.get(c(t));await e.put(c(t),a?.body??L,s)}else await e.put(f(t),L,s)},watch(n,s){let t=u(n),r=d(t),a=c(t)?c(t)+"/":"",o=R=>u("/"+(p?R.slice(p.length+1):R)),y=new Map,l=!1,g=async()=>{let R=new Map;for(let D of await e.list(r))D.key!==a&&R.set(D.key,D.mtime);return R};g().then(R=>{y=R,l=!0});let v=!1,T=async()=>{if(!(!l||v)){v=!0;try{let R=await g();for(let[D,et]of R)y.has(D)?y.get(D)!==et&&s({type:"update",path:o(D)}):s({type:"create",path:o(D)});for(let D of y.keys())R.has(D)||s({type:"remove",path:o(D)});y=R}finally{v=!1}}},W=setInterval(()=>{T()},i.pollMs??200);return W.unref?.(),()=>clearInterval(W)}}}import{createRequire as dt}from"module";var{DatabaseSync:mt}=dt(import.meta.url)("node:sqlite"),wt={streaming:!1,watch:!1,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},ht=i=>i.replace(/[\\%_]/g,e=>"\\"+e);function gt(i){let e=new mt(i);e.exec("CREATE TABLE IF NOT EXISTS files (path TEXT PRIMARY KEY, type TEXT NOT NULL, data BLOB, meta TEXT NOT NULL DEFAULT '{}', version INTEGER NOT NULL DEFAULT 0)"),e.prepare("INSERT OR IGNORE INTO files (path, type) VALUES ('/', 'dir')").run();let p=e.prepare("SELECT path, type, data, meta, version FROM files WHERE path = ?"),c=e.prepare("INSERT INTO files (path, type, data, meta, version) VALUES (?, ?, ?, ?, ?) ON CONFLICT(path) DO UPDATE SET type=excluded.type, data=excluded.data, meta=excluded.meta, version=excluded.version"),f=e.prepare("DELETE FROM files WHERE path = ?"),d=e.prepare("SELECT path, type FROM files WHERE path LIKE ? ESCAPE '\\'"),h=a=>p.get(a),m=(a,o,y,l,g)=>c.run(a,o,y,JSON.stringify(l),g),w=(a,o)=>o===a||o.startsWith(a==="/"?"/":a+"/"),n=a=>d.all(ht(a==="/"?"/":a+"/")+"%").filter(o=>w(a,o.path)&&o.path!==a),s=a=>{let o=h(a);if(!o)throw S(a);return o},t=a=>{let o=F(a),y=h(o);if(!y)throw S(o);if(y.type!=="dir")throw O(o)},r=a=>a.data?new Uint8Array(a.data):new Uint8Array(0);return{capabilities:()=>wt,async read(a){let o=u(a),y=s(o);if(y.type==="dir")throw E(o);return r(y)},async write(a,o,y){let l=u(a);t(l);let g=h(l);if(g?.type==="dir")throw E(l);if(y?.ifAbsent&&g)throw k(l);if(y?.ifMatch!==void 0&&String(g?.version??"")!==y.ifMatch)throw C(l);let v=y?.meta??(g?JSON.parse(g.meta):{});m(l,"file",U(o),v,(g?.version??0)+1)},async list(a,o){let y=u(a);if(s(y).type!=="dir")throw O(y);let g=[];for(let v of n(y))!o?.recursive&&F(v.path)!==y||g.push({name:v.path.slice(v.path.lastIndexOf("/")+1),path:v.path,type:v.type});return g},async stat(a){let o=u(a),y=s(o);return{type:y.type,size:y.type==="file"?r(y).length:0,mtime:0,ctime:0,meta:JSON.parse(y.meta),version:y.type==="file"?String(y.version):void 0}},async exists(a){return!!h(u(a))},async mkdir(a,o){let y=u(a);if(h(y)){if(o?.recursive)return;throw k(y)}if(o?.recursive){let g="";for(let v of y.split("/").filter(Boolean)){g+="/"+v;let T=h(g);if(T?.type==="file")throw O(g);T||m(g,"dir",null,{},0)}return}t(y),m(y,"dir",null,{},0)},async remove(a,o){let y=u(a);s(y);let l=n(y);if(l.length&&!o?.recursive)throw x("directory not empty",y);for(let g of l)f.run(g.path);f.run(y)},async move(a,o){await this.copy(a,o),await this.remove(a,{recursive:!0})},async copy(a,o){let y=u(a),l=u(o);if(s(y),t(l),h(l))throw k(l);if(w(y,l))throw x("cannot copy into itself",l);for(let g of[y,...n(y).map(v=>v.path)]){let v=s(g);m(l+g.slice(y.length),v.type,v.data?new Uint8Array(v.data):null,JSON.parse(v.meta),(v.version??0)+1)}},async getMeta(a){return JSON.parse(s(u(a)).meta)},async setMeta(a,o){let y=u(a),l=s(y);m(y,l.type,l.data?new Uint8Array(l.data):null,o,l.version)},watch(){return()=>{}}}}var vt={streaming:!1,watch:!1,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0};function bt(i){let e="";for(let p=0;p<i.length;p+=32768)e+=String.fromCharCode(...i.subarray(p,p+32768));return btoa(e)}function X(i){let e=atob(i),p=new Uint8Array(e.length);for(let c=0;c<e.length;c++)p[c]=e.charCodeAt(c);return p}function kt(){let i=new Map;return{async get(e){return i.get(e)},async set(e,p){i.set(e,p)},async delete(e){i.delete(e)},async list(e){return[...i.keys()].filter(p=>p.startsWith(e))}}}function St(i=globalThis.localStorage){return{async get(e){return i.getItem(e)},async set(e,p){i.setItem(e,p)},async delete(e){i.removeItem(e)},async list(e){let p=[];for(let c=0;c<i.length;c++){let f=i.key(c);f&&f.startsWith(e)&&p.push(f)}return p}}}function xt(i){let e=i.store,p=(i.prefix?i.prefix+":":"")+"vfs:",c=r=>p+u(r),f=r=>r.slice(p.length),d=(r,a)=>a===r||a.startsWith(r==="/"?"/":r+"/"),h=async r=>{let a=await e.get(c(r));return a?JSON.parse(a):void 0},m=(r,a)=>e.set(c(r),JSON.stringify(a)),w=async r=>{let a=await h(r);if(!a)throw S(r);return a},n=async r=>(await e.list(c(r)===p+"/"?p+"/":c(r)+"/")).map(f).filter(a=>a!==r&&d(r,a)),s=async r=>{let a=F(r),o=await h(a);if(!o)throw S(a);if(o.t!=="dir")throw O(a)},t=(async()=>{await e.get(c("/"))||await m("/",{t:"dir",m:{},v:0})})();return{capabilities:()=>vt,async read(r){await t;let a=u(r),o=await w(a);if(o.t==="dir")throw E(a);return X(o.d??"")},async write(r,a,o){await t;let y=u(r);await s(y);let l=await h(y);if(l?.t==="dir")throw E(y);if(o?.ifAbsent&&l)throw k(y);if(o?.ifMatch!==void 0&&String(l?.v??"")!==o.ifMatch)throw C(y);await m(y,{t:"file",d:bt(U(a)),m:o?.meta??l?.m??{},v:(l?.v??0)+1})},async list(r,a){await t;let o=u(r);if((await w(o)).t!=="dir")throw O(o);let l=[];for(let g of await n(o)){if(!a?.recursive&&F(g)!==o)continue;let v=await h(g);v&&l.push({name:g.slice(g.lastIndexOf("/")+1),path:g,type:v.t})}return l},async stat(r){await t;let a=u(r),o=await w(a);return{type:o.t,size:o.t==="file"?X(o.d??"").length:0,mtime:0,ctime:0,meta:{...o.m},version:o.t==="file"?String(o.v):void 0}},async exists(r){return await t,!!await h(u(r))},async mkdir(r,a){await t;let o=u(r);if(await h(o)){if(a?.recursive)return;throw k(o)}if(a?.recursive){let l="";for(let g of o.split("/").filter(Boolean)){l+="/"+g;let v=await h(l);if(v?.t==="file")throw O(l);v||await m(l,{t:"dir",m:{},v:0})}return}await s(o),await m(o,{t:"dir",m:{},v:0})},async remove(r,a){await t;let o=u(r);await w(o);let y=await n(o);if(y.length&&!a?.recursive)throw x("directory not empty",o);for(let l of[...y,o])await e.delete(c(l))},async move(r,a){await this.copy(r,a),await this.remove(r,{recursive:!0})},async copy(r,a){await t;let o=u(r),y=u(a);if(await w(o),await s(y),await h(y))throw k(y);if(d(o,y))throw x("cannot copy into itself",y);for(let l of[o,...await n(o)]){let g=await h(l);g&&await m(y+l.slice(o.length),{...g,v:(g.v??0)+1})}},async getMeta(r){return await t,{...(await w(u(r))).m}},async setMeta(r,a){await t;let o=u(r),y=await w(o);await m(o,{...y,m:{...a}})},watch(){return()=>{}}}}var K=new Uint8Array([86,75,1]),$=47,V=globalThis.crypto.subtle;function H(i){let e=new Uint8Array(i);return globalThis.crypto.getRandomValues(e),e}async function Ot(i,e){let p=await V.importKey("raw",new TextEncoder().encode(i),"PBKDF2",!1,["deriveKey"]);return V.deriveKey({name:"PBKDF2",salt:e.slice(),iterations:21e4,hash:"SHA-256"},p,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}function At(i,e){if(!e.key&&!e.passphrase)throw new Error("encrypt: key or passphrase required");let p=e.key?V.importKey("raw",e.key.slice(),"AES-GCM",!1,["encrypt","decrypt"]):null,c=d=>p??Ot(e.passphrase,d),f={...i.capabilities(),streaming:!1,randomAccess:!1};return{...i,readStream:void 0,writeStream:void 0,capabilities:()=>f,async stat(d){let h=await i.stat(d);return h.type==="file"?{...h,size:Math.max(0,h.size-$)}:h},async write(d,h,m){let w=H(16),n=H(12),s=await c(w),t=new Uint8Array(await V.encrypt({name:"AES-GCM",iv:n},s,U(h).slice()));await i.write(d,I([K,w,n,t]),m)},async read(d,h){let m=await i.read(d,h);if(m.length<$||m[0]!==K[0]||m[1]!==K[1]||m[2]!==K[2])throw x("invalid ciphertext",d);let w=await c(m.slice(3,19)),n;try{n=await V.decrypt({name:"AES-GCM",iv:m.slice(19,31)},w,m.slice(31))}catch{throw x("decryption failed",d)}return new Uint8Array(n)}}}function Et(i,e={}){let p=e.store??new Map,c=e.ttlMs??0,f=()=>c?Date.now():0,d=()=>c?Date.now()+c:1/0,h=(w,n)=>n===w||n.startsWith(w==="/"?"/":w+"/"),m=w=>{for(let n of[...p.keys()])h(w,n)&&p.delete(n)};return{...i,readStream:void 0,writeStream:void 0,async read(w,n){let s=u(w),t=p.get(s);if(t&&t.exp>f())return t.data.slice();let r=await i.read(s,n);return p.set(s,{data:r.slice(),exp:d()}),r.slice()},async write(w,n,s){let t=u(w),r=U(n).slice();await i.write(t,r,s),p.set(t,{data:r,exp:d()})},async remove(w,n){let s=u(w);await i.remove(s,n),m(s)},async move(w,n){let s=u(w),t=u(n);await i.move(s,t),m(s),m(t)},async copy(w,n){let s=u(w),t=u(n);await i.copy(s,t),m(t)}}}var Ut=new TextEncoder,Mt=new TextDecoder,B=new Uint8Array(0);function M(i,e=B){let p=Ut.encode(JSON.stringify(i)),c=new Uint8Array(4+p.length+e.length);return new DataView(c.buffer).setUint32(0,p.length),c.set(p,4),c.set(e,4+p.length),c}function Q(i){let p=new DataView(i.buffer,i.byteOffset,i.byteLength).getUint32(0);return{header:JSON.parse(Mt.decode(i.subarray(4,4+p))),data:i.subarray(4+p)}}function Z(i,e,p=[],c){return M({m:i,p:e,a:p},c)}function Tt(i){let{header:e,data:p}=Q(i);return{method:e.m,path:e.p,args:e.a??[],data:p}}function tt(i){let{header:e,data:p}=Q(i);return e.ok?{ok:!0,value:e.v,data:p}:{ok:!1,data:B,code:e.c,message:e.e,path:e.p}}async function q(i,e){let{method:p,path:c,args:f,data:d}=Tt(e);try{switch(p){case"read":return M({ok:!0},await i.read(c,f[0]));case"write":return await i.write(c,d,f[0]),M({ok:!0});case"list":return M({ok:!0,v:await i.list(c,f[0])});case"stat":return M({ok:!0,v:await i.stat(c)});case"exists":return M({ok:!0,v:await i.exists(c)});case"mkdir":return await i.mkdir(c,f[0]),M({ok:!0});case"remove":return await i.remove(c,f[0]),M({ok:!0});case"move":return await i.move(c,f[0]),M({ok:!0});case"copy":return await i.copy(c,f[0]),M({ok:!0});case"getMeta":return M({ok:!0,v:await i.getMeta(c)});case"setMeta":return await i.setMeta(c,f[0]),M({ok:!0});default:throw z(p)}}catch(h){let m=h instanceof A?h:x(String(h?.message??h),c);return M({ok:!1,c:m.code,e:m.message,p:m.path})}}function P(i,e,p=B){let c=new Uint8Array(5+p.length);return c[0]=i,new DataView(c.buffer).setUint32(1,e),c.set(p,5),c}function J(i){let e=new DataView(i.buffer,i.byteOffset,i.byteLength);return{type:i[0],id:e.getUint32(1),payload:i.subarray(5)}}var Rt=new TextEncoder,Dt=new TextDecoder;function Ft(i){return{handle:e=>q(i,e),async fetch(e){let p=new Uint8Array(await e.arrayBuffer());return new Response(await q(i,p),{headers:{"content-type":"application/octet-stream"}})},socket(e){let p=new Map;return{async message(c){let{type:f,id:d,payload:h}=J(c);if(f===0)e(P(1,d,await q(i,h)));else if(f===2){let{path:m}=JSON.parse(Dt.decode(h));p.set(d,i.watch(m,w=>e(P(4,d,Rt.encode(JSON.stringify(w))))))}else f===3&&(p.get(d)?.(),p.delete(d))},close(){for(let c of p.values())c();p.clear()}}}}}function Ct(i){let e=i.request?i:i.transport,p=i.capabilities??{streaming:!1,watch:!!e.watch,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},c=async(f,d,h,m)=>{let w=h?[...h]:[];for(;w.length&&w[w.length-1]===void 0;)w.pop();let n=tt(await e.request(Z(f,d,w,m)));if(!n.ok)throw new A(n.code,n.message??"",n.path);return n};return{capabilities:()=>p,async read(f,d){return(await c("read",f,[d])).data},async write(f,d,h){await c("write",f,[h],U(d))},async list(f,d){return(await c("list",f,[d])).value},async stat(f){return(await c("stat",f)).value},async exists(f){return(await c("exists",f)).value},async mkdir(f,d){await c("mkdir",f,[d])},async remove(f,d){await c("remove",f,[d])},async move(f,d){await c("move",f,[d])},async copy(f,d){await c("copy",f,[d])},async getMeta(f){return(await c("getMeta",f)).value},async setMeta(f,d){await c("setMeta",f,[d])},watch(f,d){if(!e.watch)throw z("watch");return e.watch(f,d)}}}function Pt(i,e){let p=e??((c,f)=>fetch(c,f));return{async request(c){let f=await p(i,{method:"POST",body:c});return new Uint8Array(await f.arrayBuffer())}}}var Nt=new TextEncoder,Lt=new TextDecoder;function Wt(i,e){let p=e?e():new WebSocket(i);try{p.binaryType="arraybuffer"}catch{}let c=new Map,f=new Map,d=0,h=p.readyState===1?Promise.resolve():new Promise(m=>{p.addEventListener?p.addEventListener("open",()=>m()):p.onopen=()=>m()});return p.onmessage=m=>{let{type:w,id:n,payload:s}=J(new Uint8Array(m.data));w===1?(c.get(n)?.(s),c.delete(n)):w===4&&f.get(n)?.(JSON.parse(Lt.decode(s)))},{async request(m){await h;let w=++d;return new Promise(n=>{c.set(w,n),p.send(P(0,w,m))})},watch(m,w){let n=++d;return f.set(n,w),h.then(()=>p.send(P(2,n,Nt.encode(JSON.stringify({path:m}))))),()=>{f.delete(n),h.then(()=>p.send(P(3,n,B)))}}}}export{Y as BRAND,A as VfsError,k as alreadyExists,Vt as basename,Et as cache,$t as collect,I as concat,C as conflict,F as dirname,At as encrypt,Pt as httpTransport,x as io,E as isADirectory,qt as isVfsError,It as join,xt as kv,St as localStorageKv,kt as memKv,at as memory,ut as memoryS3,yt as nodeFs,u as normalize,O as notADirectory,S as notFound,Kt as permissionDenied,Gt as readStream,Ct as remote,lt as s3,Bt as segments,Ft as serve,gt as sqlite,U as toBytes,jt as toText,z as unsupported,Xt as writeStream,Wt as wsTransport};
1
+ function u(s){let e=[];for(let p of s.split("/"))if(!(p===""||p===".")){if(p===".."){e.pop();continue}e.push(p)}return"/"+e.join("/")}function It(...s){return u(s.join("/"))}function F(s){let e=u(s),p=e.lastIndexOf("/");return p<=0?"/":e.slice(0,p)}function Vt(s){let e=u(s);return e.slice(e.lastIndexOf("/")+1)}function Bt(s){return u(s).split("/").filter(Boolean)}var Y=Symbol.for("vfskit.VfsError"),A=class extends Error{code;path;[Y]=!0;constructor(e,p,c){super(p),this.name="VfsError",this.code=e,this.path=c}},x=s=>new A("NOT_FOUND",`not found: ${s}`,s),S=s=>new A("ALREADY_EXISTS",`already exists: ${s}`,s),O=s=>new A("NOT_A_DIRECTORY",`not a directory: ${s}`,s),E=s=>new A("IS_A_DIRECTORY",`is a directory: ${s}`,s),Kt=s=>new A("PERMISSION_DENIED",`permission denied: ${s}`,s),z=s=>new A("UNSUPPORTED",`unsupported: ${s}`),C=s=>new A("CONFLICT",`version conflict: ${s}`,s),k=(s,e)=>new A("IO",s,e);function qt(s){return typeof s=="object"&&s!==null&&s[Y]===!0}var rt=new TextEncoder,nt=new TextDecoder;function U(s){return typeof s=="string"?rt.encode(s):s instanceof Uint8Array?s:new Uint8Array(s)}function Jt(s){return nt.decode(s)}function I(s){let e=0;for(let f of s)e+=f.length;let p=new Uint8Array(e),c=0;for(let f of s)p.set(f,c),c+=f.length;return p}async function Gt(s,e,p){if(s.readStream)return s.readStream(e,p);let c=await s.read(e,p);return new ReadableStream({start(f){f.enqueue(c),f.close()}})}async function Xt(s,e,p){if(s.writeStream)return s.writeStream(e,p);let c=[];return new WritableStream({write(f){c.push(f)},async close(){await s.write(e,I(c),p)}})}async function $t(s){let e=[],p=s.getReader();for(;;){let{done:c,value:f}=await p.read();if(c)break;f&&e.push(f)}return I(e)}var it={streaming:!1,watch:!0,atomicMove:!0,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0};function at(){let s=()=>Date.now(),e=0,p=()=>String(++e),c=new Map([["/",{type:"dir",meta:{},mtime:s(),ctime:s()}]]),f=new Set,l=(i,o)=>o===i||o.startsWith(i==="/"?"/":i+"/"),h=(i,o)=>{for(let t of f)l(t.base,o)&&t.cb({type:i,path:o})},m=i=>{let o=c.get(i);if(!o)throw x(i);return o},w=i=>{let o=F(i),t=c.get(o);if(!t)throw x(o);if(t.type!=="dir")throw O(o)};return{capabilities:()=>it,async read(i){let o=u(i),t=m(o);if(t.type==="dir")throw E(o);return t.data.slice()},async write(i,o,t){let r=u(i);w(r);let n=c.get(r);if(n&&n.type==="dir")throw E(r);if(t?.ifAbsent&&n)throw S(r);if(t?.ifMatch!==void 0&&n?.version!==t.ifMatch)throw C(r);let a=n?n.ctime:s();c.set(r,{type:"file",data:U(o).slice(),meta:t?.meta?{...t.meta}:n?.meta??{},ctime:a,mtime:s(),version:p()}),h(n?"update":"create",r)},async list(i,o){let t=u(i);if(m(t).type!=="dir")throw O(t);let n=[];for(let[a,y]of c)a===t||!l(t,a)||!o?.recursive&&F(a)!==t||n.push({name:a.slice(a.lastIndexOf("/")+1),path:a,type:y.type});return n},async stat(i){let o=u(i),t=m(o);return{type:t.type,size:t.type==="file"?t.data.length:0,mtime:t.mtime,ctime:t.ctime,meta:{...t.meta},version:t.type==="file"?t.version:void 0}},async exists(i){return c.has(u(i))},async mkdir(i,o){let t=u(i),r=c.get(t);if(r){if(o?.recursive&&r.type==="dir")return;throw S(t)}if(o?.recursive){let n="";for(let a of t.split("/").filter(Boolean)){n+="/"+a;let y=c.get(n);if(y){if(y.type!=="dir")throw O(n);continue}c.set(n,{type:"dir",meta:{},mtime:s(),ctime:s()}),h("create",n)}return}w(t),c.set(t,{type:"dir",meta:{},mtime:s(),ctime:s()}),h("create",t)},async remove(i,o){let t=u(i);if(t==="/")throw k("cannot remove root",t);m(t);let r=[...c.keys()].filter(n=>n!==t&&l(t,n));if(r.length&&!o?.recursive)throw k("directory not empty",t);for(let n of[...r,t])c.delete(n),h("remove",n)},async move(i,o){let t=u(i),r=u(o);if(m(t),w(r),c.has(r))throw S(r);if(l(t,r))throw k("cannot move into itself",r);for(let n of[...c.keys()].filter(a=>a===t||l(t,a))){let a=c.get(n);c.delete(n),a.type==="file"&&(a.version=p()),c.set(r+n.slice(t.length),a)}h("remove",t),h("create",r)},async copy(i,o){let t=u(i),r=u(o);if(m(t),w(r),c.has(r))throw S(r);if(l(t,r))throw k("cannot copy into itself",r);for(let n of[...c.keys()].filter(a=>a===t||l(t,a))){let a=c.get(n);c.set(r+n.slice(t.length),a.type==="file"?{type:"file",data:a.data.slice(),meta:{...a.meta},mtime:a.mtime,ctime:a.ctime,version:p()}:{type:"dir",meta:{...a.meta},mtime:a.mtime,ctime:a.ctime})}h("create",r)},async getMeta(i){return{...m(u(i)).meta}},async setMeta(i,o){let t=m(u(i));t.meta={...o},t.mtime=s(),t.type==="file"&&(t.version=p())},watch(i,o){let t={base:u(i),cb:o};return f.add(t),()=>{f.delete(t)}}}}import{promises as b,watch as G,createReadStream as st}from"fs";import{Readable as ot}from"stream";import{join as ct,dirname as N}from"path";var pt={streaming:!0,watch:!0,atomicMove:!0,nativeMeta:!1,randomAccess:!1,conditionalWrite:!0},J="/.vfskit/meta.json",_="/.vfskit/ver.json";function yt(s){let e=i=>ct(s,u(i)),p=i=>i==="/.vfskit"||i.startsWith("/.vfskit/"),c=async()=>{try{return JSON.parse(new TextDecoder().decode(await b.readFile(e(J))))}catch{return{}}},f=async i=>{await b.mkdir(N(e(J)),{recursive:!0}),await b.writeFile(e(J),new TextEncoder().encode(JSON.stringify(i)))},l=async()=>{try{return JSON.parse(new TextDecoder().decode(await b.readFile(e(_))))}catch{return{}}},h=async i=>{await b.mkdir(N(e(_)),{recursive:!0}),await b.writeFile(e(_),new TextEncoder().encode(JSON.stringify(i)))},m=(i,o,t,r)=>{let n=!1;for(let a of Object.keys(i))(a===o||a.startsWith(o+"/"))&&(i[t+a.slice(o.length)]=i[a],r||delete i[a],n=!0);return n},w=async(i,o)=>{try{return await o()}catch(t){if(t instanceof A)throw t;let r=t.code;throw r==="ENOENT"?x(i):r==="EEXIST"?S(i):r==="ENOTDIR"?O(i):r==="EISDIR"?E(i):k(String(t.message??t),i)}};return{capabilities:()=>pt,async read(i){let o=u(i);return w(o,async()=>{if((await b.stat(e(o))).isDirectory())throw E(o);return new Uint8Array(await b.readFile(e(o)))})},async write(i,o,t){let r=u(i);await w(r,()=>b.access(N(e(r))).then(()=>{}));let n=await l();if(t?.ifAbsent||t?.ifMatch!==void 0){let a=await b.stat(e(r)).then(()=>!0,()=>!1);if(t.ifAbsent&&a)throw S(r);if(t.ifMatch!==void 0&&(a&&n[r]!=null?String(n[r]):void 0)!==t.ifMatch)throw C(r)}if(await w(r,()=>b.writeFile(e(r),U(o)).then(()=>{})),n[r]=(n[r]??0)+1,await h(n),t?.meta){let a=await c();a[r]=t.meta,await f(a)}},async list(i,o){let t=u(i),r=[],n=async a=>{for(let y of await b.readdir(e(a),{withFileTypes:!0})){let d=u(a+"/"+y.name);p(d)||(r.push({name:y.name,path:d,type:y.isDirectory()?"dir":"file"}),o?.recursive&&y.isDirectory()&&await n(d))}};return await w(t,async()=>{if(!(await b.stat(e(t))).isDirectory())throw O(t);await n(t)}),r},async stat(i){let o=u(i);return w(o,async()=>{let t=await b.stat(e(o)),r=t.isDirectory(),n=r?void 0:(await l())[o];return{type:r?"dir":"file",size:r?0:t.size,mtime:t.mtimeMs,ctime:t.ctimeMs,meta:(await c())[o]??{},version:n!=null?String(n):void 0}})},async exists(i){try{return await b.stat(e(u(i))),!0}catch{return!1}},async mkdir(i,o){let t=u(i);await w(t,()=>b.mkdir(e(t),{recursive:o?.recursive}).then(()=>{}))},async remove(i,o){let t=u(i);if(t==="/")throw k("cannot remove root",t);await w(t,async()=>{if((await b.stat(e(t))).isDirectory()){if((await b.readdir(e(t))).length&&!o?.recursive)throw k("directory not empty",t);await b.rm(e(t),{recursive:!0,force:!0})}else await b.rm(e(t))});let r=await c(),n=!1;for(let d of Object.keys(r))(d===t||d.startsWith(t+"/"))&&(delete r[d],n=!0);n&&await f(r);let a=await l(),y=!1;for(let d of Object.keys(a))(d===t||d.startsWith(t+"/"))&&(delete a[d],y=!0);y&&await h(a)},async move(i,o){let t=u(i),r=u(o);await w(t,async()=>{if(await b.access(N(e(r))),await b.stat(e(r)).then(()=>!0,()=>!1))throw S(r);await b.rename(e(t),e(r))});let n=await c();m(n,t,r,!1)&&await f(n);let a=await l();if(m(a,t,r,!1)){for(let y of Object.keys(a))(y===r||y.startsWith(r+"/"))&&(a[y]=(a[y]??0)+1);await h(a)}},async copy(i,o){let t=u(i),r=u(o);await w(t,async()=>{if(await b.access(N(e(r))),await b.stat(e(r)).then(()=>!0,()=>!1))throw S(r);await b.cp(e(t),e(r),{recursive:!0})});let n=await c();m(n,t,r,!0)&&await f(n);let a=await l();if(m(a,t,r,!0)){for(let y of Object.keys(a))(y===r||y.startsWith(r+"/"))&&(a[y]=(a[y]??0)+1);await h(a)}},async getMeta(i){let o=u(i);return await w(o,()=>b.stat(e(o)).then(()=>{})),(await c())[o]??{}},async setMeta(i,o){let t=u(i),r=await w(t,()=>b.stat(e(t))),n=await c();if(n[t]=o,await f(n),r.isFile()){let a=await l();a[t]=(a[t]??0)+1,await h(a)}},watch(i,o){let t=u(i),r=(a,y)=>{if(!y)return;let d=u(t+"/"+y.toString());p(d)||b.stat(e(d)).then(()=>o({type:a==="change"?"update":"create",path:d}),()=>o({type:"remove",path:d}))},n;try{n=G(e(t),{recursive:!0},r)}catch{try{n=G(e(t),r)}catch{return()=>{}}}return()=>n.close()},async readStream(i,o){let t=u(i);await w(t,async()=>{if((await b.stat(e(t))).isDirectory())throw E(t)});let r=st(e(t),o?.signal?{signal:o.signal}:{});return ot.toWeb(r)},async writeStream(i,o){let t=u(i),r=await w(t,async()=>(await b.access(N(e(t))),b.open(e(t),"w")));return new WritableStream({async write(n){try{await r.write(n)}catch(a){throw await r.close().catch(()=>{}),a}},close:async()=>{await r.close();let n=await l();if(n[t]=(n[t]??0)+1,await h(n),o?.meta){let a=await c();a[t]=o.meta,await f(a)}},abort:async()=>{await r.close()}})}}}var ft={streaming:!1,watch:!0,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},L=new Uint8Array(0);function ut(){let s=new Map,e=0;return{async get(p){let c=s.get(p);return c?{body:c.body.slice(),meta:{...c.meta},size:c.body.length,mtime:c.mtime,version:c.version}:null},async put(p,c,f){s.set(p,{body:c.slice(),meta:{...f},mtime:Date.now(),version:String(++e)})},async del(p){s.delete(p)},async head(p){let c=s.get(p);return c?{size:c.body.length,mtime:c.mtime,meta:{...c.meta},version:c.version}:null},async list(p){let c=[];for(let[f,l]of s)f.startsWith(p)&&c.push({key:f,size:l.body.length,mtime:l.mtime});return c}}}function dt(s){let e=s.client,p=s.prefix?u("/"+s.prefix).slice(1):"",c=i=>{let o=u(i).slice(1);return p?o?p+"/"+o:p:o},f=i=>c(i)+"/",l=i=>{let o=c(i);return o?o+"/":""},h=(i,o)=>o===i||o.startsWith(i==="/"?"/":i+"/"),m=async i=>u(i)==="/"?"dir":await e.head(c(i))?"file":await e.head(f(i))||(await e.list(l(i))).length?"dir":null,w=async i=>{let o=F(i),t=await m(o);if(t===null)throw x(o);if(t!=="dir")throw O(o)};return{capabilities:()=>ft,async read(i){let o=u(i),t=await e.get(c(o));if(!t)throw await m(o)==="dir"?E(o):x(o);return t.body.slice()},async write(i,o,t){let r=u(i);if(await m(r)==="dir")throw E(r);await w(r);let n=await e.head(c(r));if(t?.ifAbsent&&n)throw S(r);if(t?.ifMatch!==void 0&&(n?n.version:void 0)!==t.ifMatch)throw C(r);await e.put(c(r),U(o),t?.meta??n?.meta??{})},async list(i,o){let t=u(i),r=await m(t);if(r===null)throw x(t);if(r!=="dir")throw O(t);let n=l(t),a=new Map;for(let y of await e.list(n)){let d=y.key.slice(n.length),g=d.endsWith("/");if(g&&(d=d.slice(0,-1)),d!=="")if(o?.recursive){let v=u(t+"/"+d),T=g?"dir":"file";(!a.has(v)||T==="dir")&&a.set(v,{name:d.split("/").pop(),path:v,type:T})}else{let v=d.split("/")[0],T=u(t+"/"+v),W=g||d.includes("/")?"dir":"file";(!a.has(T)||W==="dir")&&a.set(T,{name:v,path:T,type:W})}}return[...a.values()]},async stat(i){let o=u(i),t=await m(o);if(t===null)throw x(o);if(t==="file"){let n=await e.head(c(o));return{type:"file",size:n?.size??0,mtime:n?.mtime??0,ctime:n?.mtime??0,meta:n?.meta??{},version:n?.version}}let r=await e.head(f(o));return{type:"dir",size:0,mtime:r?.mtime??0,ctime:r?.mtime??0,meta:r?.meta??{}}},async exists(i){return await m(i)!==null},async mkdir(i,o){let t=u(i),r=await m(t);if(r!==null){if(o?.recursive&&r==="dir")return;throw S(t)}if(o?.recursive){let n=t.split("/").filter(Boolean),a="";for(let y of n){a+="/"+y;let d=await m(a);if(d==="file")throw O(a);d===null&&await e.put(f(a),L,{})}return}await w(t),await e.put(f(t),L,{})},async remove(i,o){let t=u(i);if(t==="/")throw k("cannot remove root",t);let r=await m(t);if(r===null)throw x(t);if(r==="file"){await e.del(c(t));return}let n=await e.list(l(t));if(n.filter(y=>y.key!==f(t)).length&&!o?.recursive)throw k("directory not empty",t);for(let y of n)await e.del(y.key);await e.del(f(t))},async copy(i,o){let t=u(i),r=u(o);if(h(t,r))throw k("cannot copy into itself",r);let n=await m(t);if(n===null)throw x(t);if(await m(r)!==null)throw S(r);if(await w(r),n==="file"){let y=await e.get(c(t));y&&await e.put(c(r),y.body,y.meta);return}await e.put(f(r),L,{});let a=l(t);for(let y of await e.list(a)){let d=y.key.slice(a.length);if(d==="")continue;let g=l(r)+d;if(d.endsWith("/"))await e.put(g,L,{});else{let v=await e.get(y.key);v&&await e.put(g,v.body,v.meta)}}},async move(i,o){await this.copy(i,o),await this.remove(i,{recursive:!0})},async getMeta(i){let o=u(i),t=await m(o);if(t===null)throw x(o);return(await e.head(t==="file"?c(o):f(o)))?.meta??{}},async setMeta(i,o){let t=u(i),r=await m(t);if(r===null)throw x(t);if(r==="file"){let n=await e.get(c(t));await e.put(c(t),n?.body??L,o)}else await e.put(f(t),L,o)},watch(i,o){let t=u(i),r=l(t),n=c(t)?c(t)+"/":"",a=R=>u("/"+(p?R.slice(p.length+1):R)),y=new Map,d=!1,g=async()=>{let R=new Map;for(let D of await e.list(r))D.key!==n&&R.set(D.key,D.mtime);return R};g().then(R=>{y=R,d=!0});let v=!1,T=async()=>{if(!(!d||v)){v=!0;try{let R=await g();for(let[D,et]of R)y.has(D)?y.get(D)!==et&&o({type:"update",path:a(D)}):o({type:"create",path:a(D)});for(let D of y.keys())R.has(D)||o({type:"remove",path:a(D)});y=R}finally{v=!1}}},W=setInterval(()=>{T()},s.pollMs??200);return W.unref?.(),()=>clearInterval(W)}}}import{createRequire as lt}from"module";var{DatabaseSync:mt}=lt(import.meta.url)("node:sqlite"),wt={streaming:!1,watch:!1,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},ht=s=>s.replace(/[\\%_]/g,e=>"\\"+e);function gt(s){let e=new mt(s);e.exec("CREATE TABLE IF NOT EXISTS files (path TEXT PRIMARY KEY, type TEXT NOT NULL, data BLOB, meta TEXT NOT NULL DEFAULT '{}', version INTEGER NOT NULL DEFAULT 0)"),e.prepare("INSERT OR IGNORE INTO files (path, type) VALUES ('/', 'dir')").run();let p=e.prepare("SELECT path, type, data, meta, version FROM files WHERE path = ?"),c=e.prepare("INSERT INTO files (path, type, data, meta, version) VALUES (?, ?, ?, ?, ?) ON CONFLICT(path) DO UPDATE SET type=excluded.type, data=excluded.data, meta=excluded.meta, version=excluded.version"),f=e.prepare("DELETE FROM files WHERE path = ?"),l=e.prepare("SELECT path, type FROM files WHERE path LIKE ? ESCAPE '\\'"),h=n=>p.get(n),m=(n,a,y,d,g)=>c.run(n,a,y,JSON.stringify(d),g),w=(n,a)=>a===n||a.startsWith(n==="/"?"/":n+"/"),i=n=>l.all(ht(n==="/"?"/":n+"/")+"%").filter(a=>w(n,a.path)&&a.path!==n),o=n=>{let a=h(n);if(!a)throw x(n);return a},t=n=>{let a=F(n),y=h(a);if(!y)throw x(a);if(y.type!=="dir")throw O(a)},r=n=>n.data?new Uint8Array(n.data):new Uint8Array(0);return{capabilities:()=>wt,async read(n){let a=u(n),y=o(a);if(y.type==="dir")throw E(a);return r(y)},async write(n,a,y){let d=u(n);t(d);let g=h(d);if(g?.type==="dir")throw E(d);if(y?.ifAbsent&&g)throw S(d);if(y?.ifMatch!==void 0&&(g?String(g.version):void 0)!==y.ifMatch)throw C(d);let v=y?.meta??(g?JSON.parse(g.meta):{});m(d,"file",U(a),v,(g?.version??0)+1)},async list(n,a){let y=u(n);if(o(y).type!=="dir")throw O(y);let g=[];for(let v of i(y))!a?.recursive&&F(v.path)!==y||g.push({name:v.path.slice(v.path.lastIndexOf("/")+1),path:v.path,type:v.type});return g},async stat(n){let a=u(n),y=o(a);return{type:y.type,size:y.type==="file"?r(y).length:0,mtime:0,ctime:0,meta:JSON.parse(y.meta),version:y.type==="file"?String(y.version):void 0}},async exists(n){return!!h(u(n))},async mkdir(n,a){let y=u(n),d=h(y);if(d){if(a?.recursive&&d.type==="dir")return;throw S(y)}if(a?.recursive){let g="";for(let v of y.split("/").filter(Boolean)){g+="/"+v;let T=h(g);if(T?.type==="file")throw O(g);T||m(g,"dir",null,{},0)}return}t(y),m(y,"dir",null,{},0)},async remove(n,a){let y=u(n);if(y==="/")throw k("cannot remove root",y);o(y);let d=i(y);if(d.length&&!a?.recursive)throw k("directory not empty",y);for(let g of d)f.run(g.path);f.run(y)},async move(n,a){await this.copy(n,a),await this.remove(n,{recursive:!0})},async copy(n,a){let y=u(n),d=u(a);if(o(y),t(d),h(d))throw S(d);if(w(y,d))throw k("cannot copy into itself",d);for(let g of[y,...i(y).map(v=>v.path)]){let v=o(g);m(d+g.slice(y.length),v.type,v.data?new Uint8Array(v.data):null,JSON.parse(v.meta),(v.version??0)+1)}},async getMeta(n){return JSON.parse(o(u(n)).meta)},async setMeta(n,a){let y=u(n),d=o(y);m(y,d.type,d.data?new Uint8Array(d.data):null,a,d.type==="file"?d.version+1:d.version)},watch(){return()=>{}}}}var vt={streaming:!1,watch:!1,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0};function bt(s){let e="";for(let p=0;p<s.length;p+=32768)e+=String.fromCharCode(...s.subarray(p,p+32768));return btoa(e)}function X(s){let e=atob(s),p=new Uint8Array(e.length);for(let c=0;c<e.length;c++)p[c]=e.charCodeAt(c);return p}function kt(){let s=new Map;return{async get(e){return s.get(e)},async set(e,p){s.set(e,p)},async delete(e){s.delete(e)},async list(e){return[...s.keys()].filter(p=>p.startsWith(e))}}}function St(s=globalThis.localStorage){return{async get(e){return s.getItem(e)},async set(e,p){s.setItem(e,p)},async delete(e){s.removeItem(e)},async list(e){let p=[];for(let c=0;c<s.length;c++){let f=s.key(c);f&&f.startsWith(e)&&p.push(f)}return p}}}function xt(s){let e=s.store,p=(s.prefix?s.prefix+":":"")+"vfs:",c=r=>p+u(r),f=r=>r.slice(p.length),l=(r,n)=>n===r||n.startsWith(r==="/"?"/":r+"/"),h=async r=>{let n=await e.get(c(r));return n?JSON.parse(n):void 0},m=(r,n)=>e.set(c(r),JSON.stringify(n)),w=async r=>{let n=await h(r);if(!n)throw x(r);return n},i=async r=>(await e.list(c(r)===p+"/"?p+"/":c(r)+"/")).map(f).filter(n=>n!==r&&l(r,n)),o=async r=>{let n=F(r),a=await h(n);if(!a)throw x(n);if(a.t!=="dir")throw O(n)},t=(async()=>{await e.get(c("/"))||await m("/",{t:"dir",m:{},v:0})})();return{capabilities:()=>vt,async read(r){await t;let n=u(r),a=await w(n);if(a.t==="dir")throw E(n);return X(a.d??"")},async write(r,n,a){await t;let y=u(r);await o(y);let d=await h(y);if(d?.t==="dir")throw E(y);if(a?.ifAbsent&&d)throw S(y);if(a?.ifMatch!==void 0&&(d?String(d.v):void 0)!==a.ifMatch)throw C(y);await m(y,{t:"file",d:bt(U(n)),m:a?.meta??d?.m??{},v:(d?.v??0)+1})},async list(r,n){await t;let a=u(r);if((await w(a)).t!=="dir")throw O(a);let d=[];for(let g of await i(a)){if(!n?.recursive&&F(g)!==a)continue;let v=await h(g);v&&d.push({name:g.slice(g.lastIndexOf("/")+1),path:g,type:v.t})}return d},async stat(r){await t;let n=u(r),a=await w(n);return{type:a.t,size:a.t==="file"?X(a.d??"").length:0,mtime:0,ctime:0,meta:{...a.m},version:a.t==="file"?String(a.v):void 0}},async exists(r){return await t,!!await h(u(r))},async mkdir(r,n){await t;let a=u(r),y=await h(a);if(y){if(n?.recursive&&y.t==="dir")return;throw S(a)}if(n?.recursive){let d="";for(let g of a.split("/").filter(Boolean)){d+="/"+g;let v=await h(d);if(v?.t==="file")throw O(d);v||await m(d,{t:"dir",m:{},v:0})}return}await o(a),await m(a,{t:"dir",m:{},v:0})},async remove(r,n){await t;let a=u(r);if(a==="/")throw k("cannot remove root",a);await w(a);let y=await i(a);if(y.length&&!n?.recursive)throw k("directory not empty",a);for(let d of[...y,a])await e.delete(c(d))},async move(r,n){await this.copy(r,n),await this.remove(r,{recursive:!0})},async copy(r,n){await t;let a=u(r),y=u(n);if(await w(a),await o(y),await h(y))throw S(y);if(l(a,y))throw k("cannot copy into itself",y);for(let d of[a,...await i(a)]){let g=await h(d);g&&await m(y+d.slice(a.length),{...g,v:(g.v??0)+1})}},async getMeta(r){return await t,{...(await w(u(r))).m}},async setMeta(r,n){await t;let a=u(r),y=await w(a);await m(a,{...y,m:{...n},v:y.t==="file"?(y.v??0)+1:y.v})},watch(){return()=>{}}}}var K=new Uint8Array([86,75,1]),$=47,V=globalThis.crypto.subtle;function H(s){let e=new Uint8Array(s);return globalThis.crypto.getRandomValues(e),e}async function Ot(s,e){let p=await V.importKey("raw",new TextEncoder().encode(s),"PBKDF2",!1,["deriveKey"]);return V.deriveKey({name:"PBKDF2",salt:e.slice(),iterations:21e4,hash:"SHA-256"},p,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}function At(s,e){if(!e.key&&!e.passphrase)throw new Error("encrypt: key or passphrase required");let p=e.key?V.importKey("raw",e.key.slice(),"AES-GCM",!1,["encrypt","decrypt"]):null,c=l=>p??Ot(e.passphrase,l),f={...s.capabilities(),streaming:!1,randomAccess:!1};return{...s,readStream:void 0,writeStream:void 0,capabilities:()=>f,async stat(l){let h=await s.stat(l);return h.type==="file"?{...h,size:Math.max(0,h.size-$)}:h},async write(l,h,m){let w=H(16),i=H(12),o=await c(w),t=new Uint8Array(await V.encrypt({name:"AES-GCM",iv:i},o,U(h).slice()));await s.write(l,I([K,w,i,t]),m)},async read(l,h){let m=await s.read(l,h);if(m.length<$||m[0]!==K[0]||m[1]!==K[1]||m[2]!==K[2])throw k("invalid ciphertext",l);let w=await c(m.slice(3,19)),i;try{i=await V.decrypt({name:"AES-GCM",iv:m.slice(19,31)},w,m.slice(31))}catch{throw k("decryption failed",l)}return new Uint8Array(i)}}}function Et(s,e={}){let p=e.store??new Map,c=e.ttlMs??0,f=()=>c?Date.now():0,l=()=>c?Date.now()+c:1/0,h=(w,i)=>i===w||i.startsWith(w==="/"?"/":w+"/"),m=w=>{for(let i of[...p.keys()])h(w,i)&&p.delete(i)};return{...s,readStream:void 0,writeStream:void 0,async read(w,i){let o=u(w),t=p.get(o);if(t&&t.exp>f())return t.data.slice();let r=await s.read(o,i);return p.set(o,{data:r.slice(),exp:l()}),r.slice()},async write(w,i,o){let t=u(w),r=U(i).slice();await s.write(t,r,o),p.set(t,{data:r,exp:l()})},async remove(w,i){let o=u(w);await s.remove(o,i),m(o)},async move(w,i){let o=u(w),t=u(i);await s.move(o,t),m(o),m(t)},async copy(w,i){let o=u(w),t=u(i);await s.copy(o,t),m(t)}}}var Ut=new TextEncoder,Mt=new TextDecoder,B=new Uint8Array(0);function M(s,e=B){let p=Ut.encode(JSON.stringify(s)),c=new Uint8Array(4+p.length+e.length);return new DataView(c.buffer).setUint32(0,p.length),c.set(p,4),c.set(e,4+p.length),c}function Q(s){let p=new DataView(s.buffer,s.byteOffset,s.byteLength).getUint32(0);return{header:JSON.parse(Mt.decode(s.subarray(4,4+p))),data:s.subarray(4+p)}}function Z(s,e,p=[],c){return M({m:s,p:e,a:p},c)}function Tt(s){let{header:e,data:p}=Q(s);return{method:e.m,path:e.p,args:e.a??[],data:p}}function tt(s){let{header:e,data:p}=Q(s);return e.ok?{ok:!0,value:e.v,data:p}:{ok:!1,data:B,code:e.c,message:e.e,path:e.p}}async function q(s,e){let{method:p,path:c,args:f,data:l}=Tt(e);try{switch(p){case"read":return M({ok:!0},await s.read(c,f[0]));case"write":return await s.write(c,l,f[0]),M({ok:!0});case"list":return M({ok:!0,v:await s.list(c,f[0])});case"stat":return M({ok:!0,v:await s.stat(c)});case"exists":return M({ok:!0,v:await s.exists(c)});case"mkdir":return await s.mkdir(c,f[0]),M({ok:!0});case"remove":return await s.remove(c,f[0]),M({ok:!0});case"move":return await s.move(c,f[0]),M({ok:!0});case"copy":return await s.copy(c,f[0]),M({ok:!0});case"getMeta":return M({ok:!0,v:await s.getMeta(c)});case"setMeta":return await s.setMeta(c,f[0]),M({ok:!0});default:throw z(p)}}catch(h){let m=h instanceof A?h:k(String(h?.message??h),c);return M({ok:!1,c:m.code,e:m.message,p:m.path})}}function P(s,e,p=B){let c=new Uint8Array(5+p.length);return c[0]=s,new DataView(c.buffer).setUint32(1,e),c.set(p,5),c}function j(s){let e=new DataView(s.buffer,s.byteOffset,s.byteLength);return{type:s[0],id:e.getUint32(1),payload:s.subarray(5)}}var Rt=new TextEncoder,Dt=new TextDecoder;function Ft(s){return{handle:e=>q(s,e),async fetch(e){let p=new Uint8Array(await e.arrayBuffer());return new Response(await q(s,p),{headers:{"content-type":"application/octet-stream"}})},socket(e){let p=new Map;return{async message(c){let{type:f,id:l,payload:h}=j(c);if(f===0)e(P(1,l,await q(s,h)));else if(f===2){let{path:m}=JSON.parse(Dt.decode(h));p.set(l,s.watch(m,w=>e(P(4,l,Rt.encode(JSON.stringify(w))))))}else f===3&&(p.get(l)?.(),p.delete(l))},close(){for(let c of p.values())c();p.clear()}}}}}function Ct(s){let e=s.request?s:s.transport,p=s.capabilities??{streaming:!1,watch:!!e.watch,atomicMove:!1,nativeMeta:!0,randomAccess:!1,conditionalWrite:!0},c=async(f,l,h,m)=>{let w=h?[...h]:[];for(;w.length&&w[w.length-1]===void 0;)w.pop();let i=tt(await e.request(Z(f,l,w,m)));if(!i.ok)throw new A(i.code,i.message??"",i.path);return i};return{capabilities:()=>p,async read(f,l){return(await c("read",f,[l])).data},async write(f,l,h){await c("write",f,[h],U(l))},async list(f,l){return(await c("list",f,[l])).value},async stat(f){return(await c("stat",f)).value},async exists(f){return(await c("exists",f)).value},async mkdir(f,l){await c("mkdir",f,[l])},async remove(f,l){await c("remove",f,[l])},async move(f,l){await c("move",f,[l])},async copy(f,l){await c("copy",f,[l])},async getMeta(f){return(await c("getMeta",f)).value},async setMeta(f,l){await c("setMeta",f,[l])},watch(f,l){if(!e.watch)throw z("watch");return e.watch(f,l)}}}function Pt(s,e){let p=e??((c,f)=>fetch(c,f));return{async request(c){let f=await p(s,{method:"POST",body:c});return new Uint8Array(await f.arrayBuffer())}}}var Nt=new TextEncoder,Lt=new TextDecoder;function Wt(s,e){let p=e?e():new WebSocket(s);try{p.binaryType="arraybuffer"}catch{}let c=new Map,f=new Map,l=0,h=p.readyState===1?Promise.resolve():new Promise(m=>{p.addEventListener?p.addEventListener("open",()=>m()):p.onopen=()=>m()});return p.onmessage=m=>{let{type:w,id:i,payload:o}=j(new Uint8Array(m.data));w===1?(c.get(i)?.(o),c.delete(i)):w===4&&f.get(i)?.(JSON.parse(Lt.decode(o)))},{async request(m){await h;let w=++l;return new Promise(i=>{c.set(w,i),p.send(P(0,w,m))})},watch(m,w){let i=++l;return f.set(i,w),h.then(()=>p.send(P(2,i,Nt.encode(JSON.stringify({path:m}))))),()=>{f.delete(i),h.then(()=>p.send(P(3,i,B)))}}}}export{Y as BRAND,A as VfsError,S as alreadyExists,Vt as basename,Et as cache,$t as collect,I as concat,C as conflict,F as dirname,At as encrypt,Pt as httpTransport,k as io,E as isADirectory,qt as isVfsError,It as join,xt as kv,St as localStorageKv,kt as memKv,at as memory,ut as memoryS3,yt as nodeFs,u as normalize,O as notADirectory,x as notFound,Kt as permissionDenied,Gt as readStream,Ct as remote,dt as s3,Bt as segments,Ft as serve,gt as sqlite,U as toBytes,Jt as toText,z as unsupported,Xt as writeStream,Wt as wsTransport};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artemjs/vfskit",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Universal abstraction over any virtual file system - memory, disk, S3 and more - with composable adapters, encryption and a remote bridge. Backend kit.",
5
5
  "keywords": [
6
6
  "vfs",