@ai-ecoverse/slicc-kernel 1.131.0 → 1.132.0
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 +2 -0
- package/dist/index.js.map +1 -1
- package/dist/kernel-worker.js +27 -9
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js +21 -0
- package/dist/meta.js.map +3 -3
- package/dist/node-process-worker.js +1 -1
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +21 -6
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/process-worker.js.map +2 -2
- package/dist/types/fs/notice.d.ts +9 -0
- package/dist/types/fs/types.d.ts +1 -0
- package/dist/types/kernel/vfs-file.d.ts +1 -0
- package/dist/types/meta.d.ts +6 -0
- package/package.json +1 -1
package/dist/meta.js
CHANGED
|
@@ -305,6 +305,11 @@ async function openMeta(name, factory) {
|
|
|
305
305
|
return new IndexedDbMeta(await openMetaDb(name, factory));
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
// src/fs/notice.ts
|
|
309
|
+
function dirsChannel(metadata) {
|
|
310
|
+
return `slicc-kernel-dirs:${metadata}`;
|
|
311
|
+
}
|
|
312
|
+
|
|
308
313
|
// src/fs/types.ts
|
|
309
314
|
function fsError(code, path) {
|
|
310
315
|
return Object.assign(new Error(`${code}: ${path}`), { code });
|
|
@@ -389,7 +394,23 @@ async function writeMetadata(root, entries, options = {}) {
|
|
|
389
394
|
store.close();
|
|
390
395
|
}
|
|
391
396
|
}
|
|
397
|
+
function postFsNotice(notice, options = {}) {
|
|
398
|
+
const absolute = (list) => (list ?? []).map((path) => {
|
|
399
|
+
if (!String(path).startsWith("/")) throw fsError("EINVAL", `not an absolute path: ${path}`);
|
|
400
|
+
return normalizePath(String(path));
|
|
401
|
+
});
|
|
402
|
+
const paths = absolute(notice.paths);
|
|
403
|
+
const trees = absolute(notice.trees);
|
|
404
|
+
if (paths.length === 0 && trees.length === 0) return;
|
|
405
|
+
const channel = new BroadcastChannel(dirsChannel(options.metadata ?? META_DB));
|
|
406
|
+
try {
|
|
407
|
+
channel.postMessage({ paths, trees });
|
|
408
|
+
} finally {
|
|
409
|
+
channel.close();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
392
412
|
export {
|
|
413
|
+
postFsNotice,
|
|
393
414
|
writeMetadata
|
|
394
415
|
};
|
|
395
416
|
//# sourceMappingURL=meta.js.map
|
package/dist/meta.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/fs/path-map.ts", "../src/fs/meta.ts", "../src/fs/types.ts", "../src/meta.ts"],
|
|
4
|
-
"sourcesContent": ["function parentOf(path: string): string | undefined {\n if (path === '/' || path === '') return undefined;\n const at = path.lastIndexOf('/');\n return at <= 0 ? '/' : path.slice(0, at);\n}\n\nexport class PathMap<V> {\n private readonly values = new Map<string, V>();\n private readonly children = new Map<string, Set<string>>();\n\n get size(): number {\n return this.values.size;\n }\n\n has(path: string): boolean {\n return this.values.has(path);\n }\n\n get(path: string): V | undefined {\n return this.values.get(path);\n }\n\n keys(): IterableIterator<string> {\n return this.values.keys();\n }\n\n set(path: string, value: V): this {\n if (!this.values.has(path)) this.link(path);\n this.values.set(path, value);\n return this;\n }\n\n delete(path: string): boolean {\n if (!this.values.delete(path)) return false;\n this.prune(path);\n return true;\n }\n\n subtree(root: string): string[] {\n const out: string[] = [];\n const stack = [root];\n for (let path = stack.pop(); path !== undefined; path = stack.pop()) {\n if (this.values.has(path)) out.push(path);\n const below = this.children.get(path);\n if (below) for (const child of below) stack.push(child);\n }\n return out;\n }\n\n entries(): IterableIterator<[string, V]> {\n return this.values.entries();\n }\n\n deleteTree(root: string): void {\n const stack = [root];\n for (let path = stack.pop(); path !== undefined; path = stack.pop()) {\n this.values.delete(path);\n const below = this.children.get(path);\n if (below) for (const child of below) stack.push(child);\n this.children.delete(path);\n }\n this.prune(root);\n }\n\n clear(): void {\n this.values.clear();\n this.children.clear();\n }\n\n private link(path: string): void {\n for (let child = path, parent = parentOf(path); parent !== undefined; ) {\n const set = this.children.get(parent);\n if (set?.has(child)) return;\n if (set) set.add(child);\n else this.children.set(parent, new Set([child]));\n child = parent;\n parent = parentOf(parent);\n }\n }\n\n private prune(path: string): void {\n for (let child = path, parent = parentOf(path); parent !== undefined; ) {\n if (this.values.has(child) || this.children.has(child)) return;\n const set = this.children.get(parent);\n set?.delete(child);\n if (set && set.size > 0) return;\n this.children.delete(parent);\n child = parent;\n parent = parentOf(parent);\n }\n }\n}\n", "import { PathMap } from './path-map.ts';\nexport interface MetaEntry {\n path: string;\n mode?: number;\n atimeMs?: number;\n mtimeMs?: number;\n mtimeFor?: number;\n timesAt?: number;\n timesBy?: string;\n ctimeMs?: number;\n ino?: number;\n link?: string;\n socket?: true;\n fifo?: true;\n dir?: string;\n uid?: number;\n gid?: number;\n heir?: [number, number];\n writes?: number;\n epoch?: number;\n vacated?: true;\n rename?: { from: string; to: string; at: number; replace?: true };\n}\n\nexport type MetaChange = (entry: MetaEntry | undefined) => MetaEntry | undefined;\n\nexport interface MetaUpdate {\n path: string;\n change: MetaChange;\n}\n\nexport interface MetaStore {\n get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>>;\n fresh?(paths: readonly string[]): Promise<Array<MetaEntry | undefined>>;\n update(path: string, change: MetaChange): Promise<void>;\n updateMany?(changes: ReadonlyArray<MetaUpdate>): Promise<void>;\n move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ): Promise<void>;\n remove(paths: readonly string[]): Promise<void>;\n links(dir: string): Promise<MetaEntry[]>;\n under(path: string): Promise<MetaEntry[]>;\n all(): Promise<MetaEntry[]>;\n absent?(path: string): boolean;\n removeFile?(path: string): Promise<void>;\n}\n\nexport const META_DB = 'slicc-kernel';\nexport const META_VERSION = 1;\nexport const META_STORE = 'entries';\n\nfunction parentOf(path: string): string {\n return path.slice(0, path.lastIndexOf('/')) || '/';\n}\n\nfunction moved(entry: MetaEntry, path: string): MetaEntry {\n return entry.link === undefined ? { ...entry, path } : { ...entry, path, dir: parentOf(path) };\n}\n\nfunction under(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nexport class MemoryMeta implements MetaStore {\n private readonly entries = new PathMap<MetaEntry>();\n\n async get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n return paths.map((path) => this.entries.get(path));\n }\n\n async fresh(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n return this.get(paths);\n }\n\n async update(path: string, change: MetaChange): Promise<void> {\n this.set(path, change(this.entries.get(path)));\n }\n\n private set(path: string, entry: MetaEntry | undefined): void {\n if (entry) this.entries.set(path, entry);\n else this.entries.delete(path);\n }\n\n async move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ) {\n await this.remove([to]);\n const carried = this.entries.subtree(from).map((path) => this.entries.get(path) as MetaEntry);\n for (const entry of carried) this.entries.delete(entry.path);\n for (const entry of carried) {\n const path = to + entry.path.slice(from.length);\n if (path !== to) this.entries.set(path, moved(entry, path));\n }\n this.entries.set(to, moved(root(carried.find((entry) => entry.path === from)), to));\n if (left) this.entries.set(from, left);\n }\n\n async remove(paths: readonly string[]): Promise<void> {\n for (const path of paths) this.entries.deleteTree(path);\n }\n\n absent(path: string): boolean {\n return !this.entries.has(path);\n }\n\n async links(dir: string): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e).filter((entry) => entry.dir === dir);\n }\n\n async under(path: string): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e).filter((entry) => under(entry.path, path));\n }\n\n async all(): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e);\n }\n}\n\nfunction descendants(path: string): IDBKeyRange {\n return IDBKeyRange.bound(`${path}/`, `${path}0`, false, true);\n}\n\nfunction settle<T>(transaction: IDBTransaction, value: () => T): Promise<T> {\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => resolve(value());\n transaction.onabort = () =>\n reject(transaction.error ?? new Error('metadata transaction aborted'));\n });\n}\n\ninterface Invalidation {\n paths?: readonly string[];\n trees?: readonly string[];\n}\n\nconst REMOVE_BATCH = 256;\nconst REMOVE_WAIT_MS = 5;\n\nexport class IndexedDbMeta implements MetaStore {\n private readonly db: IDBDatabase;\n private readonly cache = new PathMap<MetaEntry | null>();\n private readonly channel: BroadcastChannel;\n private generation = 0;\n private readonly listeners = new Set<(change: Invalidation) => void>();\n\n listen(listener: (change: Invalidation) => void): void {\n this.listeners.add(listener);\n }\n\n constructor(db: IDBDatabase) {\n this.db = db;\n db.onversionchange = () => db.close();\n this.channel = new BroadcastChannel(`slicc-kernel-meta:${db.name}`);\n this.channel.onmessage = ({ data }) => {\n this.drop(data as Invalidation);\n for (const listener of this.listeners) listener(data as Invalidation);\n };\n (this.channel as BroadcastChannel & { unref?: () => void }).unref?.();\n }\n\n private drop({ paths = [], trees = [] }: Invalidation): void {\n this.generation++;\n for (const path of paths) this.cache.delete(path);\n for (const tree of trees) this.cache.deleteTree(tree);\n }\n\n private changed(invalidation: Invalidation): void {\n this.drop(invalidation);\n this.channel.postMessage(invalidation);\n }\n\n private transaction(mode: IDBTransactionMode): [IDBTransaction, IDBObjectStore] {\n const transaction = this.db.transaction(META_STORE, mode);\n return [transaction, transaction.objectStore(META_STORE)];\n }\n\n async get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n const missing = paths.filter((path) => !this.cache.has(path));\n if (missing.length > 0) {\n this.settleRemoves();\n const generation = this.generation;\n const [transaction, store] = this.transaction('readonly');\n const found = new Map<string, MetaEntry | null>();\n for (const path of missing) {\n const request = store.get(path);\n request.onsuccess = () => void found.set(path, request.result ?? null);\n }\n await settle(transaction, () => undefined);\n if (generation === this.generation)\n for (const [path, entry] of found) this.cache.set(path, entry);\n return paths.map(\n (path) => (found.has(path) ? found.get(path) : this.cache.get(path)) ?? undefined\n );\n }\n return paths.map((path) => this.cache.get(path) ?? undefined);\n }\n\n async fresh(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n const [transaction, store] = this.transaction('readonly');\n const requests = paths.map((path) => store.get(path));\n return settle(transaction, () =>\n requests.map((request) => (request.result as MetaEntry | undefined) ?? undefined)\n );\n }\n\n async update(path: string, change: MetaChange): Promise<void> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n const request = store.get(path);\n let next: MetaEntry | undefined;\n request.onsuccess = () => {\n next = change(request.result);\n if (next) store.put(next);\n else store.delete(path);\n };\n await settle(transaction, () => undefined);\n this.changed({ paths: [path] });\n this.cache.set(path, next ?? null);\n }\n\n async updateMany(changes: ReadonlyArray<MetaUpdate>): Promise<void> {\n if (changes.length === 0) return;\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n const next = new Map<string, MetaEntry | null>();\n for (const { path, change } of changes) {\n const request = store.get(path);\n request.onsuccess = () => {\n const entry = change(request.result);\n next.set(path, entry ?? null);\n if (entry) store.put(entry);\n else store.delete(path);\n };\n }\n await settle(transaction, () => undefined);\n this.changed({ paths: changes.map(({ path }) => path) });\n for (const [path, entry] of next) this.cache.set(path, entry);\n }\n\n close(): void {\n this.channel.close();\n this.db.close();\n }\n\n async move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ) {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n store.delete(to);\n store.delete(descendants(to));\n const source = store.get(from);\n const below = store.getAll(descendants(from));\n below.onsuccess = () => {\n store.delete(from);\n store.delete(descendants(from));\n for (const entry of below.result as MetaEntry[]) {\n store.put(moved(entry, to + entry.path.slice(from.length)));\n }\n store.put(moved(root(source.result), to));\n if (left) store.put(left);\n };\n await settle(transaction, () => undefined);\n this.changed({ trees: [from, to] });\n }\n\n absent(path: string): boolean {\n return this.cache.has(path) && this.cache.get(path) === null;\n }\n\n private removing = new Map<string, string>();\n private removeTimer: ReturnType<typeof setTimeout> | undefined;\n\n async remove(paths: readonly string[]): Promise<void> {\n this.settleRemoves();\n return this.removeNow(paths);\n }\n\n async removeFile(path: string): Promise<void> {\n const known = this.cache.get(path);\n if (!known) return this.remove([path]);\n this.generation++;\n this.cache.set(path, null);\n this.removing.set(path, JSON.stringify(known));\n if (this.removing.size >= REMOVE_BATCH) return this.flushRemoves();\n this.removeTimer ??= setTimeout(\n () => void this.flushRemoves().catch(() => undefined),\n REMOVE_WAIT_MS\n );\n }\n\n private async removeNow(paths: readonly string[]): Promise<void> {\n const [transaction, store] = this.transaction('readwrite');\n for (const path of paths) {\n store.delete(path);\n store.delete(descendants(path));\n }\n await settle(transaction, () => undefined);\n this.changed({ trees: paths });\n }\n\n private settleRemoves(): void {\n if (this.removing.size > 0) void this.flushRemoves().catch(() => undefined);\n }\n\n private flushRemoves(): Promise<void> {\n clearTimeout(this.removeTimer);\n this.removeTimer = undefined;\n const batch = this.removing;\n if (batch.size === 0) return Promise.resolve();\n this.removing = new Map();\n const [transaction, store] = this.transaction('readwrite');\n for (const [path, seen] of batch) {\n const request = store.get(path);\n request.onsuccess = () => {\n if (request.result && JSON.stringify(request.result) === seen) store.delete(path);\n };\n }\n const paths = [...batch.keys()];\n return settle(transaction, () => void this.channel.postMessage({ paths }));\n }\n\n async links(dir: string): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const request = store.index('dir').getAll(dir);\n return settle(transaction, () => request.result as MetaEntry[]);\n }\n\n async under(path: string): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const self = store.get(path);\n const below = store.getAll(descendants(path));\n return settle(transaction, () =>\n [self.result as MetaEntry | undefined, ...(below.result as MetaEntry[])].filter(\n (entry): entry is MetaEntry => entry !== undefined\n )\n );\n }\n\n async all(): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const request = store.getAll();\n return settle(transaction, () => request.result as MetaEntry[]);\n }\n}\n\nexport function openMetaDb(name: string, factory: IDBFactory): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = factory.open(name, META_VERSION);\n request.onupgradeneeded = (event) => {\n if (event.oldVersion < 1) {\n request.result.createObjectStore(META_STORE, { keyPath: 'path' }).createIndex('dir', 'dir');\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\nexport async function openMeta(name: string, factory: IDBFactory): Promise<IndexedDbMeta> {\n return new IndexedDbMeta(await openMetaDb(name, factory));\n}\n", "export interface FsStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n isSocket?: boolean;\n isFifo?: boolean;\n size: number;\n mode: number;\n mtime: Date;\n atime: Date;\n ctime: Date;\n ino: number;\n nlink?: number;\n dev?: number;\n readonly?: boolean;\n maxFile?: number;\n ranged?: boolean;\n linkable?: boolean;\n version?: string;\n uid?: number;\n gid?: number;\n}\n\nexport type UsersMode = 'off' | 'report' | 'enforce';\n\nexport const DEFAULT_USERS: UsersMode = 'enforce';\n\nexport interface Owner {\n uid: number;\n gid: number;\n}\n\nexport interface Perm {\n uid: number;\n gid: number;\n mode?: number;\n link?: string;\n}\n\nexport interface NewOwner extends Owner {\n mode?: number;\n parents?: number;\n socket?: boolean;\n fifo?: boolean;\n}\n\nexport interface CopyOptions {\n exclusive: boolean;\n owner?: NewOwner;\n}\n\nexport interface OwnerChange {\n uid?: number;\n gid?: number;\n follow?: boolean;\n kind?: 'chown' | 'adopt' | 'new';\n mode?: number;\n}\n\nexport interface HeldEntry {\n writeFile: KernelFs['writeFile'];\n direct: boolean;\n}\n\nexport interface Peers {\n joined(): Promise<unknown>;\n crowded(): boolean;\n watch(listener: (crowded: boolean) => void): void;\n fresh?(): void;\n}\n\nexport interface KernelFs {\n resolvePath(base: string, path: string): string;\n exclusive?<T>(path: string, run: (held: HeldEntry) => Promise<T>, follow?: boolean): Promise<T>;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: Uint8Array | string, owner?: NewOwner): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FsStat>;\n lstat(path: string): Promise<FsStat>;\n readdir(path: string): Promise<string[]>;\n readdirStat(path: string): Promise<Array<[string, FsStat | null]>>;\n mkdir(path: string, options?: { recursive?: boolean; owner?: NewOwner }): Promise<void>;\n rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean; file?: boolean }\n ): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n link(from: string, to: string, follow?: boolean): Promise<void>;\n links?(path: string): boolean;\n symlink(target: string, path: string, owner?: NewOwner): Promise<void>;\n readlink(path: string): Promise<string>;\n realpath?(path: string, follow: boolean): Promise<string>;\n createExclusive?(path: string, owner?: NewOwner): Promise<void>;\n copyFile?(from: string, to: string, options: CopyOptions): Promise<void>;\n readonly rootName?: string;\n chown?(path: string, change: OwnerChange): Promise<void>;\n trackOwners?(): void;\n onPeer?(settle: () => Promise<void>): void;\n remoteChanges?(listener: (change: { paths: readonly string[] }) => void): () => void;\n peers?(): Peers | undefined;\n crossings?(mounted: (path: string) => boolean): void;\n ancestry?(path: string): Promise<Array<Perm | undefined>>;\n hasOwner?(path: string): Promise<boolean>;\n chmod(path: string, mode: number): Promise<void>;\n append?(path: string, bytes: Uint8Array): Promise<number>;\n utimes(path: string, atime: Date, mtime: Date): Promise<void>;\n lutimes?(path: string, atime: Date, mtime: Date): Promise<void>;\n pread?(path: string, offset: number, length: number, version?: string): Promise<Uint8Array>;\n pwrite?(path: string, offset: number, bytes: Uint8Array, transfer?: boolean): Promise<void>;\n truncate?(path: string, size: number): Promise<void>;\n protect?(prefixes: readonly string[], versions?: boolean): void;\n unguarded?(): KernelFs;\n noLinks?(): KernelFs;\n mayChange?(path: string, follow: boolean, whole?: boolean): Promise<void>;\n commandTarget?(path: string): Promise<string | undefined>;\n readVersioned?(path: string, cached?: boolean): Promise<{ bytes: Uint8Array; version: string }>;\n version?(path: string, cached?: boolean): Promise<string>;\n opfsCalls?(): number;\n opfsOps?(): number;\n}\n\nexport type RangedOps = Required<Pick<KernelFs, 'pread' | 'pwrite' | 'truncate'>>;\n\nexport function rangedOps(fs: Partial<RangedOps>): RangedOps | undefined {\n const { pread, pwrite, truncate } = fs;\n if (!pread || !pwrite || !truncate) return undefined;\n return { pread: pread.bind(fs), pwrite: pwrite.bind(fs), truncate: truncate.bind(fs) };\n}\n\nexport async function lutimesOf(\n fs: KernelFs,\n path: string,\n atime: Date,\n mtime: Date\n): Promise<void> {\n if (fs.lutimes) return fs.lutimes(path, atime, mtime);\n if ((await fs.lstat(path)).isSymbolicLink) throw fsError('EOPNOTSUPP', path);\n return fs.utimes(path, atime, mtime);\n}\n\nexport function mayLink(fs: { links?(path: string): boolean }, path: string): boolean {\n return fs.links?.(path) ?? true;\n}\n\nexport function modeOption(mode: unknown): number {\n if (!Number.isInteger(mode) || (mode as number) < 0 || (mode as number) > 0o7777) {\n throw fsError('EINVAL', `not a mode: ${String(mode)}`);\n }\n return mode as number;\n}\n\nexport function fsError(code: string, path: string): Error & { code: string } {\n return Object.assign(new Error(`${code}: ${path}`), { code });\n}\n\nexport function normalizePath(path: string): string {\n const parts: string[] = [];\n for (const part of path.split('/')) {\n if (part === '' || part === '.') continue;\n if (part === '..') parts.pop();\n else parts.push(part);\n }\n return `/${parts.join('/')}`;\n}\n\nexport function resolvePath(base: string, path: string): string {\n return normalizePath(path.startsWith('/') ? path : `${base}/${path}`);\n}\n\nexport function inodeOf(path: string): number {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < path.length; i++) {\n const c = path.charCodeAt(i);\n h1 = Math.imul(h1 ^ c, 2654435761);\n h2 = Math.imul(h2 ^ c, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;\n}\n\nexport interface Redirect {\n of: string;\n to: string;\n}\n\nexport function redirected(of: string, to: string): Error {\n return Object.assign(fsError('EXDEV', `${of} leads to the mount at ${to}`), {\n redirect: { of: normalizePath(of), to: normalizePath(to) },\n });\n}\n\nexport function redirectOf(err: unknown): Redirect | undefined {\n return (err as { redirect?: Redirect } | null)?.redirect;\n}\n", "import { META_DB, type MetaEntry, openMeta } from './fs/meta.ts';\nimport { fsError, normalizePath } from './fs/types.ts';\n\nexport interface MetadataEntry {\n path: string;\n mode?: number;\n uid?: number;\n gid?: number;\n}\n\nexport interface WriteMetadataOptions {\n metadata?: string;\n indexedDB?: IDBFactory;\n}\n\nconst MAX_ID = 0xfffffffe;\n\nfunction id(value: unknown, what: string): number {\n if (!Number.isInteger(value) || (value as number) < 0 || (value as number) > MAX_ID) {\n throw fsError('EINVAL', `not a ${what}: ${String(value)}`);\n }\n return value as number;\n}\n\nfunction checked(entry: MetadataEntry): MetadataEntry {\n if (!String(entry.path).startsWith('/'))\n throw fsError('EINVAL', `not an absolute path: ${entry.path}`);\n const path = normalizePath(String(entry.path));\n if ((entry.uid === undefined) !== (entry.gid === undefined)) {\n throw fsError('EINVAL', `${path}: give both uid and gid, or neither`);\n }\n const mode = entry.mode;\n if (mode !== undefined && (!Number.isInteger(mode) || mode < 0 || mode > 0o7777)) {\n throw fsError('EINVAL', `${path}: not a mode: ${String(mode)}`);\n }\n return {\n path,\n ...(mode !== undefined ? { mode } : {}),\n ...(entry.uid !== undefined ? { uid: id(entry.uid, 'uid'), gid: id(entry.gid, 'gid') } : {}),\n };\n}\n\nasync function present(root: FileSystemDirectoryHandle, path: string): Promise<boolean> {\n const parts = path.split('/').filter(Boolean);\n let dir = root;\n for (const [i, name] of parts.entries()) {\n const last = i === parts.length - 1;\n try {\n dir = await dir.getDirectoryHandle(name);\n } catch {\n if (!last) return false;\n return dir.getFileHandle(name).then(\n () => true,\n () => false\n );\n }\n }\n return true;\n}\n\nexport async function writeMetadata(\n root: FileSystemDirectoryHandle,\n entries: readonly MetadataEntry[],\n options: WriteMetadataOptions = {}\n): Promise<void> {\n const merged = new Map<string, MetadataEntry>();\n for (const want of entries.map(checked))\n merged.set(want.path, { ...merged.get(want.path), ...want });\n const wanted = [...merged.values()];\n for (const { path } of wanted) {\n if (!(await present(root, path))) throw fsError('ENOENT', path);\n }\n const factory = options.indexedDB ?? globalThis.indexedDB;\n const store = await openMeta(options.metadata ?? META_DB, factory);\n const ctimeMs = Date.now();\n try {\n await store.updateMany(\n wanted.map((want) => ({\n path: want.path,\n change: (entry: MetaEntry | undefined): MetaEntry => ({\n ...entry,\n path: want.path,\n ...(want.mode !== undefined ? { mode: want.mode } : {}),\n ...(want.uid !== undefined ? { uid: want.uid, gid: want.gid as number } : {}),\n ctimeMs,\n }),\n }))\n );\n } finally {\n store.close();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/fs/path-map.ts", "../src/fs/meta.ts", "../src/fs/notice.ts", "../src/fs/types.ts", "../src/meta.ts"],
|
|
4
|
+
"sourcesContent": ["function parentOf(path: string): string | undefined {\n if (path === '/' || path === '') return undefined;\n const at = path.lastIndexOf('/');\n return at <= 0 ? '/' : path.slice(0, at);\n}\n\nexport class PathMap<V> {\n private readonly values = new Map<string, V>();\n private readonly children = new Map<string, Set<string>>();\n\n get size(): number {\n return this.values.size;\n }\n\n has(path: string): boolean {\n return this.values.has(path);\n }\n\n get(path: string): V | undefined {\n return this.values.get(path);\n }\n\n keys(): IterableIterator<string> {\n return this.values.keys();\n }\n\n set(path: string, value: V): this {\n if (!this.values.has(path)) this.link(path);\n this.values.set(path, value);\n return this;\n }\n\n delete(path: string): boolean {\n if (!this.values.delete(path)) return false;\n this.prune(path);\n return true;\n }\n\n subtree(root: string): string[] {\n const out: string[] = [];\n const stack = [root];\n for (let path = stack.pop(); path !== undefined; path = stack.pop()) {\n if (this.values.has(path)) out.push(path);\n const below = this.children.get(path);\n if (below) for (const child of below) stack.push(child);\n }\n return out;\n }\n\n entries(): IterableIterator<[string, V]> {\n return this.values.entries();\n }\n\n deleteTree(root: string): void {\n const stack = [root];\n for (let path = stack.pop(); path !== undefined; path = stack.pop()) {\n this.values.delete(path);\n const below = this.children.get(path);\n if (below) for (const child of below) stack.push(child);\n this.children.delete(path);\n }\n this.prune(root);\n }\n\n clear(): void {\n this.values.clear();\n this.children.clear();\n }\n\n private link(path: string): void {\n for (let child = path, parent = parentOf(path); parent !== undefined; ) {\n const set = this.children.get(parent);\n if (set?.has(child)) return;\n if (set) set.add(child);\n else this.children.set(parent, new Set([child]));\n child = parent;\n parent = parentOf(parent);\n }\n }\n\n private prune(path: string): void {\n for (let child = path, parent = parentOf(path); parent !== undefined; ) {\n if (this.values.has(child) || this.children.has(child)) return;\n const set = this.children.get(parent);\n set?.delete(child);\n if (set && set.size > 0) return;\n this.children.delete(parent);\n child = parent;\n parent = parentOf(parent);\n }\n }\n}\n", "import { PathMap } from './path-map.ts';\nexport interface MetaEntry {\n path: string;\n mode?: number;\n atimeMs?: number;\n mtimeMs?: number;\n mtimeFor?: number;\n timesAt?: number;\n timesBy?: string;\n ctimeMs?: number;\n ino?: number;\n link?: string;\n socket?: true;\n fifo?: true;\n dir?: string;\n uid?: number;\n gid?: number;\n heir?: [number, number];\n writes?: number;\n epoch?: number;\n vacated?: true;\n rename?: { from: string; to: string; at: number; replace?: true };\n}\n\nexport type MetaChange = (entry: MetaEntry | undefined) => MetaEntry | undefined;\n\nexport interface MetaUpdate {\n path: string;\n change: MetaChange;\n}\n\nexport interface MetaStore {\n get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>>;\n fresh?(paths: readonly string[]): Promise<Array<MetaEntry | undefined>>;\n update(path: string, change: MetaChange): Promise<void>;\n updateMany?(changes: ReadonlyArray<MetaUpdate>): Promise<void>;\n move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ): Promise<void>;\n remove(paths: readonly string[]): Promise<void>;\n links(dir: string): Promise<MetaEntry[]>;\n under(path: string): Promise<MetaEntry[]>;\n all(): Promise<MetaEntry[]>;\n absent?(path: string): boolean;\n removeFile?(path: string): Promise<void>;\n}\n\nexport const META_DB = 'slicc-kernel';\nexport const META_VERSION = 1;\nexport const META_STORE = 'entries';\n\nfunction parentOf(path: string): string {\n return path.slice(0, path.lastIndexOf('/')) || '/';\n}\n\nfunction moved(entry: MetaEntry, path: string): MetaEntry {\n return entry.link === undefined ? { ...entry, path } : { ...entry, path, dir: parentOf(path) };\n}\n\nfunction under(path: string, root: string): boolean {\n return path === root || path.startsWith(`${root}/`);\n}\n\nexport class MemoryMeta implements MetaStore {\n private readonly entries = new PathMap<MetaEntry>();\n\n async get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n return paths.map((path) => this.entries.get(path));\n }\n\n async fresh(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n return this.get(paths);\n }\n\n async update(path: string, change: MetaChange): Promise<void> {\n this.set(path, change(this.entries.get(path)));\n }\n\n private set(path: string, entry: MetaEntry | undefined): void {\n if (entry) this.entries.set(path, entry);\n else this.entries.delete(path);\n }\n\n async move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ) {\n await this.remove([to]);\n const carried = this.entries.subtree(from).map((path) => this.entries.get(path) as MetaEntry);\n for (const entry of carried) this.entries.delete(entry.path);\n for (const entry of carried) {\n const path = to + entry.path.slice(from.length);\n if (path !== to) this.entries.set(path, moved(entry, path));\n }\n this.entries.set(to, moved(root(carried.find((entry) => entry.path === from)), to));\n if (left) this.entries.set(from, left);\n }\n\n async remove(paths: readonly string[]): Promise<void> {\n for (const path of paths) this.entries.deleteTree(path);\n }\n\n absent(path: string): boolean {\n return !this.entries.has(path);\n }\n\n async links(dir: string): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e).filter((entry) => entry.dir === dir);\n }\n\n async under(path: string): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e).filter((entry) => under(entry.path, path));\n }\n\n async all(): Promise<MetaEntry[]> {\n return [...this.entries.entries()].map(([, e]) => e);\n }\n}\n\nfunction descendants(path: string): IDBKeyRange {\n return IDBKeyRange.bound(`${path}/`, `${path}0`, false, true);\n}\n\nfunction settle<T>(transaction: IDBTransaction, value: () => T): Promise<T> {\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => resolve(value());\n transaction.onabort = () =>\n reject(transaction.error ?? new Error('metadata transaction aborted'));\n });\n}\n\ninterface Invalidation {\n paths?: readonly string[];\n trees?: readonly string[];\n}\n\nconst REMOVE_BATCH = 256;\nconst REMOVE_WAIT_MS = 5;\n\nexport class IndexedDbMeta implements MetaStore {\n private readonly db: IDBDatabase;\n private readonly cache = new PathMap<MetaEntry | null>();\n private readonly channel: BroadcastChannel;\n private generation = 0;\n private readonly listeners = new Set<(change: Invalidation) => void>();\n\n listen(listener: (change: Invalidation) => void): void {\n this.listeners.add(listener);\n }\n\n constructor(db: IDBDatabase) {\n this.db = db;\n db.onversionchange = () => db.close();\n this.channel = new BroadcastChannel(`slicc-kernel-meta:${db.name}`);\n this.channel.onmessage = ({ data }) => {\n this.drop(data as Invalidation);\n for (const listener of this.listeners) listener(data as Invalidation);\n };\n (this.channel as BroadcastChannel & { unref?: () => void }).unref?.();\n }\n\n private drop({ paths = [], trees = [] }: Invalidation): void {\n this.generation++;\n for (const path of paths) this.cache.delete(path);\n for (const tree of trees) this.cache.deleteTree(tree);\n }\n\n private changed(invalidation: Invalidation): void {\n this.drop(invalidation);\n this.channel.postMessage(invalidation);\n }\n\n private transaction(mode: IDBTransactionMode): [IDBTransaction, IDBObjectStore] {\n const transaction = this.db.transaction(META_STORE, mode);\n return [transaction, transaction.objectStore(META_STORE)];\n }\n\n async get(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n const missing = paths.filter((path) => !this.cache.has(path));\n if (missing.length > 0) {\n this.settleRemoves();\n const generation = this.generation;\n const [transaction, store] = this.transaction('readonly');\n const found = new Map<string, MetaEntry | null>();\n for (const path of missing) {\n const request = store.get(path);\n request.onsuccess = () => void found.set(path, request.result ?? null);\n }\n await settle(transaction, () => undefined);\n if (generation === this.generation)\n for (const [path, entry] of found) this.cache.set(path, entry);\n return paths.map(\n (path) => (found.has(path) ? found.get(path) : this.cache.get(path)) ?? undefined\n );\n }\n return paths.map((path) => this.cache.get(path) ?? undefined);\n }\n\n async fresh(paths: readonly string[]): Promise<Array<MetaEntry | undefined>> {\n const [transaction, store] = this.transaction('readonly');\n const requests = paths.map((path) => store.get(path));\n return settle(transaction, () =>\n requests.map((request) => (request.result as MetaEntry | undefined) ?? undefined)\n );\n }\n\n async update(path: string, change: MetaChange): Promise<void> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n const request = store.get(path);\n let next: MetaEntry | undefined;\n request.onsuccess = () => {\n next = change(request.result);\n if (next) store.put(next);\n else store.delete(path);\n };\n await settle(transaction, () => undefined);\n this.changed({ paths: [path] });\n this.cache.set(path, next ?? null);\n }\n\n async updateMany(changes: ReadonlyArray<MetaUpdate>): Promise<void> {\n if (changes.length === 0) return;\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n const next = new Map<string, MetaEntry | null>();\n for (const { path, change } of changes) {\n const request = store.get(path);\n request.onsuccess = () => {\n const entry = change(request.result);\n next.set(path, entry ?? null);\n if (entry) store.put(entry);\n else store.delete(path);\n };\n }\n await settle(transaction, () => undefined);\n this.changed({ paths: changes.map(({ path }) => path) });\n for (const [path, entry] of next) this.cache.set(path, entry);\n }\n\n close(): void {\n this.channel.close();\n this.db.close();\n }\n\n async move(\n from: string,\n to: string,\n root: (entry: MetaEntry | undefined) => MetaEntry,\n left?: MetaEntry\n ) {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readwrite');\n store.delete(to);\n store.delete(descendants(to));\n const source = store.get(from);\n const below = store.getAll(descendants(from));\n below.onsuccess = () => {\n store.delete(from);\n store.delete(descendants(from));\n for (const entry of below.result as MetaEntry[]) {\n store.put(moved(entry, to + entry.path.slice(from.length)));\n }\n store.put(moved(root(source.result), to));\n if (left) store.put(left);\n };\n await settle(transaction, () => undefined);\n this.changed({ trees: [from, to] });\n }\n\n absent(path: string): boolean {\n return this.cache.has(path) && this.cache.get(path) === null;\n }\n\n private removing = new Map<string, string>();\n private removeTimer: ReturnType<typeof setTimeout> | undefined;\n\n async remove(paths: readonly string[]): Promise<void> {\n this.settleRemoves();\n return this.removeNow(paths);\n }\n\n async removeFile(path: string): Promise<void> {\n const known = this.cache.get(path);\n if (!known) return this.remove([path]);\n this.generation++;\n this.cache.set(path, null);\n this.removing.set(path, JSON.stringify(known));\n if (this.removing.size >= REMOVE_BATCH) return this.flushRemoves();\n this.removeTimer ??= setTimeout(\n () => void this.flushRemoves().catch(() => undefined),\n REMOVE_WAIT_MS\n );\n }\n\n private async removeNow(paths: readonly string[]): Promise<void> {\n const [transaction, store] = this.transaction('readwrite');\n for (const path of paths) {\n store.delete(path);\n store.delete(descendants(path));\n }\n await settle(transaction, () => undefined);\n this.changed({ trees: paths });\n }\n\n private settleRemoves(): void {\n if (this.removing.size > 0) void this.flushRemoves().catch(() => undefined);\n }\n\n private flushRemoves(): Promise<void> {\n clearTimeout(this.removeTimer);\n this.removeTimer = undefined;\n const batch = this.removing;\n if (batch.size === 0) return Promise.resolve();\n this.removing = new Map();\n const [transaction, store] = this.transaction('readwrite');\n for (const [path, seen] of batch) {\n const request = store.get(path);\n request.onsuccess = () => {\n if (request.result && JSON.stringify(request.result) === seen) store.delete(path);\n };\n }\n const paths = [...batch.keys()];\n return settle(transaction, () => void this.channel.postMessage({ paths }));\n }\n\n async links(dir: string): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const request = store.index('dir').getAll(dir);\n return settle(transaction, () => request.result as MetaEntry[]);\n }\n\n async under(path: string): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const self = store.get(path);\n const below = store.getAll(descendants(path));\n return settle(transaction, () =>\n [self.result as MetaEntry | undefined, ...(below.result as MetaEntry[])].filter(\n (entry): entry is MetaEntry => entry !== undefined\n )\n );\n }\n\n async all(): Promise<MetaEntry[]> {\n this.settleRemoves();\n const [transaction, store] = this.transaction('readonly');\n const request = store.getAll();\n return settle(transaction, () => request.result as MetaEntry[]);\n }\n}\n\nexport function openMetaDb(name: string, factory: IDBFactory): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = factory.open(name, META_VERSION);\n request.onupgradeneeded = (event) => {\n if (event.oldVersion < 1) {\n request.result.createObjectStore(META_STORE, { keyPath: 'path' }).createIndex('dir', 'dir');\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\nexport async function openMeta(name: string, factory: IDBFactory): Promise<IndexedDbMeta> {\n return new IndexedDbMeta(await openMetaDb(name, factory));\n}\n", "export interface FsNotice {\n paths?: readonly string[];\n trees?: readonly string[];\n}\n\nexport function dirsChannel(metadata: string): string {\n return `slicc-kernel-dirs:${metadata}`;\n}\n\nexport function noticeOf(data: unknown): { paths: string[]; trees: string[] } {\n if (Array.isArray(data)) return { paths: data.filter((p) => typeof p === 'string'), trees: [] };\n const notice = (data ?? {}) as FsNotice;\n const strings = (list: unknown) =>\n Array.isArray(list) ? list.filter((p): p is string => typeof p === 'string') : [];\n return { paths: strings(notice.paths), trees: strings(notice.trees) };\n}\n", "export interface FsStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n isSocket?: boolean;\n isFifo?: boolean;\n size: number;\n mode: number;\n mtime: Date;\n atime: Date;\n ctime: Date;\n ino: number;\n nlink?: number;\n dev?: number;\n readonly?: boolean;\n maxFile?: number;\n ranged?: boolean;\n linkable?: boolean;\n version?: string;\n uid?: number;\n gid?: number;\n}\n\nexport type UsersMode = 'off' | 'report' | 'enforce';\n\nexport const DEFAULT_USERS: UsersMode = 'enforce';\n\nexport interface Owner {\n uid: number;\n gid: number;\n}\n\nexport interface Perm {\n uid: number;\n gid: number;\n mode?: number;\n link?: string;\n}\n\nexport interface NewOwner extends Owner {\n mode?: number;\n parents?: number;\n socket?: boolean;\n fifo?: boolean;\n}\n\nexport interface CopyOptions {\n exclusive: boolean;\n owner?: NewOwner;\n}\n\nexport interface OwnerChange {\n uid?: number;\n gid?: number;\n follow?: boolean;\n kind?: 'chown' | 'adopt' | 'new';\n mode?: number;\n}\n\nexport interface HeldEntry {\n writeFile: KernelFs['writeFile'];\n direct: boolean;\n}\n\nexport interface Peers {\n joined(): Promise<unknown>;\n crowded(): boolean;\n watch(listener: (crowded: boolean) => void): void;\n fresh?(): void;\n}\n\nexport interface KernelFs {\n resolvePath(base: string, path: string): string;\n exclusive?<T>(path: string, run: (held: HeldEntry) => Promise<T>, follow?: boolean): Promise<T>;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: Uint8Array | string, owner?: NewOwner): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FsStat>;\n lstat(path: string): Promise<FsStat>;\n readdir(path: string): Promise<string[]>;\n readdirStat(path: string): Promise<Array<[string, FsStat | null]>>;\n mkdir(path: string, options?: { recursive?: boolean; owner?: NewOwner }): Promise<void>;\n rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean; file?: boolean }\n ): Promise<void>;\n rename(from: string, to: string): Promise<void>;\n link(from: string, to: string, follow?: boolean): Promise<void>;\n links?(path: string): boolean;\n symlink(target: string, path: string, owner?: NewOwner): Promise<void>;\n readlink(path: string): Promise<string>;\n realpath?(path: string, follow: boolean): Promise<string>;\n createExclusive?(path: string, owner?: NewOwner): Promise<void>;\n copyFile?(from: string, to: string, options: CopyOptions): Promise<void>;\n readonly rootName?: string;\n chown?(path: string, change: OwnerChange): Promise<void>;\n trackOwners?(): void;\n onPeer?(settle: () => Promise<void>): void;\n remoteChanges?(\n listener: (change: { paths: readonly string[]; trees?: readonly string[] }) => void\n ): () => void;\n peers?(): Peers | undefined;\n crossings?(mounted: (path: string) => boolean): void;\n ancestry?(path: string): Promise<Array<Perm | undefined>>;\n hasOwner?(path: string): Promise<boolean>;\n chmod(path: string, mode: number): Promise<void>;\n append?(path: string, bytes: Uint8Array): Promise<number>;\n utimes(path: string, atime: Date, mtime: Date): Promise<void>;\n lutimes?(path: string, atime: Date, mtime: Date): Promise<void>;\n pread?(path: string, offset: number, length: number, version?: string): Promise<Uint8Array>;\n pwrite?(path: string, offset: number, bytes: Uint8Array, transfer?: boolean): Promise<void>;\n truncate?(path: string, size: number): Promise<void>;\n protect?(prefixes: readonly string[], versions?: boolean): void;\n unguarded?(): KernelFs;\n noLinks?(): KernelFs;\n mayChange?(path: string, follow: boolean, whole?: boolean): Promise<void>;\n commandTarget?(path: string): Promise<string | undefined>;\n readVersioned?(path: string, cached?: boolean): Promise<{ bytes: Uint8Array; version: string }>;\n version?(path: string, cached?: boolean): Promise<string>;\n opfsCalls?(): number;\n opfsOps?(): number;\n}\n\nexport type RangedOps = Required<Pick<KernelFs, 'pread' | 'pwrite' | 'truncate'>>;\n\nexport function rangedOps(fs: Partial<RangedOps>): RangedOps | undefined {\n const { pread, pwrite, truncate } = fs;\n if (!pread || !pwrite || !truncate) return undefined;\n return { pread: pread.bind(fs), pwrite: pwrite.bind(fs), truncate: truncate.bind(fs) };\n}\n\nexport async function lutimesOf(\n fs: KernelFs,\n path: string,\n atime: Date,\n mtime: Date\n): Promise<void> {\n if (fs.lutimes) return fs.lutimes(path, atime, mtime);\n if ((await fs.lstat(path)).isSymbolicLink) throw fsError('EOPNOTSUPP', path);\n return fs.utimes(path, atime, mtime);\n}\n\nexport function mayLink(fs: { links?(path: string): boolean }, path: string): boolean {\n return fs.links?.(path) ?? true;\n}\n\nexport function modeOption(mode: unknown): number {\n if (!Number.isInteger(mode) || (mode as number) < 0 || (mode as number) > 0o7777) {\n throw fsError('EINVAL', `not a mode: ${String(mode)}`);\n }\n return mode as number;\n}\n\nexport function fsError(code: string, path: string): Error & { code: string } {\n return Object.assign(new Error(`${code}: ${path}`), { code });\n}\n\nexport function normalizePath(path: string): string {\n const parts: string[] = [];\n for (const part of path.split('/')) {\n if (part === '' || part === '.') continue;\n if (part === '..') parts.pop();\n else parts.push(part);\n }\n return `/${parts.join('/')}`;\n}\n\nexport function resolvePath(base: string, path: string): string {\n return normalizePath(path.startsWith('/') ? path : `${base}/${path}`);\n}\n\nexport function inodeOf(path: string): number {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < path.length; i++) {\n const c = path.charCodeAt(i);\n h1 = Math.imul(h1 ^ c, 2654435761);\n h2 = Math.imul(h2 ^ c, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;\n}\n\nexport interface Redirect {\n of: string;\n to: string;\n}\n\nexport function redirected(of: string, to: string): Error {\n return Object.assign(fsError('EXDEV', `${of} leads to the mount at ${to}`), {\n redirect: { of: normalizePath(of), to: normalizePath(to) },\n });\n}\n\nexport function redirectOf(err: unknown): Redirect | undefined {\n return (err as { redirect?: Redirect } | null)?.redirect;\n}\n", "import { META_DB, type MetaEntry, openMeta } from './fs/meta.ts';\nimport { dirsChannel, type FsNotice } from './fs/notice.ts';\nimport { fsError, normalizePath } from './fs/types.ts';\n\nexport type { FsNotice };\n\nexport interface MetadataEntry {\n path: string;\n mode?: number;\n uid?: number;\n gid?: number;\n}\n\nexport interface WriteMetadataOptions {\n metadata?: string;\n indexedDB?: IDBFactory;\n}\n\nconst MAX_ID = 0xfffffffe;\n\nfunction id(value: unknown, what: string): number {\n if (!Number.isInteger(value) || (value as number) < 0 || (value as number) > MAX_ID) {\n throw fsError('EINVAL', `not a ${what}: ${String(value)}`);\n }\n return value as number;\n}\n\nfunction checked(entry: MetadataEntry): MetadataEntry {\n if (!String(entry.path).startsWith('/'))\n throw fsError('EINVAL', `not an absolute path: ${entry.path}`);\n const path = normalizePath(String(entry.path));\n if ((entry.uid === undefined) !== (entry.gid === undefined)) {\n throw fsError('EINVAL', `${path}: give both uid and gid, or neither`);\n }\n const mode = entry.mode;\n if (mode !== undefined && (!Number.isInteger(mode) || mode < 0 || mode > 0o7777)) {\n throw fsError('EINVAL', `${path}: not a mode: ${String(mode)}`);\n }\n return {\n path,\n ...(mode !== undefined ? { mode } : {}),\n ...(entry.uid !== undefined ? { uid: id(entry.uid, 'uid'), gid: id(entry.gid, 'gid') } : {}),\n };\n}\n\nasync function present(root: FileSystemDirectoryHandle, path: string): Promise<boolean> {\n const parts = path.split('/').filter(Boolean);\n let dir = root;\n for (const [i, name] of parts.entries()) {\n const last = i === parts.length - 1;\n try {\n dir = await dir.getDirectoryHandle(name);\n } catch {\n if (!last) return false;\n return dir.getFileHandle(name).then(\n () => true,\n () => false\n );\n }\n }\n return true;\n}\n\nexport async function writeMetadata(\n root: FileSystemDirectoryHandle,\n entries: readonly MetadataEntry[],\n options: WriteMetadataOptions = {}\n): Promise<void> {\n const merged = new Map<string, MetadataEntry>();\n for (const want of entries.map(checked))\n merged.set(want.path, { ...merged.get(want.path), ...want });\n const wanted = [...merged.values()];\n for (const { path } of wanted) {\n if (!(await present(root, path))) throw fsError('ENOENT', path);\n }\n const factory = options.indexedDB ?? globalThis.indexedDB;\n const store = await openMeta(options.metadata ?? META_DB, factory);\n const ctimeMs = Date.now();\n try {\n await store.updateMany(\n wanted.map((want) => ({\n path: want.path,\n change: (entry: MetaEntry | undefined): MetaEntry => ({\n ...entry,\n path: want.path,\n ...(want.mode !== undefined ? { mode: want.mode } : {}),\n ...(want.uid !== undefined ? { uid: want.uid, gid: want.gid as number } : {}),\n ctimeMs,\n }),\n }))\n );\n } finally {\n store.close();\n }\n}\n\nexport interface PostFsNoticeOptions {\n metadata?: string;\n}\n\nexport function postFsNotice(notice: FsNotice, options: PostFsNoticeOptions = {}): void {\n const absolute = (list: readonly string[] | undefined) =>\n (list ?? []).map((path) => {\n if (!String(path).startsWith('/')) throw fsError('EINVAL', `not an absolute path: ${path}`);\n return normalizePath(String(path));\n });\n const paths = absolute(notice.paths);\n const trees = absolute(notice.trees);\n if (paths.length === 0 && trees.length === 0) return;\n const channel = new BroadcastChannel(dirsChannel(options.metadata ?? META_DB));\n try {\n channel.postMessage({ paths, trees });\n } finally {\n channel.close();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["parentOf"]
|
|
7
7
|
}
|
|
@@ -6479,7 +6479,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
6479
6479
|
var init_version = __esm({
|
|
6480
6480
|
"src/version.ts"() {
|
|
6481
6481
|
"use strict";
|
|
6482
|
-
KERNEL_VERSION = true ? "1.
|
|
6482
|
+
KERNEL_VERSION = true ? "1.132.0" : "0.0.0-dev";
|
|
6483
6483
|
OS_RELEASE = "6.0.0-slicc";
|
|
6484
6484
|
}
|
|
6485
6485
|
});
|