UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

112 lines • 4.73 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { SystemClock } from "../../utils/clock.js"; export class IndexCacheStore { /** The clock every listing deadline of this store is set and read on. */ clock; /** @param clock the clock listings expire on; undefined means the real one. */ constructor(clock = new SystemClock()) { this.clock = clock; } /** Apply this index's ownership rules to a refill snapshot. */ scopeSnapshot(snapshot) { return snapshot; } /** Read retained rows by path, omitting missing entries. */ async getMany(vfsPaths) { const rows = new Map(); for (const path of new Set(vfsPaths)) { const entry = (await this.get(path)).entry; if (entry != null) rows.set(path, entry); } return rows; } /** Atomically replace an existing row without renewing its listing; custom stores may decline. */ replaceIfUnchanged(_path, _predecessor, _entry) { return Promise.resolve(false); } /** * Hand children a re-list found gone to the mount's cleanup. A raw store * belongs to no mount, so there is nothing to clean. */ reportGone(_gone) { return Promise.resolve(); } /** Token captured before fetching listings, including descendant seeds. */ refillToken() { throw new Error('refillToken is not implemented'); } /** Expire complete parent listings contradicted by the observed immediate child keys. */ invalidateMissing(_paths) { throw new Error('invalidateMissing is not implemented'); } /** null rejects an older refill without reporting any deletions. */ refillDir(_path, _entries, _token, _expiredAt, _options = {}) { throw new Error('refillDir is not implemented'); } /** * Cache observed children without claiming a complete directory. Stores * supporting partial freshness return these keys as `partialEntries` * until expiry or invalidation. A partial listing proves nothing * complete, so it carries no version. Custom stores inherit the conservative * put-only fallback, which refreshes the parent on the next lookup. */ async setPartialDir(vfsPath, entries, _expiredAt) { await this.invalidateDir(vfsPath); const stem = vfsPath.replace(/\/$/, ''); for (const [name, entry] of entries) await this.put(`${stem}/${name}`, entry); } /** * Whether the running command fetched `folder`'s listing itself. * * A raw store belongs to no mount and no command, so it cannot tell and * answers false; a mount's view answers from its cache manager. Mirrors * Python's `listed_this_command`. */ listedThisCommand(_folder) { return false; } /** * Whether a listing is cached at `vfsPath` or anywhere under it. * * Asked when a removed path may be a folder, to avoid a subtree scan for * each plain-file delete. Only a retained listing counts, even one past its * ttl (expiry is checked when it is read). A row or tombstone does not prove * a listing remains below the path. A children-first delete stream may * already have removed every listing before the folder's own event arrives. * * A store that cannot tell answers true, so callers conservatively drop * the subtree and refetch it. * * Mirrors Python `IndexCacheStore.holds_subtree`. */ holdsSubtree(_vfsPath) { return Promise.resolve(true); } /** * Release whatever the store holds open. The default is a no-op: * an in-memory index owns nothing. A store backed by a connection * (redis) overrides this and must be idempotent — `close()` is * called once per owning VFS, and a VFS shared between * workspaces is closed by whichever one owns it. * * Mirrors Python `IndexCacheStore.close` (`cache/index/store.py`). */ close() { return Promise.resolve(); } } //# sourceMappingURL=store.js.map