@objectstack/metadata-fs 17.3.0 → 17.4.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/CHANGELOG.md +15 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @objectstack/metadata-fs
|
|
2
2
|
|
|
3
|
+
## 17.4.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c5d6803: Published `.js.map` files no longer embed the complete original source text (`sourcesContent`) — comments included. `sourcemap: true` was esbuild shorthand, and esbuild's own default for `sourcesContent` is `true`; nobody had decided to publish every package's full source (including `@internal`/test-only comments) to npm inside its source maps, it fell out of a default nobody had looked at. Measured before this change: 55 of 57 publishable packages shipped embedded source text, and maps were roughly half of `@objectstack/spec`'s published bytes.
|
|
8
|
+
|
|
9
|
+
`sourcesContent: false` is now set at one shared place (`scripts/tsup-drop-sources-content.mjs`, wired into every `tsup.config.ts` via tsup's `esbuildOptions` hook — most packages build through the repo-root config directly and pick this up with no config change of their own). `mappings` are untouched, so stack-trace positions still resolve correctly to the original file/line/column; only the embedded source text is gone.
|
|
10
|
+
|
|
11
|
+
`@objectstack/cli` (built with `tsc`, not `tsup`) never embedded source text to begin with — its maps' `sources` entries point at `src/**` paths that are not part of the published tarball either way. That is not a defect unique to `cli`: every `tsup`-built package's `sources` entries are `../src/**`-relative paths that are equally outside `files: ["dist", …]`, and were merely masked by the embedded content that just stopped shipping. Shipping `src/**` in `files[]` to make `sources` resolve was rejected — it would put most of the removed bytes straight back. So `cli`'s maps are left exactly as `tsc` emits them: this is now the fleet-consistent shape (accurate `mappings`, non-resolving-but-honest `sources` labels, no embedded text), not an outlier.
|
|
12
|
+
|
|
13
|
+
A new gate, `pnpm check:sourcemap-no-sources-content`, sweeps every built, non-private package's `dist/**/*.map` and fails if any of them carries a non-empty `sourcesContent` array — so a future `tsup.config.ts` that skips the shared hook, or a toolchain upgrade that changes esbuild's default back, is caught rather than silently re-publishing source text.
|
|
14
|
+
- Updated dependencies [c5d6803]
|
|
15
|
+
- Updated dependencies [4df2a98]
|
|
16
|
+
- @objectstack/metadata-core@17.4.0
|
|
17
|
+
|
|
3
18
|
## 17.3.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/repository.ts","../src/layout.ts","../src/jsonl-log.ts","../src/sync.ts","../src/watch-iterable.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nexport * from './repository.js';\nexport { JsonlLog } from './jsonl-log.js';\nexport type { FsLayout } from './layout.js';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * `FileSystemRepository` — Node-only implementation of\n * `MetadataRepository` backed by JSON files plus a JSONL change log.\n *\n * See `README.md` for the on-disk layout and ADR-0008 §10 PR-4 for the\n * design rationale.\n *\n * Invariants\n * ──────────\n * - All `put` / `delete` ops serialize per-key via `KeyedMutex`.\n * - The change-log JSONL is the durable source of `seq`. On boot we\n * scan the log to learn the next seq value.\n * - Body files (`<type>/<name>.json`) are the source of truth; the\n * log is a denormalised history index.\n * - chokidar-driven external edits are translated into MetadataEvents\n * by hashing the new content and comparing to the last-known hash.\n * - The root directory is created **on the first write, not on attach**\n * (#7000). Attaching and reading a repository whose root does not exist\n * is legal and answers \"empty\"; see `start()` / `ensureRoot()`.\n * - `close()` ENDS every live `watch()` iterator — the same observation the\n * consumer's own `iterator.return()` produces, never a synthetic event\n * standing in for shutdown (#11127; invariant 8 in `metadata-core`).\n */\n\nimport fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport type { FSWatcher } from 'chokidar';\nimport chokidar from 'chokidar';\nimport {\n type MetadataRepository,\n type MetaRef,\n type MetadataItem,\n type MetadataItemHeader,\n type MetadataEvent,\n type PutOptions,\n type PutResult,\n type DeleteOptions,\n type DeleteResult,\n type ListFilter,\n type WatchFilter,\n type HistoryOptions,\n type MetadataType,\n hashSpec,\n ConflictError,\n refKey,\n} from '@objectstack/metadata-core';\nimport {\n type FsLayout,\n itemPath,\n parseItemPath,\n typeDir,\n logFile,\n} from './layout.js';\nimport { JsonlLog } from './jsonl-log.js';\nimport { KeyedMutex, createBroker, type EventBroker } from './sync.js';\nimport { createWatchIterable } from './watch-iterable.js';\n\nexport interface FileSystemRepositoryOptions {\n /** Absolute path to the metadata root directory. */\n root: string;\n /** Tenant/org. */\n org: string;\n /** Identity reported in events that originate from external FS edits. */\n fsActor?: string;\n /** Disable chokidar watcher (e.g. for read-only contexts). */\n disableWatch?: boolean;\n /** Optional clock injection for deterministic tests. */\n now?: () => Date;\n}\n\nconst matchRefFilter = (\n ref: MetaRef,\n filter: { org?: string; type?: MetadataType; name?: string },\n): boolean => {\n if (filter.org && filter.org !== ref.org) return false;\n if (filter.type && filter.type !== ref.type) return false;\n if (filter.name && filter.name !== ref.name) return false;\n return true;\n};\n\nconst matchEvent = (evt: MetadataEvent, filter: WatchFilter): boolean => matchRefFilter(evt.ref, filter);\n\n/**\n * Cadence of the content-keyed reconciliation sweep (#9339).\n *\n * Twice the watcher's own 1000ms poll interval: long enough that the watcher\n * normally delivers first and the sweep finds nothing to do, short enough that\n * a delivery the watcher lost is recovered in the same order of magnitude as a\n * poll rather than at the next process restart.\n *\n * It is deliberately NOT derived from `interval` at runtime. The two are\n * independent knobs — the poll interval sets detection latency for the fast\n * path, this sets the worst-case latency of the backstop — and coupling them\n * would make a future change to one silently retune the other.\n */\nconst RESYNC_INTERVAL_MS = 2_000;\n\n/**\n * The ONE errno that is a truthful \"there is nothing here\" for a directory\n * read, as opposed to \"the read could not run\" (#8895 — discriminate or\n * propagate). A path that does not exist holds no items, so answering with an\n * empty listing states a fact. Every other code — EACCES, EIO, ENOTDIR, and\n * above all EMFILE/ENFILE under fd exhaustion — means the answer was never\n * obtained, and inventing an empty one there is the defect itself.\n */\nconst isEnoent = (err: unknown): boolean =>\n (err as NodeJS.ErrnoException | null)?.code === 'ENOENT';\n\nexport class FileSystemRepository implements MetadataRepository {\n private readonly layout: FsLayout;\n private readonly org: string;\n private readonly fsActor: string;\n private readonly disableWatch: boolean;\n private readonly now: () => Date;\n private readonly log: JsonlLog;\n private readonly mutex = new KeyedMutex();\n private readonly broker: EventBroker = createBroker(matchEvent);\n\n /** In-memory index: refKey → current hash (HEAD). */\n private readonly heads = new Map<string, string>();\n /** Next seq counter, hydrated from the log on `start()`. */\n private nextSeq = 1;\n private watcher: FSWatcher | null = null;\n private started = false;\n /** Pending reconciliation sweep (#9339). Chained, never overlapping. */\n private resyncTimer: ReturnType<typeof setTimeout> | null = null;\n /** False before the watcher is armed and from `close()` onwards. */\n private resyncEnabled = false;\n /**\n * Sweep read faults already reported, keyed `CODE @ path`, so a standing\n * fault is announced once rather than every 2s (AGENTS.md: say it once, at\n * the first degradation). An entry is cleared when that path reads again.\n */\n private readonly resyncFaults = new Set<string>();\n /**\n * Bumped by every `close()`. `watch()` reads it before its deferred log\n * replay starts and hands the comparison to `createWatchIterable`, so a\n * subscription that registers AFTER the shutdown sweep terminates on\n * arrival instead of parking forever (#11127). A counter rather than a\n * boolean because `start()` may follow `close()`: a repository restart must\n * not poison the watchers opened after it.\n */\n private closeGeneration = 0;\n\n constructor(opts: FileSystemRepositoryOptions) {\n this.org = opts.org;\n this.fsActor = opts.fsActor ?? 'fs';\n this.disableWatch = opts.disableWatch ?? false;\n this.now = opts.now ?? (() => new Date());\n this.layout = { root: path.resolve(opts.root) };\n this.log = new JsonlLog(logFile(this.layout));\n }\n\n // ── Lifecycle ───────────────────────────────────────────────────────\n\n /**\n * Attach the repository. **Creates nothing on disk** (#7000).\n *\n * Attaching is not a write. `start()` used to `mkdir` both the root and\n * `<root>/.objectstack/.log` unconditionally, which meant every read-only\n * boot that merely attaches a repository left a skeleton behind — most\n * visibly `os migrate plan`, a declared dry run, on a project that has\n * never been started. That is the same property #6743 ruled on for\n * `.objectstack/data/`: a dry run leaves nothing behind, and the existence\n * of `.objectstack/` has to stay a usable \"this project has been started\"\n * signal.\n *\n * Every read path below already treats a missing root as an empty\n * repository (`scanHeads` swallows ENOENT, `JsonlLog` guards on\n * `existsSync`, `get` guards on `existsSync`), so the root is materialized\n * by `ensureRoot()` on the first write instead.\n */\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n // 1) Scan body files to build the head index. No-op on a missing root.\n await this.scanHeads();\n\n // 2) Hydrate nextSeq from the existing log. No-op on a missing log.\n const highest = await this.log.highestSeq();\n this.nextSeq = highest + 1;\n\n // 3) Start the watcher (unless disabled). chokidar cannot watch a path\n // that does not exist yet: measured on chokidar 5 with `usePolling`,\n // a root created AFTER `watch()` produces no events at all, ever. So\n // when the root is absent the watcher is armed later, by the\n // `ensureRoot()` call that brings the root into existence — otherwise\n // dropping the `mkdir` above would silently kill external-edit\n // detection for the whole life of the process.\n if (!this.disableWatch && existsSync(this.layout.root)) this.startWatcher();\n }\n\n /**\n * Bring the repository root into existence. Called by every write path\n * immediately before it touches the disk — `start()` deliberately does not\n * create it (#7000), so this is the single seam where the root appears.\n *\n * It is also where a watcher that `start()` could not arm (missing root)\n * gets armed, so \"external edits are detected\" survives the change.\n */\n private async ensureRoot(): Promise<void> {\n await fs.mkdir(this.layout.root, { recursive: true });\n if (this.started && !this.disableWatch && !this.watcher) this.startWatcher();\n }\n\n /**\n * Shut the repository down, ending every live `watch()` iterator.\n *\n * **Shutdown terminates; it does not emit** — invariant 8 in\n * `@objectstack/metadata-core`'s `repository.ts`, and the reason this method\n * reaches the broker at all. It used to retire the chokidar watcher and the\n * resync sweep and stop there. The broker has no teardown of its own\n * (`subscribe`/`unsubscribe` add to and delete from a plain `Set`), and each\n * iterator parks its pending `next()` on a `waiter` that only a broker\n * `push` or the iterator's own terminator can settle. After `close()` the\n * chokidar source was gone, so no `push` could arrive; the subscriber was\n * still registered, and nothing ran its terminator. A consumer holding a\n * `for await` at shutdown — `MetadataManager.startRepositoryWatch()` is\n * exactly that shape — therefore never saw its loop end, for EVERY\n * subscription shape including `watch({})`.\n *\n * Termination is expressed as termination: each subscription's\n * `terminate()`, which is the same routine the consumer's own\n * `iterator.return()` runs, so no consumer has to tell \"the repository shut\n * down under me\" apart from \"I broke my own loop\". A synthetic drain event\n * would be the wrong shape and was measured to be so (#11021): the\n * subscriptions most in need of draining are exactly the ones whose filter\n * or numeric `since` drops it, and delivering an event has never ended an\n * iterator.\n */\n async close(): Promise<void> {\n // Retire the sweep BEFORE awaiting the watcher, so a sweep that lands\n // during `watcher.close()` cannot reschedule itself behind our back.\n this.stopResync();\n // Terminate BEFORE the await for the same reason: a `watcher.close()` that\n // rejects must not leave a consumer's `for await` parked forever, and a\n // straggler event from the dying watcher has no one left to reach. Events\n // still queued or unreplayed at this moment MAY be dropped (invariant 8),\n // on this path and on `return()` alike.\n this.closeGeneration++;\n this.broker.terminateAll();\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n this.started = false;\n }\n\n // ── Read API ────────────────────────────────────────────────────────\n\n async get(ref: MetaRef): Promise<MetadataItem | null> {\n this.assertScope(ref);\n const file = itemPath(this.layout, ref.type, ref.name);\n if (!existsSync(file)) return null;\n const body = await readJson(file);\n if (!body) return null;\n const hash = hashSpec(body);\n if (ref.version && ref.version !== hash) return null;\n // Walk back through the log to populate parent/authoredBy/seq.\n const meta = await this.findMetaForHash(ref, hash);\n return {\n ref: { ...ref, version: undefined },\n body: body as Record<string, unknown>,\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? new Date(0).toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n };\n }\n\n async getByHash(ref: MetaRef, hash: string): Promise<MetadataItem | null> {\n // FS repo stores only HEAD bodies on disk; the JSONL log records\n // events (hashes) but not historical bodies. Resolve only if the\n // requested hash matches HEAD.\n const head = await this.get(ref);\n if (!head || head.hash !== hash) return null;\n return head;\n }\n\n async *list(filter: ListFilter): AsyncIterable<MetadataItemHeader> {\n const limit = filter.limit ?? Infinity;\n let yielded = 0;\n for (const [key, hash] of this.heads) {\n const ref = parseRefKey(key);\n if (!ref) continue;\n if (!matchRefFilter(ref, filter)) continue;\n if (filter.nameContains && !ref.name.includes(filter.nameContains)) continue;\n const meta = await this.findMetaForHash(ref, hash);\n const header: MetadataItemHeader = {\n ref: { ...ref, version: undefined },\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? new Date(0).toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n };\n yield header;\n if (++yielded >= limit) return;\n }\n }\n\n async *history(ref: MetaRef, opts: HistoryOptions = {}): AsyncIterable<MetadataEvent> {\n this.assertScope(ref);\n const since = opts.sinceSeq ?? -1;\n const limit = opts.limit ?? Infinity;\n let yielded = 0;\n for await (const evt of this.log.readAll()) {\n if (evt.seq <= since) continue;\n if (evt.ref.type !== ref.type || evt.ref.name !== ref.name) continue;\n if (evt.ref.org !== ref.org) continue;\n yield evt;\n if (++yielded >= limit) return;\n }\n }\n\n watch(filter: WatchFilter, since?: number): AsyncIterable<MetadataEvent> {\n // Eagerly snapshot the existing log for replay; new events route via broker.\n const replay: MetadataEvent[] = [];\n const promise = (async () => {\n for await (const evt of this.log.readAll()) {\n if (matchEvent(evt, filter)) replay.push(evt);\n }\n })();\n // Read BEFORE the read above can complete: the subscriber below is\n // registered only when it does, which is a window `close()`'s sweep cannot\n // see (#11127). Compared on arrival, a shutdown inside that window ends\n // this iterator instead of parking it.\n const generation = this.closeGeneration;\n // We must await replay before returning, but the public API is\n // sync-returning AsyncIterable. Wrap in a deferred iterable.\n return deferredIterable(promise.then(() =>\n createWatchIterable({\n filter,\n since,\n replay,\n broker: this.broker,\n matches: matchEvent,\n branchKeyOf: (e) => e.ref.org,\n arrivesClosed: () => this.closeGeneration !== generation,\n }),\n ));\n }\n\n // ── Write API ───────────────────────────────────────────────────────\n\n put(ref: MetaRef, spec: unknown, opts: PutOptions): Promise<PutResult> {\n this.assertScope(ref);\n return this.mutex.run(refKey(ref), async () => {\n const key = refKey(ref);\n const currentHead = this.heads.get(key) ?? null;\n if ((opts.parentVersion ?? null) !== currentHead) {\n throw new ConflictError(ref, opts.parentVersion ?? null, currentHead);\n }\n const hash = hashSpec(spec);\n if (currentHead === hash) {\n // No-op write — same content.\n const meta = await this.findMetaForHash(ref, hash);\n return {\n version: hash,\n seq: meta?.seq ?? 0,\n item: {\n ref: { ...ref, version: undefined },\n body: spec as Record<string, unknown>,\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? this.now().toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n },\n };\n }\n\n const seq = this.nextSeq++;\n const ts = this.now().toISOString();\n const file = itemPath(this.layout, ref.type, ref.name);\n // First write of the process materializes the root (#7000).\n await this.ensureRoot();\n await fs.mkdir(typeDir(this.layout, ref.type), { recursive: true });\n await writeJsonAtomic(file, spec);\n // The watcher must not depend on its own directory scan to notice a\n // path we created ourselves (#7282). See `trackWrittenPath`.\n this.trackWrittenPath(file);\n // Publishing the new head here is what suppresses the watcher event this\n // write is about to produce — see `handleFsChange` (#7335). It runs in\n // the same continuation as the `rename` above, and `awaitWriteFinish`\n // holds any event for a further `stabilityThreshold`, so the index is\n // always current by the time an event for this path can be delivered.\n this.heads.set(key, hash);\n\n const evt: MetadataEvent = {\n seq,\n op: currentHead ? 'update' : 'create',\n ref: { ...ref, version: undefined },\n hash,\n parentHash: currentHead,\n actor: opts.actor,\n message: opts.message,\n ts,\n source: opts.source ?? 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n\n return {\n version: hash,\n seq,\n item: {\n ref: { ...ref, version: undefined },\n body: spec as Record<string, unknown>,\n hash,\n parentHash: currentHead,\n authoredBy: opts.actor,\n authoredAt: ts,\n message: opts.message,\n seq,\n },\n };\n });\n }\n\n delete(ref: MetaRef, opts: DeleteOptions): Promise<DeleteResult> {\n this.assertScope(ref);\n return this.mutex.run(refKey(ref), async () => {\n const key = refKey(ref);\n const currentHead = this.heads.get(key) ?? null;\n if (currentHead !== opts.parentVersion) {\n throw new ConflictError(ref, opts.parentVersion, currentHead);\n }\n const file = itemPath(this.layout, ref.type, ref.name);\n // A delete appends a tombstone to the change log, so it is a write too.\n await this.ensureRoot();\n // Retire the head BEFORE touching the disk, not after (#7335).\n //\n // `awaitWriteFinish` only debounces `add`/`change`; chokidar emits\n // `unlink` with no stability delay at all, so — unlike `put()` — this\n // face has no cushion between the disk mutation and the event it\n // produces. Clearing the index first makes `handleFsChange`'s\n // `if (!currentHead) return` a total suppression for our own removal\n // rather than a race against the poll callback.\n this.heads.delete(key);\n try {\n if (existsSync(file)) await fs.unlink(file);\n } catch (err) {\n // The disk still holds the item, so the index must too — otherwise a\n // failed delete would leave the repository claiming a file it can\n // still read. Restores exactly the pre-call state before rethrowing.\n if (currentHead !== null) this.heads.set(key, currentHead);\n throw err;\n }\n const seq = this.nextSeq++;\n const ts = this.now().toISOString();\n const evt: MetadataEvent = {\n seq,\n op: 'delete',\n ref: { ...ref, version: undefined },\n hash: null,\n parentHash: currentHead,\n actor: opts.actor,\n message: opts.message,\n ts,\n source: opts.source ?? 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n return { seq };\n });\n }\n\n // ── Internals ───────────────────────────────────────────────────────\n\n private assertScope(ref: MetaRef): void {\n if (ref.org !== this.org) {\n throw new Error(\n `FileSystemRepository scope mismatch: expected org=${this.org}, got org=${ref.org}`,\n );\n }\n }\n\n private async scanHeads(): Promise<void> {\n this.heads.clear();\n // Walk one level deep: <root>/<type>/<name>.json\n let entries: import('node:fs').Dirent[] = [];\n try {\n entries = await fs.readdir(this.layout.root, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n const type = entry.name;\n const dir = path.join(this.layout.root, type);\n let files: string[] = [];\n try {\n files = await fs.readdir(dir);\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const name = file.slice(0, -'.json'.length);\n const ref: MetaRef = {\n org: this.org,\n type: type as MetadataType,\n name,\n };\n const body = await readJson(path.join(dir, file));\n if (!body) continue;\n this.heads.set(refKey(ref), hashSpec(body));\n }\n }\n }\n\n private async findMetaForHash(\n ref: MetaRef,\n hash: string,\n ): Promise<MetadataEvent | null> {\n let last: MetadataEvent | null = null;\n for await (const evt of this.log.readAll()) {\n if (evt.ref.type !== ref.type || evt.ref.name !== ref.name) continue;\n if (evt.ref.org !== ref.org) continue;\n if (evt.hash === hash) last = evt;\n }\n return last;\n }\n\n /**\n * Register a path this repository just wrote with the watcher (#7282).\n *\n * chokidar's initial scan is asynchronous, and every write path here can be\n * running **while it is still walking the tree** — `start()` arms the watcher\n * and the caller may `put()` on the next tick, and `ensureRoot()` arms it in\n * the middle of the very first write. With `usePolling` that combination has\n * a permanently-blinding interleaving, measured on chokidar 5 with this\n * repository's own options:\n *\n * 1. chokidar reads `<root>/<type>/` and finds it EMPTY — the atomic\n * `rename` in `writeJsonAtomic` has not landed yet.\n * 2. the rename lands; the directory's mtime changes.\n * 3. chokidar calls `watchFile()` on that directory, and libuv takes its\n * polling baseline stat — which already reflects step 2.\n *\n * From then on the directory's stat never changes again, so no poll ever\n * fires for it, `_handleRead` never re-runs, the item file is never added to\n * the watched set, and no per-file watcher is ever created. chokidar emits\n * neither `add` nor `change` for that path **for the life of the process** —\n * `getWatched()` reports the type directory as `[]` forever while the file\n * sits in it. That is the whole of #7282: the four merge-queue ejections all\n * waited out their deadlines (20s, then 25541ms against 25s) on an event that\n * was never going to be delivered, which is why widening the deadline and\n * widening the pre-edit sleep both changed nothing, and why lowering\n * `interval` would change nothing either — a shorter poll re-compares against\n * the same unchanged directory stat.\n *\n * The window is exactly \"files that exist at baseline time but were absent\n * from the snapshot read a moment earlier\", and the only writer that can be\n * inside it is us. So we close it at the source: tell the watcher explicitly\n * about every path we create, instead of hoping its scan happened to see it.\n *\n * `add()` is idempotent here — `_handleFile` returns early when the parent\n * directory already tracks the basename — and it emits nothing, because\n * chokidar treats an explicit `add()` as an initial add and `ignoreInitial`\n * is set. Its effect is the one we need: `_watchWithNodeFs` registers the\n * basename with the parent directory (without which chokidar drops `change`\n * events for the file) and starts the per-file poll.\n */\n private trackWrittenPath(file: string): void {\n const w = this.watcher;\n // `add()` clears `closed`, so never hand a closing watcher a new path.\n if (!w || w.closed) return;\n w.add(file);\n }\n\n private startWatcher(): void {\n const root = this.layout.root;\n const w = chokidar.watch(root, {\n // Skip dotfiles under the root — including the repository's own\n // `.objectstack/` bookkeeping subtree — matched on the path RELATIVE\n // to the watch root (#7150). See `isIgnoredWatchPath`.\n ignored: (p: string) => isIgnoredWatchPath(root, p),\n ignoreInitial: true,\n depth: 2,\n awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 20 },\n // Use polling to avoid `fs.watch` EMFILE on macOS / busy dev hosts.\n // The depth-2 recursion would otherwise wire native watches across\n // the entire customization tree.\n usePolling: true,\n interval: 1000,\n binaryInterval: 2000,\n // Declared explicitly, not inherited. chokidar's own default-correction\n // (`if (opts.atomic === undefined) opts.atomic = !opts.usePolling`) can\n // only fire when the caller omits `atomic`, but its defaults literal\n // already assigns `atomic: true` *before* the caller's options are\n // spread in — so leaving `atomic` unset here does not mean \"off under\n // polling\" the way the correction's own comment claims, it silently\n // resolves to `true` regardless of `usePolling`. That has been this\n // repository's actual runtime behaviour all along (verified by reading\n // back the resolved option from a real watcher instance, #12696): every\n // `unlink` gets chokidar's 100ms editor-atomic-write deferral, and\n // `DOT_RE` (vim swap files, `~`, sublime tmp) is folded into\n // `_isIgnored` on top of this repository's own `isIgnoredWatchPath`\n // (#7150). `atomic: true` here keeps that behaviour byte-for-byte —\n // this is a declaration, not a change. Flipping it to `false` would\n // remove both behaviours from a live delivery path and needs its own\n // reverse verification; see #12696 for the analysis.\n atomic: true,\n });\n w.on('add', (p) => void this.handleFsChange(p, 'add'));\n w.on('change', (p) => void this.handleFsChange(p, 'change'));\n w.on('unlink', (p) => void this.handleFsChange(p, 'unlink'));\n this.watcher = w;\n // The watcher is the fast path, not the guarantee (#9339). See `resync`.\n this.startResync();\n }\n\n /**\n * Publish the `delete` face of an externally-observed removal.\n *\n * Extracted from `handleFsChange` unchanged so the reconciliation sweep\n * (#9339) can reuse it **verbatim** rather than growing a second copy of the\n * event shape. The one-line invariant: the caller already holds the per-key\n * mutex, and `!currentHead` is the content-keyed suppression that makes our\n * own `delete()` a no-op here.\n */\n private async publishExternalDelete(ref: MetaRef, key: string): Promise<void> {\n const currentHead = this.heads.get(key) ?? null;\n if (!currentHead) return;\n this.heads.delete(key);\n const seq = this.nextSeq++;\n const evt: MetadataEvent = {\n seq,\n op: 'delete',\n ref: { ...ref, version: undefined },\n hash: null,\n parentHash: currentHead,\n actor: this.fsActor,\n ts: this.now().toISOString(),\n source: 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n }\n\n private startResync(): void {\n this.resyncEnabled = true;\n this.scheduleResync();\n }\n\n private stopResync(): void {\n this.resyncEnabled = false;\n if (this.resyncTimer) {\n clearTimeout(this.resyncTimer);\n this.resyncTimer = null;\n }\n }\n\n /**\n * Schedule the next sweep — chained, never `setInterval` (#9339).\n *\n * A chained timeout cannot stack: the next sweep is armed only once the\n * previous one has finished, so a saturated runner degrades to *fewer*\n * sweeps instead of a growing backlog of overlapping tree walks. The timer\n * is `unref`ed because a backstop must never be the reason a process stays\n * alive.\n */\n private scheduleResync(): void {\n if (!this.resyncEnabled || this.resyncTimer) return;\n const timer = setTimeout(() => {\n this.resyncTimer = null;\n void this.resync().finally(() => this.scheduleResync());\n }, RESYNC_INTERVAL_MS);\n timer.unref?.();\n this.resyncTimer = timer;\n }\n\n /**\n * Announce a sweep read that could not run — the non-silence half of #8895's\n * \"discriminate or propagate\".\n *\n * ## Why `error` and not `warn`\n *\n * AGENTS.md decides the level with one question: *after the degradation, does\n * the system still look \"normal\" from the outside while something it claims\n * is persisted has not actually landed?* Here it does. Nothing throws, the\n * watcher stays armed, `getWatched()` stays populated, `start()` succeeded —\n * and the repository's index quietly stops tracking what is on disk. That is\n * the rule's second limb verbatim (\"persisted state and runtime state\n * disagree\"), not the functional-degradation limb: no capability is visibly\n * smaller, so nobody finds out by using the missing thing.\n *\n * The counter-argument — *this is only a backstop, the watcher is still the\n * fast path* — is why the level is arguable, and it does not survive the\n * failing errno. The sharp case is fd exhaustion: EMFILE/ENFILE break this\n * `readdir` and chokidar's `fs.watchFile` polling **at the same time and for\n * the same reason**, so the fast path is not an independent fallback under\n * precisely the load that produces this fault. A backstop that is silently\n * absent whenever it is most needed is a durability-shaped degradation.\n *\n * ⚠️ AGENTS.md also warns against over-applying `error`, and the discipline\n * that answers it is the ledger, not a quieter level: an `error` owes the\n * consequence and the fix, said **once** at the first degradation rather than\n * once per failed read. A sweep runs every 2s forever, so an unlatched\n * `console.error` here would be the mirror-image failure the same rule names.\n *\n * ⛔ It deliberately does NOT throw. This runs on a background timer; taking\n * a process down on a transient EACCES would be worse than the bug. The bar\n * met here is non-silence, not propagation.\n *\n * The channel is `console.error` because this class has no logger: nothing is\n * injected through `FileSystemRepositoryOptions`, and widening that public\n * surface to carry one is out of scope for this fix.\n */\n private reportResyncFault(target: string, err: unknown): void {\n const code = (err as NodeJS.ErrnoException | null)?.code ?? 'UNKNOWN';\n const key = `${code} @ ${target}`;\n if (this.resyncFaults.has(key)) return;\n this.resyncFaults.add(key);\n console.error(\n `[FileSystemRepository] metadata reconciliation sweep could not read ${target} (${code}). ` +\n `CONSEQUENCE: external edits under this path are no longer reconciled, so this ` +\n `repository's index and its watch() subscribers can drift from what is on disk while ` +\n `everything keeps reporting healthy. The chokidar watcher is not an independent ` +\n `fallback here — fd exhaustion degrades both. ` +\n `FIX: restore read access to the path; the sweep recovers by itself on the first ` +\n `successful read. Reported once per path and error code.`,\n );\n }\n\n /** Re-arm reporting for a path that reads again, so a recurrence is heard. */\n private clearResyncFault(target: string): void {\n if (this.resyncFaults.size === 0) return;\n const suffix = ` @ ${target}`;\n for (const key of this.resyncFaults) {\n if (key.endsWith(suffix)) this.resyncFaults.delete(key);\n }\n }\n\n /**\n * Content-keyed reconciliation sweep — the backstop that makes external-edit\n * detection a guarantee rather than a single chance (#9339, #7282).\n *\n * ## Why the watcher alone cannot be the guarantee\n *\n * An external write to `<root>/<type>/<name>.json` reaches a subscriber only\n * if chokidar notices it, and under `usePolling` it gets **exactly one**\n * opportunity to do so: the write advances the type directory's mtime once,\n * and chokidar re-reads a directory only when its stat *strictly advances*,\n * so every later poll compares an unchanged stat and can never rediscover\n * the file. Measured on #9339 with a fault-injection harness: with the one\n * read suppressed, fifteen further poll ticks never find the new file, and a\n * 20s deadline and a 200s deadline buy the same single attempt. That is the\n * structural reason behind #7282's empirical finding that the event is\n * \"never delivered, not slow\", and why widening the deadline (#7208) and\n * lowering `interval` were both spent before they were tried.\n *\n * At least six independent one-shot gates sit on that single attempt,\n * spanning three layers — the kernel timestamp (the directory mtime does not\n * strictly advance), chokidar's readdir throttle and readdir snapshot, and\n * chokidar's emit gates (`_throttle('add')`, a stale `_pendingWrites` entry,\n * the `awaitWriteFinish` ENOENT early return). Each one produces a\n * byte-identical observable: no event, ever, for that path.\n *\n * ## Why this shape, and not a narrower one\n *\n * ⚠️ The six are indistinguishable at the point of failure, so **any fix\n * that has to name which gate fired is a fix for one member of a family** —\n * which is exactly how #7282 was closed and exactly why it reopened. This\n * sweep never asks. It compares what is on disk against `heads`, the index\n * that already defines what this repository believes it holds, and publishes\n * the divergence through the same `handleFsChange` the watcher feeds. It is\n * therefore robust across all six *by construction*, and equally across a\n * seventh nobody has found: the only property it relies on is that the bytes\n * on disk stopped matching the index.\n *\n * `put()` is unaffected and keeps its direct registration (`trackWrittenPath`\n * calls `watcher.add` and bypasses the whole chain, which is why the `put()`\n * half of this family was already closed by #7336 and the external-write half\n * was not).\n *\n * ## Cost, and why it is bounded\n *\n * One pass over `<root>/<type>/*.json` per sweep — the same walk `start()`\n * already performs once — with no retry loop inside it and no work at all\n * when nothing diverged. Sweeps are chained, so they cannot overlap; the\n * timer is `unref`ed and dies with `close()`; and it is armed only alongside\n * the watcher, so a `disableWatch` repository pays nothing.\n *\n * Discovery is by content, never by stat: a stat pre-filter would reintroduce\n * a time key of exactly the kind this replaces.\n */\n private async resync(): Promise<void> {\n const root = this.layout.root;\n let entries: import('node:fs').Dirent[] = [];\n try {\n entries = await fs.readdir(root, { withFileTypes: true });\n this.clearResyncFault(root);\n } catch (err) {\n // ENOENT is truthful: a root that does not exist holds nothing to\n // reconcile, and the next sweep sees whatever replaces it. Any other\n // errno means the read could not RUN, and staying silent about that\n // would make this backstop absent for the life of the process exactly\n // when the load-dependent loss it exists to catch is most likely —\n // EMFILE/ENFILE degrade this read and chokidar's own polling together.\n if (!isEnoent(err)) this.reportResyncFault(root, err);\n return;\n }\n const onDisk = new Set<string>();\n /**\n * Type directories whose listing could not be obtained. Their keys are\n * missing from `onDisk` for a reason that is NOT \"the files are gone\", so\n * the delete pass below must not read that absence as a removal.\n */\n const unreadableTypes = new Set<string>();\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n // Same dot-entry rule as `scanHeads` and `isIgnoredWatchPath`, so the\n // boot scan, the watcher and this sweep agree on what the repository\n // contains (#7150).\n if (entry.name.startsWith('.')) continue;\n const dir = path.join(root, entry.name);\n let files: string[] = [];\n try {\n files = await fs.readdir(dir);\n this.clearResyncFault(dir);\n } catch (err) {\n // The same discrimination at type granularity. An unreadable type\n // directory silently stops reconciling EVERY item of that type, which\n // is exactly the invented-emptiness shape #8895 rules on.\n if (!isEnoent(err)) {\n this.reportResyncFault(dir, err);\n unreadableTypes.add(entry.name);\n }\n continue;\n }\n for (const file of files) {\n if (!file.endsWith('.json') || file.startsWith('.')) continue;\n const abs = path.join(dir, file);\n const parsed = parseItemPath(this.layout, abs);\n if (!parsed) continue;\n const ref: MetaRef = {\n org: this.org,\n type: parsed.type as MetadataType,\n name: parsed.name,\n };\n const key = refKey(ref);\n onDisk.add(key);\n const before = this.heads.get(key);\n await this.handleFsChange(abs, 'add');\n if (this.heads.get(key) !== before) {\n // We just published a change the watcher never delivered, so the\n // watcher may not know this path at all (the loss can be upstream of\n // chokidar's `_handleFile`). Re-arm it through the same seam `put()`\n // uses, so the fast path is restored instead of leaving every future\n // edit to this file dependent on the sweep.\n this.trackWrittenPath(abs);\n }\n }\n }\n for (const key of [...this.heads.keys()]) {\n if (onDisk.has(key)) continue;\n const ref = parseRefKey(key);\n if (!ref) continue;\n // Absent from `onDisk` because we could not look, not because it is gone.\n if (unreadableTypes.has(ref.type)) continue;\n const file = itemPath(this.layout, ref.type, ref.name);\n await this.mutex.run(key, async () => {\n // Re-checked UNDER the lock. The enumeration above ran outside it, so\n // a `put()` that created this file in between would otherwise be\n // reported as an external delete.\n if (existsSync(file)) return;\n await this.publishExternalDelete(ref, key);\n });\n }\n }\n\n /**\n * Translate a watcher event into a `MetadataEvent`, or drop it.\n *\n * ## Self-writes are suppressed by content identity, never by a clock (#7335)\n *\n * This used to open with `if (this.selfWrites.has(absPath)) return;` — a\n * `Set` that `put()`/`delete()` added the path to and a `setTimeout(…, 200)`\n * cleared. That check discarded **every** event for a recently-written path\n * without ever looking at what the watcher had actually observed, which is\n * the whole defect: with `usePolling`, chokidar compares state once per\n * `interval`, so our write and an external edit landing between two ticks\n * are delivered as **one** event carrying the *external* content. Dropping\n * it on a wall clock destroyed the only notification that edit would ever\n * produce.\n *\n * Measured on `origin/main` @ `69fde55`, 40 iterations, poll phase\n * randomised so the delivery lag samples `[0, interval)` uniformly:\n *\n * delivery lag < 200ms → 7 runs → external edit SWALLOWED, every time\n * delivery lag > 200ms → 33 runs → external edit delivered, every time\n *\n * A perfect split on the wall-clock boundary, and the reason earlier\n * instrumentation saw 0/360: a *fixed* pre-edit sleep phase-locks the poll,\n * pinning the lag (measured: 519–585ms across 25 runs) safely outside the\n * window. Nothing about the window was rare — it was unsampled.\n *\n * What remains is the check that was already doing the real work one step\n * down, and it needs no timer because it compares the content the watcher\n * **read** against the index:\n *\n * - `add`/`change` — `currentHead === hash` drops the event when the bytes\n * on disk are the bytes we last published. `put()` sets that head in the\n * same continuation as its `rename`, and `awaitWriteFinish` holds the\n * event for a further `stabilityThreshold`, so it is never late.\n * - `unlink` — `!currentHead` drops the event when the index already\n * agrees the item is gone. `delete()` retires the head *before* it\n * unlinks, precisely because this face gets no `awaitWriteFinish` delay.\n * This is the whole of the *self-write* answer on this face, and it is\n * not the whole of the face — see the section below it.\n *\n * Both faces are pinned together in `test/self-write-suppression.test.ts`.\n *\n * ## A removal is confirmed against the disk before it is published (#7369)\n *\n * Those two checks answer \"is this event OURS\". Neither answers \"did this\n * happen at all\", and the `unlink` face needs that second question asked\n * because its input is a third party's inference: chokidar decides a file is\n * gone from a *stat that failed*, not only from a file that went away, and\n * `!currentHead` cannot tell the two apart because a spurious unlink leaves\n * the index exactly as valid as it was.\n *\n * The cost of getting it wrong is not a dropped notification, which the\n * sweep would repair. A `delete` is appended to the change log and broadcast\n * to every subscriber, and `MetadataManager` drops the item from the\n * registry and the `list()` cache on receipt. The sweep then finds the file\n * still on disk and republishes it as a `create` — so a failed stat becomes\n * a durable, permanently recorded delete/create pair for an item that never\n * changed, and every consumer sees the item disappear in between. That is\n * the shape ADR-0008's log is least able to walk back.\n *\n * So `existsSync` under the same per-key lock the sweep uses, and the same\n * decision it makes: absent ⇒ publish the removal; present ⇒ this was a\n * change, answered by the content path below. Genuine removals pay nothing —\n * `delete()` is still suppressed by `!currentHead`, and an external `rm` is\n * still published on the first delivery, because for those the file really\n * is gone. Pinned in `test/external-delete-requires-absence.test.ts`.\n *\n * Note the deliberate limit: identity is judged on what round-trips through\n * the file, so a spec whose in-memory form does not (a `Date`, which\n * canonicalises to `{}` in memory but to an ISO string once written and\n * re-read) is republished as an external `update`. That predates this change\n * and is independent of it — such a spec already fails `put().version ===\n * get().hash`, and the 200ms window never covered it either, expiring some\n * 360ms before the event it would have had to catch.\n */\n private async handleFsChange(absPath: string, kind: 'add' | 'change' | 'unlink'): Promise<void> {\n const parsed = parseItemPath(this.layout, absPath);\n if (!parsed) return;\n const ref: MetaRef = {\n org: this.org,\n type: parsed.type as MetadataType,\n name: parsed.name,\n };\n const key = refKey(ref);\n await this.mutex.run(key, async () => {\n // A watcher `unlink` is a CLAIM of absence, not absence — so it is\n // confirmed against the disk before a `delete` is published (#7369).\n // `!currentHead` inside `publishExternalDelete` cannot do this job: it\n // compares against the INDEX, which is exactly what a spurious unlink\n // leaves intact. The reconciliation sweep already re-checks disk truth\n // under this same lock before retiring a key, for a reason it states in\n // place; the watcher face was the one path that published a removal on\n // the observer's word alone.\n //\n // chokidar reaches its removal path from failed *stats* as well as from\n // real removals, and says so at both sites (chokidar 5 `handler.js`):\n // `_handleFile`'s poll listener re-stats a file whose watched stat came\n // back zeroed and calls `_remove` from the catch — under the comment\n // \"Fix issues where mtime is null but file is still present\" — with no\n // discrimination on errno, so EMFILE/ENFILE retires a file that is\n // there; and `_handleRead`'s snapshot diff `_remove`s every previously\n // tracked entry its readdirp pass did not enumerate, which includes the\n // entries whose per-entry `lstat` failed rather than only the ones that\n // are gone. Both faults are load-shaped, which is why the merge queue —\n // the only context that runs the FULL suite — is where this surfaced,\n // twice, on a case that touches nothing else.\n //\n // Falling through is the repair, not just skipping: when the path is\n // still there the honest reading of the event is \"something happened to\n // this file\", which is the content path's question. It answers with the\n // same `currentHead === hash` comparison used everywhere else, so a\n // spurious unlink that accompanied a real in-place edit still surfaces\n // as the `update` it always was, in the same tick, rather than as the\n // `delete` + `create` pair the index-only check produced.\n if (kind === 'unlink' && !existsSync(absPath)) {\n await this.publishExternalDelete(ref, key);\n return;\n }\n const body = await readJson(absPath);\n if (!body) return;\n const hash = hashSpec(body);\n const currentHead = this.heads.get(key) ?? null;\n if (currentHead === hash) return; // No content change.\n this.heads.set(key, hash);\n const seq = this.nextSeq++;\n const evt: MetadataEvent = {\n seq,\n op: currentHead ? 'update' : 'create',\n ref: { ...ref, version: undefined },\n hash,\n parentHash: currentHead,\n actor: this.fsActor,\n ts: this.now().toISOString(),\n source: 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n });\n }\n}\n\n// ── Utilities ─────────────────────────────────────────────────────────\n\n/**\n * Watcher ignore matcher — \"everything under the root, except the\n * repository's own bookkeeping\" (#7150).\n *\n * chokidar hands its matcher **absolute** paths, and applies it to the\n * watched root itself as well as to entries discovered underneath it. The\n * previous matcher was a bare dotfile regex (`/(^|[\\\\/])\\../`), which\n * therefore matched the `.objectstack` segment of the root path the plugin\n * actually uses (`<project>/.objectstack/metadata`, `REPO_SUBDIR` in\n * `packages/metadata/src/plugin.ts`) and ignored the whole watch. Measured on\n * chokidar 5 with this repository's own options, two identical trees\n * differing only in whether the root sits under a dot-directory:\n *\n * plain root getWatched: ['<root>', 'view'] events: add+change\n * dot-rooted getWatched: [] events: none\n *\n * So the intent is kept and only the *frame of reference* is fixed: judge the\n * path relative to the root, so dot segments belonging to the root itself are\n * never considered.\n *\n * Why not drop the matcher entirely and lean on `parseItemPath`, which already\n * rejects `.objectstack`? Measured: `parseItemPath` rejects that ONE name, so\n * a dot-directory at the type level leaks — `<root>/.cache/x.json` parses as\n * type `.cache`, and `<root>/view/.scratch.json` as an item named `.scratch`.\n * Both would be published as `MetadataEvent`s while `scanHeads` skips every\n * dot entry on boot, leaving the boot scan and the watcher disagreeing about\n * what the repository contains. Dropping it also puts `.objectstack/.log/` in\n * the poll set, so every one of the repository's own log appends wakes\n * `handleFsChange` only to be discarded.\n */\nfunction isIgnoredWatchPath(root: string, absPath: string): boolean {\n const rel = path.relative(root, absPath);\n // The watched root itself, and anything outside it, are not ours to judge.\n if (rel === '' || rel.startsWith('..')) return false;\n return rel.split(/[\\\\/]/).some((segment) => segment.startsWith('.'));\n}\n\nasync function readJson(file: string): Promise<unknown | null> {\n try {\n const text = await fs.readFile(file, 'utf8');\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nasync function writeJsonAtomic(file: string, body: unknown): Promise<void> {\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(body, null, 2) + '\\n', 'utf8');\n await fs.rename(tmp, file);\n}\n\nfunction parseRefKey(key: string): MetaRef | null {\n const parts = key.split('/');\n if (parts.length !== 3) return null;\n return {\n org: parts[0]!,\n type: parts[1]! as MetadataType,\n name: parts[2]!,\n };\n}\n\n/**\n * Wrap a Promise<AsyncIterable<T>> as a sync-returning AsyncIterable<T>.\n * The first `.next()` awaits the promise.\n */\nfunction deferredIterable<T>(promise: Promise<AsyncIterable<T>>): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator]() {\n let inner: AsyncIterator<T> | null = null;\n return {\n async next() {\n if (!inner) {\n const iterable = await promise;\n inner = iterable[Symbol.asyncIterator]();\n }\n return inner.next();\n },\n async return(value?: unknown) {\n if (!inner) {\n const iterable = await promise;\n inner = iterable[Symbol.asyncIterator]();\n }\n if (inner.return) return inner.return(value);\n return { value: undefined, done: true };\n },\n } as AsyncIterator<T>;\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Disk layout helpers — see ADR-0008 §10 PR-4 / packages/metadata-fs README.\n *\n * <root>/<type>/<name>.json — canonical body\n * <root>/.objectstack/.log/main.jsonl — append-only change log\n */\n\nimport path from 'node:path';\nimport type { MetadataType } from '@objectstack/metadata-core';\n\nexport interface FsLayout {\n /** Absolute path to the metadata root. */\n root: string;\n}\n\nexport function itemPath(layout: FsLayout, type: MetadataType, name: string): string {\n return path.join(layout.root, type, `${name}.json`);\n}\n\nexport function typeDir(layout: FsLayout, type: MetadataType): string {\n return path.join(layout.root, type);\n}\n\nexport function logDir(layout: FsLayout): string {\n return path.join(layout.root, '.objectstack', '.log');\n}\n\nexport function logFile(layout: FsLayout): string {\n // Single change log per filesystem root (branching is a Git concern,\n // not a metadata-layer concern).\n return path.join(logDir(layout), `main.jsonl`);\n}\n\n/** Parse a path like \".../view/case_grid.json\" into {type, name}. */\nexport function parseItemPath(\n layout: FsLayout,\n absPath: string,\n): { type: string; name: string } | null {\n const rel = path.relative(layout.root, absPath);\n if (rel.startsWith('..') || rel.startsWith('.objectstack')) return null;\n const segments = rel.split(path.sep);\n if (segments.length !== 2) return null;\n const type = segments[0]!;\n const file = segments[1]!;\n if (!file.endsWith('.json')) return null;\n const name = file.slice(0, -'.json'.length);\n return { type, name };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Append-only JSONL change log writer / reader. Each line is a single\n * `MetadataEvent` serialized via `JSON.stringify`.\n *\n * Durability strategy\n * ───────────────────\n * - Append with `O_APPEND` semantics (Node's `fs.appendFile` is\n * atomic for sub-PIPE_BUF-sized writes; events are well under 4 KiB).\n * - Read by streaming the file line-by-line and JSON.parse-ing each.\n * - On a corrupt line we skip and continue — the body files are the\n * source of truth; the log is a denormalised history index.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { createReadStream, existsSync } from 'node:fs';\nimport type { MetadataEvent } from '@objectstack/metadata-core';\n\nexport class JsonlLog {\n constructor(private readonly file: string) {}\n\n async append(evt: MetadataEvent): Promise<void> {\n await fs.mkdir(path.dirname(this.file), { recursive: true });\n await fs.appendFile(this.file, JSON.stringify(evt) + '\\n', 'utf8');\n }\n\n /** Read all events in seq order (i.e. file order). */\n async *readAll(): AsyncIterable<MetadataEvent> {\n if (!existsSync(this.file)) return;\n const rl = readline.createInterface({\n input: createReadStream(this.file, { encoding: 'utf8' }),\n crlfDelay: Infinity,\n });\n try {\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n yield JSON.parse(line) as MetadataEvent;\n } catch {\n // Skip corrupt line.\n }\n }\n } finally {\n rl.close();\n }\n }\n\n /** Return the highest seq number in the log, or 0 if empty. */\n async highestSeq(): Promise<number> {\n let max = 0;\n for await (const evt of this.readAll()) {\n if (typeof evt.seq === 'number' && evt.seq > max) max = evt.seq;\n }\n return max;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Mutex / event-broker primitives used by FileSystemRepository.\n *\n * `KeyedMutex` serializes operations on the same key (refKey). The\n * broker re-uses the same manual-AsyncIterator pattern as\n * InMemoryRepository so that consumer `return()` reliably unblocks.\n */\n\nimport type { MetadataEvent, WatchFilter } from '@objectstack/metadata-core';\n\nexport class KeyedMutex {\n private readonly tails = new Map<string, Promise<unknown>>();\n\n async run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const prev = this.tails.get(key) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Save the swallowed-error tail so successive runs don't reject on\n // an unrelated prior failure.\n const swallowed = next.catch(() => undefined);\n this.tails.set(key, swallowed);\n try {\n return await next;\n } finally {\n // Best-effort cleanup: drop the entry if nothing newer was queued.\n if (this.tails.get(key) === swallowed) {\n this.tails.delete(key);\n }\n }\n }\n}\n\n/**\n * One live `watch()` subscription, as a record rather than a bare event sink.\n *\n * Both halves live together because SHUTDOWN NEEDS THE SECOND ONE. A registry\n * of event sinks can only express shutdown as \"send an event\", and an event is\n * precisely what a filtered or numeric-`since` subscriber is entitled to drop\n * — and delivering one has never ended an iterator anyway. See invariant 8 in\n * `@objectstack/metadata-core`'s `repository.ts` (#11021, #11127).\n */\nexport interface BrokerSubscriber {\n filter: WatchFilter;\n closed: boolean;\n push(evt: MetadataEvent): void;\n /**\n * Ends this subscription's iterator: settles a parked `next()` with\n * `{ done: true }` and no value, and unregisters. The SAME routine\n * `iterator.return()` runs, so a consumer that breaks its loop and a\n * consumer whose repository shut down under it observe the same thing.\n */\n terminate(): void;\n}\n\nexport interface EventBroker {\n subscribe(sub: BrokerSubscriber): void;\n unsubscribe(sub: BrokerSubscriber): void;\n publish(evt: MetadataEvent): void;\n /**\n * Terminate every live subscription. This is what `FileSystemRepository`'s\n * repository-level `close()` owes a pending iterator (#11127): before it\n * existed, `close()` retired the chokidar watcher and the resync sweep and\n * stopped there, so the source that could settle a parked `next()` was gone\n * while the subscriber stayed registered with nothing left to settle it.\n *\n * Idempotent, and a no-op when nothing is watching.\n */\n terminateAll(): void;\n}\n\nexport function createBroker(matches: (evt: MetadataEvent, filter: WatchFilter) => boolean): EventBroker {\n const subs = new Set<BrokerSubscriber>();\n return {\n subscribe: (s) => { subs.add(s); },\n unsubscribe: (s) => { subs.delete(s); },\n publish: (evt) => {\n for (const s of subs) {\n if (s.closed) continue;\n if (!matches(evt, s.filter)) continue;\n s.push(evt);\n }\n },\n terminateAll: () => {\n // Snapshot and clear BEFORE terminating: `terminate()` unregisters\n // itself, and mutating a Set under its own iteration is how the second\n // subscriber gets skipped.\n const snapshot = Array.from(subs);\n subs.clear();\n for (const s of snapshot) {\n try {\n s.terminate();\n } catch {\n /* one wedged consumer must not strand the rest */\n }\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Manual `AsyncIterator` factory for `repo.watch()`. Mirrors the\n * pattern used in `@objectstack/metadata-core`'s `InMemoryRepository`:\n * async generators do NOT run `finally` when paused on an unresolved\n * `await`, so we cannot use them to implement `watch()`.\n */\n\nimport type { MetadataEvent, WatchFilter } from '@objectstack/metadata-core';\nimport { type EventBroker, type BrokerSubscriber } from './sync.js';\n\nexport interface CreateWatchIteratorArgs {\n filter: WatchFilter;\n since: number | undefined;\n replay: MetadataEvent[];\n broker: EventBroker;\n /** Returns true if `evt.ref` matches `filter`. */\n matches: (evt: MetadataEvent, filter: WatchFilter) => boolean;\n branchKeyOf: (evt: MetadataEvent) => string;\n /**\n * Checked ONCE, immediately after this subscription is registered. True\n * means the repository shut down while `watch()`'s deferred log replay was\n * still in flight, so this subscription arrived after `close()` had already\n * swept the broker. It is terminated on arrival rather than left parked on a\n * broker nobody will publish to or drain again (#11127).\n */\n arrivesClosed?: () => boolean;\n}\n\nexport function createWatchIterable(\n args: CreateWatchIteratorArgs,\n): AsyncIterable<MetadataEvent> {\n const queue: MetadataEvent[] = [];\n let waiter: ((evt: IteratorResult<MetadataEvent>) => void) | null = null;\n let closed = false;\n const delivered = new Set<string>();\n const evtKey = (e: MetadataEvent) => `${args.branchKeyOf(e)}#${e.seq}`;\n\n const subscriber: BrokerSubscriber = {\n filter: args.filter,\n closed: false,\n // Assigned below, once `close` exists. Termination and the consumer's own\n // `return()` are ONE routine, deliberately: invariant 8 requires shutdown\n // to be indistinguishable from `iterator.return()`.\n terminate: () => undefined,\n push: (evt) => {\n if (subscriber.closed) return;\n const k = evtKey(evt);\n if (delivered.has(k)) return;\n if (waiter) {\n delivered.add(k);\n const w = waiter;\n waiter = null;\n w({ value: clone(evt), done: false });\n } else {\n queue.push(evt);\n }\n },\n };\n args.broker.subscribe(subscriber);\n\n const replay = [...args.replay].sort((a, b) => a.seq - b.seq);\n let replayIdx = 0;\n\n const drain = (): IteratorResult<MetadataEvent> | null => {\n while (replayIdx < replay.length) {\n const evt = replay[replayIdx++]!;\n if (typeof args.since === 'number' && evt.seq <= args.since) continue;\n const k = evtKey(evt);\n if (delivered.has(k)) continue;\n delivered.add(k);\n return { value: clone(evt), done: false };\n }\n while (queue.length > 0) {\n const evt = queue.shift()!;\n const k = evtKey(evt);\n if (delivered.has(k)) continue;\n delivered.add(k);\n return { value: clone(evt), done: false };\n }\n return null;\n };\n\n const close = (): IteratorResult<MetadataEvent> => {\n if (!closed) {\n closed = true;\n subscriber.closed = true;\n args.broker.unsubscribe(subscriber);\n if (waiter) {\n const w = waiter;\n waiter = null;\n w({ value: undefined, done: true });\n }\n }\n return { value: undefined, done: true };\n };\n\n // The terminator `repo.close()` runs. Same routine as `return()` below.\n subscriber.terminate = close;\n\n // Shutdown that landed while the deferred log replay was in flight — this\n // subscription missed the sweep, so it terminates on arrival (#11127).\n if (args.arrivesClosed?.()) close();\n\n const iterator: AsyncIterator<MetadataEvent> = {\n next: () => {\n if (closed) return Promise.resolve({ value: undefined, done: true });\n const immediate = drain();\n if (immediate) return Promise.resolve(immediate);\n return new Promise<IteratorResult<MetadataEvent>>((resolve) => {\n waiter = resolve;\n });\n },\n return: () => Promise.resolve(close()),\n throw: (err) => {\n close();\n return Promise.reject(err);\n },\n };\n return { [Symbol.asyncIterator]: () => iterator };\n}\n\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"],"mappings":"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","names":["import_promises","import_node_fs","import_node_path","path","import_node_path","fs","path","readline","path","fs","chokidar"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/repository.ts","../src/layout.ts","../src/jsonl-log.ts","../src/sync.ts","../src/watch-iterable.ts"],"mappings":"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","names":["import_promises","import_node_fs","import_node_path","path","import_node_path","fs","path","readline","path","fs","chokidar"]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/repository.ts","../src/layout.ts","../src/jsonl-log.ts","../src/sync.ts","../src/watch-iterable.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * `FileSystemRepository` — Node-only implementation of\n * `MetadataRepository` backed by JSON files plus a JSONL change log.\n *\n * See `README.md` for the on-disk layout and ADR-0008 §10 PR-4 for the\n * design rationale.\n *\n * Invariants\n * ──────────\n * - All `put` / `delete` ops serialize per-key via `KeyedMutex`.\n * - The change-log JSONL is the durable source of `seq`. On boot we\n * scan the log to learn the next seq value.\n * - Body files (`<type>/<name>.json`) are the source of truth; the\n * log is a denormalised history index.\n * - chokidar-driven external edits are translated into MetadataEvents\n * by hashing the new content and comparing to the last-known hash.\n * - The root directory is created **on the first write, not on attach**\n * (#7000). Attaching and reading a repository whose root does not exist\n * is legal and answers \"empty\"; see `start()` / `ensureRoot()`.\n * - `close()` ENDS every live `watch()` iterator — the same observation the\n * consumer's own `iterator.return()` produces, never a synthetic event\n * standing in for shutdown (#11127; invariant 8 in `metadata-core`).\n */\n\nimport fs from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport type { FSWatcher } from 'chokidar';\nimport chokidar from 'chokidar';\nimport {\n type MetadataRepository,\n type MetaRef,\n type MetadataItem,\n type MetadataItemHeader,\n type MetadataEvent,\n type PutOptions,\n type PutResult,\n type DeleteOptions,\n type DeleteResult,\n type ListFilter,\n type WatchFilter,\n type HistoryOptions,\n type MetadataType,\n hashSpec,\n ConflictError,\n refKey,\n} from '@objectstack/metadata-core';\nimport {\n type FsLayout,\n itemPath,\n parseItemPath,\n typeDir,\n logFile,\n} from './layout.js';\nimport { JsonlLog } from './jsonl-log.js';\nimport { KeyedMutex, createBroker, type EventBroker } from './sync.js';\nimport { createWatchIterable } from './watch-iterable.js';\n\nexport interface FileSystemRepositoryOptions {\n /** Absolute path to the metadata root directory. */\n root: string;\n /** Tenant/org. */\n org: string;\n /** Identity reported in events that originate from external FS edits. */\n fsActor?: string;\n /** Disable chokidar watcher (e.g. for read-only contexts). */\n disableWatch?: boolean;\n /** Optional clock injection for deterministic tests. */\n now?: () => Date;\n}\n\nconst matchRefFilter = (\n ref: MetaRef,\n filter: { org?: string; type?: MetadataType; name?: string },\n): boolean => {\n if (filter.org && filter.org !== ref.org) return false;\n if (filter.type && filter.type !== ref.type) return false;\n if (filter.name && filter.name !== ref.name) return false;\n return true;\n};\n\nconst matchEvent = (evt: MetadataEvent, filter: WatchFilter): boolean => matchRefFilter(evt.ref, filter);\n\n/**\n * Cadence of the content-keyed reconciliation sweep (#9339).\n *\n * Twice the watcher's own 1000ms poll interval: long enough that the watcher\n * normally delivers first and the sweep finds nothing to do, short enough that\n * a delivery the watcher lost is recovered in the same order of magnitude as a\n * poll rather than at the next process restart.\n *\n * It is deliberately NOT derived from `interval` at runtime. The two are\n * independent knobs — the poll interval sets detection latency for the fast\n * path, this sets the worst-case latency of the backstop — and coupling them\n * would make a future change to one silently retune the other.\n */\nconst RESYNC_INTERVAL_MS = 2_000;\n\n/**\n * The ONE errno that is a truthful \"there is nothing here\" for a directory\n * read, as opposed to \"the read could not run\" (#8895 — discriminate or\n * propagate). A path that does not exist holds no items, so answering with an\n * empty listing states a fact. Every other code — EACCES, EIO, ENOTDIR, and\n * above all EMFILE/ENFILE under fd exhaustion — means the answer was never\n * obtained, and inventing an empty one there is the defect itself.\n */\nconst isEnoent = (err: unknown): boolean =>\n (err as NodeJS.ErrnoException | null)?.code === 'ENOENT';\n\nexport class FileSystemRepository implements MetadataRepository {\n private readonly layout: FsLayout;\n private readonly org: string;\n private readonly fsActor: string;\n private readonly disableWatch: boolean;\n private readonly now: () => Date;\n private readonly log: JsonlLog;\n private readonly mutex = new KeyedMutex();\n private readonly broker: EventBroker = createBroker(matchEvent);\n\n /** In-memory index: refKey → current hash (HEAD). */\n private readonly heads = new Map<string, string>();\n /** Next seq counter, hydrated from the log on `start()`. */\n private nextSeq = 1;\n private watcher: FSWatcher | null = null;\n private started = false;\n /** Pending reconciliation sweep (#9339). Chained, never overlapping. */\n private resyncTimer: ReturnType<typeof setTimeout> | null = null;\n /** False before the watcher is armed and from `close()` onwards. */\n private resyncEnabled = false;\n /**\n * Sweep read faults already reported, keyed `CODE @ path`, so a standing\n * fault is announced once rather than every 2s (AGENTS.md: say it once, at\n * the first degradation). An entry is cleared when that path reads again.\n */\n private readonly resyncFaults = new Set<string>();\n /**\n * Bumped by every `close()`. `watch()` reads it before its deferred log\n * replay starts and hands the comparison to `createWatchIterable`, so a\n * subscription that registers AFTER the shutdown sweep terminates on\n * arrival instead of parking forever (#11127). A counter rather than a\n * boolean because `start()` may follow `close()`: a repository restart must\n * not poison the watchers opened after it.\n */\n private closeGeneration = 0;\n\n constructor(opts: FileSystemRepositoryOptions) {\n this.org = opts.org;\n this.fsActor = opts.fsActor ?? 'fs';\n this.disableWatch = opts.disableWatch ?? false;\n this.now = opts.now ?? (() => new Date());\n this.layout = { root: path.resolve(opts.root) };\n this.log = new JsonlLog(logFile(this.layout));\n }\n\n // ── Lifecycle ───────────────────────────────────────────────────────\n\n /**\n * Attach the repository. **Creates nothing on disk** (#7000).\n *\n * Attaching is not a write. `start()` used to `mkdir` both the root and\n * `<root>/.objectstack/.log` unconditionally, which meant every read-only\n * boot that merely attaches a repository left a skeleton behind — most\n * visibly `os migrate plan`, a declared dry run, on a project that has\n * never been started. That is the same property #6743 ruled on for\n * `.objectstack/data/`: a dry run leaves nothing behind, and the existence\n * of `.objectstack/` has to stay a usable \"this project has been started\"\n * signal.\n *\n * Every read path below already treats a missing root as an empty\n * repository (`scanHeads` swallows ENOENT, `JsonlLog` guards on\n * `existsSync`, `get` guards on `existsSync`), so the root is materialized\n * by `ensureRoot()` on the first write instead.\n */\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n // 1) Scan body files to build the head index. No-op on a missing root.\n await this.scanHeads();\n\n // 2) Hydrate nextSeq from the existing log. No-op on a missing log.\n const highest = await this.log.highestSeq();\n this.nextSeq = highest + 1;\n\n // 3) Start the watcher (unless disabled). chokidar cannot watch a path\n // that does not exist yet: measured on chokidar 5 with `usePolling`,\n // a root created AFTER `watch()` produces no events at all, ever. So\n // when the root is absent the watcher is armed later, by the\n // `ensureRoot()` call that brings the root into existence — otherwise\n // dropping the `mkdir` above would silently kill external-edit\n // detection for the whole life of the process.\n if (!this.disableWatch && existsSync(this.layout.root)) this.startWatcher();\n }\n\n /**\n * Bring the repository root into existence. Called by every write path\n * immediately before it touches the disk — `start()` deliberately does not\n * create it (#7000), so this is the single seam where the root appears.\n *\n * It is also where a watcher that `start()` could not arm (missing root)\n * gets armed, so \"external edits are detected\" survives the change.\n */\n private async ensureRoot(): Promise<void> {\n await fs.mkdir(this.layout.root, { recursive: true });\n if (this.started && !this.disableWatch && !this.watcher) this.startWatcher();\n }\n\n /**\n * Shut the repository down, ending every live `watch()` iterator.\n *\n * **Shutdown terminates; it does not emit** — invariant 8 in\n * `@objectstack/metadata-core`'s `repository.ts`, and the reason this method\n * reaches the broker at all. It used to retire the chokidar watcher and the\n * resync sweep and stop there. The broker has no teardown of its own\n * (`subscribe`/`unsubscribe` add to and delete from a plain `Set`), and each\n * iterator parks its pending `next()` on a `waiter` that only a broker\n * `push` or the iterator's own terminator can settle. After `close()` the\n * chokidar source was gone, so no `push` could arrive; the subscriber was\n * still registered, and nothing ran its terminator. A consumer holding a\n * `for await` at shutdown — `MetadataManager.startRepositoryWatch()` is\n * exactly that shape — therefore never saw its loop end, for EVERY\n * subscription shape including `watch({})`.\n *\n * Termination is expressed as termination: each subscription's\n * `terminate()`, which is the same routine the consumer's own\n * `iterator.return()` runs, so no consumer has to tell \"the repository shut\n * down under me\" apart from \"I broke my own loop\". A synthetic drain event\n * would be the wrong shape and was measured to be so (#11021): the\n * subscriptions most in need of draining are exactly the ones whose filter\n * or numeric `since` drops it, and delivering an event has never ended an\n * iterator.\n */\n async close(): Promise<void> {\n // Retire the sweep BEFORE awaiting the watcher, so a sweep that lands\n // during `watcher.close()` cannot reschedule itself behind our back.\n this.stopResync();\n // Terminate BEFORE the await for the same reason: a `watcher.close()` that\n // rejects must not leave a consumer's `for await` parked forever, and a\n // straggler event from the dying watcher has no one left to reach. Events\n // still queued or unreplayed at this moment MAY be dropped (invariant 8),\n // on this path and on `return()` alike.\n this.closeGeneration++;\n this.broker.terminateAll();\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n this.started = false;\n }\n\n // ── Read API ────────────────────────────────────────────────────────\n\n async get(ref: MetaRef): Promise<MetadataItem | null> {\n this.assertScope(ref);\n const file = itemPath(this.layout, ref.type, ref.name);\n if (!existsSync(file)) return null;\n const body = await readJson(file);\n if (!body) return null;\n const hash = hashSpec(body);\n if (ref.version && ref.version !== hash) return null;\n // Walk back through the log to populate parent/authoredBy/seq.\n const meta = await this.findMetaForHash(ref, hash);\n return {\n ref: { ...ref, version: undefined },\n body: body as Record<string, unknown>,\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? new Date(0).toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n };\n }\n\n async getByHash(ref: MetaRef, hash: string): Promise<MetadataItem | null> {\n // FS repo stores only HEAD bodies on disk; the JSONL log records\n // events (hashes) but not historical bodies. Resolve only if the\n // requested hash matches HEAD.\n const head = await this.get(ref);\n if (!head || head.hash !== hash) return null;\n return head;\n }\n\n async *list(filter: ListFilter): AsyncIterable<MetadataItemHeader> {\n const limit = filter.limit ?? Infinity;\n let yielded = 0;\n for (const [key, hash] of this.heads) {\n const ref = parseRefKey(key);\n if (!ref) continue;\n if (!matchRefFilter(ref, filter)) continue;\n if (filter.nameContains && !ref.name.includes(filter.nameContains)) continue;\n const meta = await this.findMetaForHash(ref, hash);\n const header: MetadataItemHeader = {\n ref: { ...ref, version: undefined },\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? new Date(0).toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n };\n yield header;\n if (++yielded >= limit) return;\n }\n }\n\n async *history(ref: MetaRef, opts: HistoryOptions = {}): AsyncIterable<MetadataEvent> {\n this.assertScope(ref);\n const since = opts.sinceSeq ?? -1;\n const limit = opts.limit ?? Infinity;\n let yielded = 0;\n for await (const evt of this.log.readAll()) {\n if (evt.seq <= since) continue;\n if (evt.ref.type !== ref.type || evt.ref.name !== ref.name) continue;\n if (evt.ref.org !== ref.org) continue;\n yield evt;\n if (++yielded >= limit) return;\n }\n }\n\n watch(filter: WatchFilter, since?: number): AsyncIterable<MetadataEvent> {\n // Eagerly snapshot the existing log for replay; new events route via broker.\n const replay: MetadataEvent[] = [];\n const promise = (async () => {\n for await (const evt of this.log.readAll()) {\n if (matchEvent(evt, filter)) replay.push(evt);\n }\n })();\n // Read BEFORE the read above can complete: the subscriber below is\n // registered only when it does, which is a window `close()`'s sweep cannot\n // see (#11127). Compared on arrival, a shutdown inside that window ends\n // this iterator instead of parking it.\n const generation = this.closeGeneration;\n // We must await replay before returning, but the public API is\n // sync-returning AsyncIterable. Wrap in a deferred iterable.\n return deferredIterable(promise.then(() =>\n createWatchIterable({\n filter,\n since,\n replay,\n broker: this.broker,\n matches: matchEvent,\n branchKeyOf: (e) => e.ref.org,\n arrivesClosed: () => this.closeGeneration !== generation,\n }),\n ));\n }\n\n // ── Write API ───────────────────────────────────────────────────────\n\n put(ref: MetaRef, spec: unknown, opts: PutOptions): Promise<PutResult> {\n this.assertScope(ref);\n return this.mutex.run(refKey(ref), async () => {\n const key = refKey(ref);\n const currentHead = this.heads.get(key) ?? null;\n if ((opts.parentVersion ?? null) !== currentHead) {\n throw new ConflictError(ref, opts.parentVersion ?? null, currentHead);\n }\n const hash = hashSpec(spec);\n if (currentHead === hash) {\n // No-op write — same content.\n const meta = await this.findMetaForHash(ref, hash);\n return {\n version: hash,\n seq: meta?.seq ?? 0,\n item: {\n ref: { ...ref, version: undefined },\n body: spec as Record<string, unknown>,\n hash,\n parentHash: meta?.parentHash ?? null,\n authoredBy: meta?.actor ?? this.fsActor,\n authoredAt: meta?.ts ?? this.now().toISOString(),\n message: meta?.message,\n seq: meta?.seq ?? 0,\n },\n };\n }\n\n const seq = this.nextSeq++;\n const ts = this.now().toISOString();\n const file = itemPath(this.layout, ref.type, ref.name);\n // First write of the process materializes the root (#7000).\n await this.ensureRoot();\n await fs.mkdir(typeDir(this.layout, ref.type), { recursive: true });\n await writeJsonAtomic(file, spec);\n // The watcher must not depend on its own directory scan to notice a\n // path we created ourselves (#7282). See `trackWrittenPath`.\n this.trackWrittenPath(file);\n // Publishing the new head here is what suppresses the watcher event this\n // write is about to produce — see `handleFsChange` (#7335). It runs in\n // the same continuation as the `rename` above, and `awaitWriteFinish`\n // holds any event for a further `stabilityThreshold`, so the index is\n // always current by the time an event for this path can be delivered.\n this.heads.set(key, hash);\n\n const evt: MetadataEvent = {\n seq,\n op: currentHead ? 'update' : 'create',\n ref: { ...ref, version: undefined },\n hash,\n parentHash: currentHead,\n actor: opts.actor,\n message: opts.message,\n ts,\n source: opts.source ?? 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n\n return {\n version: hash,\n seq,\n item: {\n ref: { ...ref, version: undefined },\n body: spec as Record<string, unknown>,\n hash,\n parentHash: currentHead,\n authoredBy: opts.actor,\n authoredAt: ts,\n message: opts.message,\n seq,\n },\n };\n });\n }\n\n delete(ref: MetaRef, opts: DeleteOptions): Promise<DeleteResult> {\n this.assertScope(ref);\n return this.mutex.run(refKey(ref), async () => {\n const key = refKey(ref);\n const currentHead = this.heads.get(key) ?? null;\n if (currentHead !== opts.parentVersion) {\n throw new ConflictError(ref, opts.parentVersion, currentHead);\n }\n const file = itemPath(this.layout, ref.type, ref.name);\n // A delete appends a tombstone to the change log, so it is a write too.\n await this.ensureRoot();\n // Retire the head BEFORE touching the disk, not after (#7335).\n //\n // `awaitWriteFinish` only debounces `add`/`change`; chokidar emits\n // `unlink` with no stability delay at all, so — unlike `put()` — this\n // face has no cushion between the disk mutation and the event it\n // produces. Clearing the index first makes `handleFsChange`'s\n // `if (!currentHead) return` a total suppression for our own removal\n // rather than a race against the poll callback.\n this.heads.delete(key);\n try {\n if (existsSync(file)) await fs.unlink(file);\n } catch (err) {\n // The disk still holds the item, so the index must too — otherwise a\n // failed delete would leave the repository claiming a file it can\n // still read. Restores exactly the pre-call state before rethrowing.\n if (currentHead !== null) this.heads.set(key, currentHead);\n throw err;\n }\n const seq = this.nextSeq++;\n const ts = this.now().toISOString();\n const evt: MetadataEvent = {\n seq,\n op: 'delete',\n ref: { ...ref, version: undefined },\n hash: null,\n parentHash: currentHead,\n actor: opts.actor,\n message: opts.message,\n ts,\n source: opts.source ?? 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n return { seq };\n });\n }\n\n // ── Internals ───────────────────────────────────────────────────────\n\n private assertScope(ref: MetaRef): void {\n if (ref.org !== this.org) {\n throw new Error(\n `FileSystemRepository scope mismatch: expected org=${this.org}, got org=${ref.org}`,\n );\n }\n }\n\n private async scanHeads(): Promise<void> {\n this.heads.clear();\n // Walk one level deep: <root>/<type>/<name>.json\n let entries: import('node:fs').Dirent[] = [];\n try {\n entries = await fs.readdir(this.layout.root, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n const type = entry.name;\n const dir = path.join(this.layout.root, type);\n let files: string[] = [];\n try {\n files = await fs.readdir(dir);\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n const name = file.slice(0, -'.json'.length);\n const ref: MetaRef = {\n org: this.org,\n type: type as MetadataType,\n name,\n };\n const body = await readJson(path.join(dir, file));\n if (!body) continue;\n this.heads.set(refKey(ref), hashSpec(body));\n }\n }\n }\n\n private async findMetaForHash(\n ref: MetaRef,\n hash: string,\n ): Promise<MetadataEvent | null> {\n let last: MetadataEvent | null = null;\n for await (const evt of this.log.readAll()) {\n if (evt.ref.type !== ref.type || evt.ref.name !== ref.name) continue;\n if (evt.ref.org !== ref.org) continue;\n if (evt.hash === hash) last = evt;\n }\n return last;\n }\n\n /**\n * Register a path this repository just wrote with the watcher (#7282).\n *\n * chokidar's initial scan is asynchronous, and every write path here can be\n * running **while it is still walking the tree** — `start()` arms the watcher\n * and the caller may `put()` on the next tick, and `ensureRoot()` arms it in\n * the middle of the very first write. With `usePolling` that combination has\n * a permanently-blinding interleaving, measured on chokidar 5 with this\n * repository's own options:\n *\n * 1. chokidar reads `<root>/<type>/` and finds it EMPTY — the atomic\n * `rename` in `writeJsonAtomic` has not landed yet.\n * 2. the rename lands; the directory's mtime changes.\n * 3. chokidar calls `watchFile()` on that directory, and libuv takes its\n * polling baseline stat — which already reflects step 2.\n *\n * From then on the directory's stat never changes again, so no poll ever\n * fires for it, `_handleRead` never re-runs, the item file is never added to\n * the watched set, and no per-file watcher is ever created. chokidar emits\n * neither `add` nor `change` for that path **for the life of the process** —\n * `getWatched()` reports the type directory as `[]` forever while the file\n * sits in it. That is the whole of #7282: the four merge-queue ejections all\n * waited out their deadlines (20s, then 25541ms against 25s) on an event that\n * was never going to be delivered, which is why widening the deadline and\n * widening the pre-edit sleep both changed nothing, and why lowering\n * `interval` would change nothing either — a shorter poll re-compares against\n * the same unchanged directory stat.\n *\n * The window is exactly \"files that exist at baseline time but were absent\n * from the snapshot read a moment earlier\", and the only writer that can be\n * inside it is us. So we close it at the source: tell the watcher explicitly\n * about every path we create, instead of hoping its scan happened to see it.\n *\n * `add()` is idempotent here — `_handleFile` returns early when the parent\n * directory already tracks the basename — and it emits nothing, because\n * chokidar treats an explicit `add()` as an initial add and `ignoreInitial`\n * is set. Its effect is the one we need: `_watchWithNodeFs` registers the\n * basename with the parent directory (without which chokidar drops `change`\n * events for the file) and starts the per-file poll.\n */\n private trackWrittenPath(file: string): void {\n const w = this.watcher;\n // `add()` clears `closed`, so never hand a closing watcher a new path.\n if (!w || w.closed) return;\n w.add(file);\n }\n\n private startWatcher(): void {\n const root = this.layout.root;\n const w = chokidar.watch(root, {\n // Skip dotfiles under the root — including the repository's own\n // `.objectstack/` bookkeeping subtree — matched on the path RELATIVE\n // to the watch root (#7150). See `isIgnoredWatchPath`.\n ignored: (p: string) => isIgnoredWatchPath(root, p),\n ignoreInitial: true,\n depth: 2,\n awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 20 },\n // Use polling to avoid `fs.watch` EMFILE on macOS / busy dev hosts.\n // The depth-2 recursion would otherwise wire native watches across\n // the entire customization tree.\n usePolling: true,\n interval: 1000,\n binaryInterval: 2000,\n // Declared explicitly, not inherited. chokidar's own default-correction\n // (`if (opts.atomic === undefined) opts.atomic = !opts.usePolling`) can\n // only fire when the caller omits `atomic`, but its defaults literal\n // already assigns `atomic: true` *before* the caller's options are\n // spread in — so leaving `atomic` unset here does not mean \"off under\n // polling\" the way the correction's own comment claims, it silently\n // resolves to `true` regardless of `usePolling`. That has been this\n // repository's actual runtime behaviour all along (verified by reading\n // back the resolved option from a real watcher instance, #12696): every\n // `unlink` gets chokidar's 100ms editor-atomic-write deferral, and\n // `DOT_RE` (vim swap files, `~`, sublime tmp) is folded into\n // `_isIgnored` on top of this repository's own `isIgnoredWatchPath`\n // (#7150). `atomic: true` here keeps that behaviour byte-for-byte —\n // this is a declaration, not a change. Flipping it to `false` would\n // remove both behaviours from a live delivery path and needs its own\n // reverse verification; see #12696 for the analysis.\n atomic: true,\n });\n w.on('add', (p) => void this.handleFsChange(p, 'add'));\n w.on('change', (p) => void this.handleFsChange(p, 'change'));\n w.on('unlink', (p) => void this.handleFsChange(p, 'unlink'));\n this.watcher = w;\n // The watcher is the fast path, not the guarantee (#9339). See `resync`.\n this.startResync();\n }\n\n /**\n * Publish the `delete` face of an externally-observed removal.\n *\n * Extracted from `handleFsChange` unchanged so the reconciliation sweep\n * (#9339) can reuse it **verbatim** rather than growing a second copy of the\n * event shape. The one-line invariant: the caller already holds the per-key\n * mutex, and `!currentHead` is the content-keyed suppression that makes our\n * own `delete()` a no-op here.\n */\n private async publishExternalDelete(ref: MetaRef, key: string): Promise<void> {\n const currentHead = this.heads.get(key) ?? null;\n if (!currentHead) return;\n this.heads.delete(key);\n const seq = this.nextSeq++;\n const evt: MetadataEvent = {\n seq,\n op: 'delete',\n ref: { ...ref, version: undefined },\n hash: null,\n parentHash: currentHead,\n actor: this.fsActor,\n ts: this.now().toISOString(),\n source: 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n }\n\n private startResync(): void {\n this.resyncEnabled = true;\n this.scheduleResync();\n }\n\n private stopResync(): void {\n this.resyncEnabled = false;\n if (this.resyncTimer) {\n clearTimeout(this.resyncTimer);\n this.resyncTimer = null;\n }\n }\n\n /**\n * Schedule the next sweep — chained, never `setInterval` (#9339).\n *\n * A chained timeout cannot stack: the next sweep is armed only once the\n * previous one has finished, so a saturated runner degrades to *fewer*\n * sweeps instead of a growing backlog of overlapping tree walks. The timer\n * is `unref`ed because a backstop must never be the reason a process stays\n * alive.\n */\n private scheduleResync(): void {\n if (!this.resyncEnabled || this.resyncTimer) return;\n const timer = setTimeout(() => {\n this.resyncTimer = null;\n void this.resync().finally(() => this.scheduleResync());\n }, RESYNC_INTERVAL_MS);\n timer.unref?.();\n this.resyncTimer = timer;\n }\n\n /**\n * Announce a sweep read that could not run — the non-silence half of #8895's\n * \"discriminate or propagate\".\n *\n * ## Why `error` and not `warn`\n *\n * AGENTS.md decides the level with one question: *after the degradation, does\n * the system still look \"normal\" from the outside while something it claims\n * is persisted has not actually landed?* Here it does. Nothing throws, the\n * watcher stays armed, `getWatched()` stays populated, `start()` succeeded —\n * and the repository's index quietly stops tracking what is on disk. That is\n * the rule's second limb verbatim (\"persisted state and runtime state\n * disagree\"), not the functional-degradation limb: no capability is visibly\n * smaller, so nobody finds out by using the missing thing.\n *\n * The counter-argument — *this is only a backstop, the watcher is still the\n * fast path* — is why the level is arguable, and it does not survive the\n * failing errno. The sharp case is fd exhaustion: EMFILE/ENFILE break this\n * `readdir` and chokidar's `fs.watchFile` polling **at the same time and for\n * the same reason**, so the fast path is not an independent fallback under\n * precisely the load that produces this fault. A backstop that is silently\n * absent whenever it is most needed is a durability-shaped degradation.\n *\n * ⚠️ AGENTS.md also warns against over-applying `error`, and the discipline\n * that answers it is the ledger, not a quieter level: an `error` owes the\n * consequence and the fix, said **once** at the first degradation rather than\n * once per failed read. A sweep runs every 2s forever, so an unlatched\n * `console.error` here would be the mirror-image failure the same rule names.\n *\n * ⛔ It deliberately does NOT throw. This runs on a background timer; taking\n * a process down on a transient EACCES would be worse than the bug. The bar\n * met here is non-silence, not propagation.\n *\n * The channel is `console.error` because this class has no logger: nothing is\n * injected through `FileSystemRepositoryOptions`, and widening that public\n * surface to carry one is out of scope for this fix.\n */\n private reportResyncFault(target: string, err: unknown): void {\n const code = (err as NodeJS.ErrnoException | null)?.code ?? 'UNKNOWN';\n const key = `${code} @ ${target}`;\n if (this.resyncFaults.has(key)) return;\n this.resyncFaults.add(key);\n console.error(\n `[FileSystemRepository] metadata reconciliation sweep could not read ${target} (${code}). ` +\n `CONSEQUENCE: external edits under this path are no longer reconciled, so this ` +\n `repository's index and its watch() subscribers can drift from what is on disk while ` +\n `everything keeps reporting healthy. The chokidar watcher is not an independent ` +\n `fallback here — fd exhaustion degrades both. ` +\n `FIX: restore read access to the path; the sweep recovers by itself on the first ` +\n `successful read. Reported once per path and error code.`,\n );\n }\n\n /** Re-arm reporting for a path that reads again, so a recurrence is heard. */\n private clearResyncFault(target: string): void {\n if (this.resyncFaults.size === 0) return;\n const suffix = ` @ ${target}`;\n for (const key of this.resyncFaults) {\n if (key.endsWith(suffix)) this.resyncFaults.delete(key);\n }\n }\n\n /**\n * Content-keyed reconciliation sweep — the backstop that makes external-edit\n * detection a guarantee rather than a single chance (#9339, #7282).\n *\n * ## Why the watcher alone cannot be the guarantee\n *\n * An external write to `<root>/<type>/<name>.json` reaches a subscriber only\n * if chokidar notices it, and under `usePolling` it gets **exactly one**\n * opportunity to do so: the write advances the type directory's mtime once,\n * and chokidar re-reads a directory only when its stat *strictly advances*,\n * so every later poll compares an unchanged stat and can never rediscover\n * the file. Measured on #9339 with a fault-injection harness: with the one\n * read suppressed, fifteen further poll ticks never find the new file, and a\n * 20s deadline and a 200s deadline buy the same single attempt. That is the\n * structural reason behind #7282's empirical finding that the event is\n * \"never delivered, not slow\", and why widening the deadline (#7208) and\n * lowering `interval` were both spent before they were tried.\n *\n * At least six independent one-shot gates sit on that single attempt,\n * spanning three layers — the kernel timestamp (the directory mtime does not\n * strictly advance), chokidar's readdir throttle and readdir snapshot, and\n * chokidar's emit gates (`_throttle('add')`, a stale `_pendingWrites` entry,\n * the `awaitWriteFinish` ENOENT early return). Each one produces a\n * byte-identical observable: no event, ever, for that path.\n *\n * ## Why this shape, and not a narrower one\n *\n * ⚠️ The six are indistinguishable at the point of failure, so **any fix\n * that has to name which gate fired is a fix for one member of a family** —\n * which is exactly how #7282 was closed and exactly why it reopened. This\n * sweep never asks. It compares what is on disk against `heads`, the index\n * that already defines what this repository believes it holds, and publishes\n * the divergence through the same `handleFsChange` the watcher feeds. It is\n * therefore robust across all six *by construction*, and equally across a\n * seventh nobody has found: the only property it relies on is that the bytes\n * on disk stopped matching the index.\n *\n * `put()` is unaffected and keeps its direct registration (`trackWrittenPath`\n * calls `watcher.add` and bypasses the whole chain, which is why the `put()`\n * half of this family was already closed by #7336 and the external-write half\n * was not).\n *\n * ## Cost, and why it is bounded\n *\n * One pass over `<root>/<type>/*.json` per sweep — the same walk `start()`\n * already performs once — with no retry loop inside it and no work at all\n * when nothing diverged. Sweeps are chained, so they cannot overlap; the\n * timer is `unref`ed and dies with `close()`; and it is armed only alongside\n * the watcher, so a `disableWatch` repository pays nothing.\n *\n * Discovery is by content, never by stat: a stat pre-filter would reintroduce\n * a time key of exactly the kind this replaces.\n */\n private async resync(): Promise<void> {\n const root = this.layout.root;\n let entries: import('node:fs').Dirent[] = [];\n try {\n entries = await fs.readdir(root, { withFileTypes: true });\n this.clearResyncFault(root);\n } catch (err) {\n // ENOENT is truthful: a root that does not exist holds nothing to\n // reconcile, and the next sweep sees whatever replaces it. Any other\n // errno means the read could not RUN, and staying silent about that\n // would make this backstop absent for the life of the process exactly\n // when the load-dependent loss it exists to catch is most likely —\n // EMFILE/ENFILE degrade this read and chokidar's own polling together.\n if (!isEnoent(err)) this.reportResyncFault(root, err);\n return;\n }\n const onDisk = new Set<string>();\n /**\n * Type directories whose listing could not be obtained. Their keys are\n * missing from `onDisk` for a reason that is NOT \"the files are gone\", so\n * the delete pass below must not read that absence as a removal.\n */\n const unreadableTypes = new Set<string>();\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n // Same dot-entry rule as `scanHeads` and `isIgnoredWatchPath`, so the\n // boot scan, the watcher and this sweep agree on what the repository\n // contains (#7150).\n if (entry.name.startsWith('.')) continue;\n const dir = path.join(root, entry.name);\n let files: string[] = [];\n try {\n files = await fs.readdir(dir);\n this.clearResyncFault(dir);\n } catch (err) {\n // The same discrimination at type granularity. An unreadable type\n // directory silently stops reconciling EVERY item of that type, which\n // is exactly the invented-emptiness shape #8895 rules on.\n if (!isEnoent(err)) {\n this.reportResyncFault(dir, err);\n unreadableTypes.add(entry.name);\n }\n continue;\n }\n for (const file of files) {\n if (!file.endsWith('.json') || file.startsWith('.')) continue;\n const abs = path.join(dir, file);\n const parsed = parseItemPath(this.layout, abs);\n if (!parsed) continue;\n const ref: MetaRef = {\n org: this.org,\n type: parsed.type as MetadataType,\n name: parsed.name,\n };\n const key = refKey(ref);\n onDisk.add(key);\n const before = this.heads.get(key);\n await this.handleFsChange(abs, 'add');\n if (this.heads.get(key) !== before) {\n // We just published a change the watcher never delivered, so the\n // watcher may not know this path at all (the loss can be upstream of\n // chokidar's `_handleFile`). Re-arm it through the same seam `put()`\n // uses, so the fast path is restored instead of leaving every future\n // edit to this file dependent on the sweep.\n this.trackWrittenPath(abs);\n }\n }\n }\n for (const key of [...this.heads.keys()]) {\n if (onDisk.has(key)) continue;\n const ref = parseRefKey(key);\n if (!ref) continue;\n // Absent from `onDisk` because we could not look, not because it is gone.\n if (unreadableTypes.has(ref.type)) continue;\n const file = itemPath(this.layout, ref.type, ref.name);\n await this.mutex.run(key, async () => {\n // Re-checked UNDER the lock. The enumeration above ran outside it, so\n // a `put()` that created this file in between would otherwise be\n // reported as an external delete.\n if (existsSync(file)) return;\n await this.publishExternalDelete(ref, key);\n });\n }\n }\n\n /**\n * Translate a watcher event into a `MetadataEvent`, or drop it.\n *\n * ## Self-writes are suppressed by content identity, never by a clock (#7335)\n *\n * This used to open with `if (this.selfWrites.has(absPath)) return;` — a\n * `Set` that `put()`/`delete()` added the path to and a `setTimeout(…, 200)`\n * cleared. That check discarded **every** event for a recently-written path\n * without ever looking at what the watcher had actually observed, which is\n * the whole defect: with `usePolling`, chokidar compares state once per\n * `interval`, so our write and an external edit landing between two ticks\n * are delivered as **one** event carrying the *external* content. Dropping\n * it on a wall clock destroyed the only notification that edit would ever\n * produce.\n *\n * Measured on `origin/main` @ `69fde55`, 40 iterations, poll phase\n * randomised so the delivery lag samples `[0, interval)` uniformly:\n *\n * delivery lag < 200ms → 7 runs → external edit SWALLOWED, every time\n * delivery lag > 200ms → 33 runs → external edit delivered, every time\n *\n * A perfect split on the wall-clock boundary, and the reason earlier\n * instrumentation saw 0/360: a *fixed* pre-edit sleep phase-locks the poll,\n * pinning the lag (measured: 519–585ms across 25 runs) safely outside the\n * window. Nothing about the window was rare — it was unsampled.\n *\n * What remains is the check that was already doing the real work one step\n * down, and it needs no timer because it compares the content the watcher\n * **read** against the index:\n *\n * - `add`/`change` — `currentHead === hash` drops the event when the bytes\n * on disk are the bytes we last published. `put()` sets that head in the\n * same continuation as its `rename`, and `awaitWriteFinish` holds the\n * event for a further `stabilityThreshold`, so it is never late.\n * - `unlink` — `!currentHead` drops the event when the index already\n * agrees the item is gone. `delete()` retires the head *before* it\n * unlinks, precisely because this face gets no `awaitWriteFinish` delay.\n * This is the whole of the *self-write* answer on this face, and it is\n * not the whole of the face — see the section below it.\n *\n * Both faces are pinned together in `test/self-write-suppression.test.ts`.\n *\n * ## A removal is confirmed against the disk before it is published (#7369)\n *\n * Those two checks answer \"is this event OURS\". Neither answers \"did this\n * happen at all\", and the `unlink` face needs that second question asked\n * because its input is a third party's inference: chokidar decides a file is\n * gone from a *stat that failed*, not only from a file that went away, and\n * `!currentHead` cannot tell the two apart because a spurious unlink leaves\n * the index exactly as valid as it was.\n *\n * The cost of getting it wrong is not a dropped notification, which the\n * sweep would repair. A `delete` is appended to the change log and broadcast\n * to every subscriber, and `MetadataManager` drops the item from the\n * registry and the `list()` cache on receipt. The sweep then finds the file\n * still on disk and republishes it as a `create` — so a failed stat becomes\n * a durable, permanently recorded delete/create pair for an item that never\n * changed, and every consumer sees the item disappear in between. That is\n * the shape ADR-0008's log is least able to walk back.\n *\n * So `existsSync` under the same per-key lock the sweep uses, and the same\n * decision it makes: absent ⇒ publish the removal; present ⇒ this was a\n * change, answered by the content path below. Genuine removals pay nothing —\n * `delete()` is still suppressed by `!currentHead`, and an external `rm` is\n * still published on the first delivery, because for those the file really\n * is gone. Pinned in `test/external-delete-requires-absence.test.ts`.\n *\n * Note the deliberate limit: identity is judged on what round-trips through\n * the file, so a spec whose in-memory form does not (a `Date`, which\n * canonicalises to `{}` in memory but to an ISO string once written and\n * re-read) is republished as an external `update`. That predates this change\n * and is independent of it — such a spec already fails `put().version ===\n * get().hash`, and the 200ms window never covered it either, expiring some\n * 360ms before the event it would have had to catch.\n */\n private async handleFsChange(absPath: string, kind: 'add' | 'change' | 'unlink'): Promise<void> {\n const parsed = parseItemPath(this.layout, absPath);\n if (!parsed) return;\n const ref: MetaRef = {\n org: this.org,\n type: parsed.type as MetadataType,\n name: parsed.name,\n };\n const key = refKey(ref);\n await this.mutex.run(key, async () => {\n // A watcher `unlink` is a CLAIM of absence, not absence — so it is\n // confirmed against the disk before a `delete` is published (#7369).\n // `!currentHead` inside `publishExternalDelete` cannot do this job: it\n // compares against the INDEX, which is exactly what a spurious unlink\n // leaves intact. The reconciliation sweep already re-checks disk truth\n // under this same lock before retiring a key, for a reason it states in\n // place; the watcher face was the one path that published a removal on\n // the observer's word alone.\n //\n // chokidar reaches its removal path from failed *stats* as well as from\n // real removals, and says so at both sites (chokidar 5 `handler.js`):\n // `_handleFile`'s poll listener re-stats a file whose watched stat came\n // back zeroed and calls `_remove` from the catch — under the comment\n // \"Fix issues where mtime is null but file is still present\" — with no\n // discrimination on errno, so EMFILE/ENFILE retires a file that is\n // there; and `_handleRead`'s snapshot diff `_remove`s every previously\n // tracked entry its readdirp pass did not enumerate, which includes the\n // entries whose per-entry `lstat` failed rather than only the ones that\n // are gone. Both faults are load-shaped, which is why the merge queue —\n // the only context that runs the FULL suite — is where this surfaced,\n // twice, on a case that touches nothing else.\n //\n // Falling through is the repair, not just skipping: when the path is\n // still there the honest reading of the event is \"something happened to\n // this file\", which is the content path's question. It answers with the\n // same `currentHead === hash` comparison used everywhere else, so a\n // spurious unlink that accompanied a real in-place edit still surfaces\n // as the `update` it always was, in the same tick, rather than as the\n // `delete` + `create` pair the index-only check produced.\n if (kind === 'unlink' && !existsSync(absPath)) {\n await this.publishExternalDelete(ref, key);\n return;\n }\n const body = await readJson(absPath);\n if (!body) return;\n const hash = hashSpec(body);\n const currentHead = this.heads.get(key) ?? null;\n if (currentHead === hash) return; // No content change.\n this.heads.set(key, hash);\n const seq = this.nextSeq++;\n const evt: MetadataEvent = {\n seq,\n op: currentHead ? 'update' : 'create',\n ref: { ...ref, version: undefined },\n hash,\n parentHash: currentHead,\n actor: this.fsActor,\n ts: this.now().toISOString(),\n source: 'fs',\n };\n await this.log.append(evt);\n this.broker.publish(evt);\n });\n }\n}\n\n// ── Utilities ─────────────────────────────────────────────────────────\n\n/**\n * Watcher ignore matcher — \"everything under the root, except the\n * repository's own bookkeeping\" (#7150).\n *\n * chokidar hands its matcher **absolute** paths, and applies it to the\n * watched root itself as well as to entries discovered underneath it. The\n * previous matcher was a bare dotfile regex (`/(^|[\\\\/])\\../`), which\n * therefore matched the `.objectstack` segment of the root path the plugin\n * actually uses (`<project>/.objectstack/metadata`, `REPO_SUBDIR` in\n * `packages/metadata/src/plugin.ts`) and ignored the whole watch. Measured on\n * chokidar 5 with this repository's own options, two identical trees\n * differing only in whether the root sits under a dot-directory:\n *\n * plain root getWatched: ['<root>', 'view'] events: add+change\n * dot-rooted getWatched: [] events: none\n *\n * So the intent is kept and only the *frame of reference* is fixed: judge the\n * path relative to the root, so dot segments belonging to the root itself are\n * never considered.\n *\n * Why not drop the matcher entirely and lean on `parseItemPath`, which already\n * rejects `.objectstack`? Measured: `parseItemPath` rejects that ONE name, so\n * a dot-directory at the type level leaks — `<root>/.cache/x.json` parses as\n * type `.cache`, and `<root>/view/.scratch.json` as an item named `.scratch`.\n * Both would be published as `MetadataEvent`s while `scanHeads` skips every\n * dot entry on boot, leaving the boot scan and the watcher disagreeing about\n * what the repository contains. Dropping it also puts `.objectstack/.log/` in\n * the poll set, so every one of the repository's own log appends wakes\n * `handleFsChange` only to be discarded.\n */\nfunction isIgnoredWatchPath(root: string, absPath: string): boolean {\n const rel = path.relative(root, absPath);\n // The watched root itself, and anything outside it, are not ours to judge.\n if (rel === '' || rel.startsWith('..')) return false;\n return rel.split(/[\\\\/]/).some((segment) => segment.startsWith('.'));\n}\n\nasync function readJson(file: string): Promise<unknown | null> {\n try {\n const text = await fs.readFile(file, 'utf8');\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nasync function writeJsonAtomic(file: string, body: unknown): Promise<void> {\n const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(body, null, 2) + '\\n', 'utf8');\n await fs.rename(tmp, file);\n}\n\nfunction parseRefKey(key: string): MetaRef | null {\n const parts = key.split('/');\n if (parts.length !== 3) return null;\n return {\n org: parts[0]!,\n type: parts[1]! as MetadataType,\n name: parts[2]!,\n };\n}\n\n/**\n * Wrap a Promise<AsyncIterable<T>> as a sync-returning AsyncIterable<T>.\n * The first `.next()` awaits the promise.\n */\nfunction deferredIterable<T>(promise: Promise<AsyncIterable<T>>): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator]() {\n let inner: AsyncIterator<T> | null = null;\n return {\n async next() {\n if (!inner) {\n const iterable = await promise;\n inner = iterable[Symbol.asyncIterator]();\n }\n return inner.next();\n },\n async return(value?: unknown) {\n if (!inner) {\n const iterable = await promise;\n inner = iterable[Symbol.asyncIterator]();\n }\n if (inner.return) return inner.return(value);\n return { value: undefined, done: true };\n },\n } as AsyncIterator<T>;\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Disk layout helpers — see ADR-0008 §10 PR-4 / packages/metadata-fs README.\n *\n * <root>/<type>/<name>.json — canonical body\n * <root>/.objectstack/.log/main.jsonl — append-only change log\n */\n\nimport path from 'node:path';\nimport type { MetadataType } from '@objectstack/metadata-core';\n\nexport interface FsLayout {\n /** Absolute path to the metadata root. */\n root: string;\n}\n\nexport function itemPath(layout: FsLayout, type: MetadataType, name: string): string {\n return path.join(layout.root, type, `${name}.json`);\n}\n\nexport function typeDir(layout: FsLayout, type: MetadataType): string {\n return path.join(layout.root, type);\n}\n\nexport function logDir(layout: FsLayout): string {\n return path.join(layout.root, '.objectstack', '.log');\n}\n\nexport function logFile(layout: FsLayout): string {\n // Single change log per filesystem root (branching is a Git concern,\n // not a metadata-layer concern).\n return path.join(logDir(layout), `main.jsonl`);\n}\n\n/** Parse a path like \".../view/case_grid.json\" into {type, name}. */\nexport function parseItemPath(\n layout: FsLayout,\n absPath: string,\n): { type: string; name: string } | null {\n const rel = path.relative(layout.root, absPath);\n if (rel.startsWith('..') || rel.startsWith('.objectstack')) return null;\n const segments = rel.split(path.sep);\n if (segments.length !== 2) return null;\n const type = segments[0]!;\n const file = segments[1]!;\n if (!file.endsWith('.json')) return null;\n const name = file.slice(0, -'.json'.length);\n return { type, name };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Append-only JSONL change log writer / reader. Each line is a single\n * `MetadataEvent` serialized via `JSON.stringify`.\n *\n * Durability strategy\n * ───────────────────\n * - Append with `O_APPEND` semantics (Node's `fs.appendFile` is\n * atomic for sub-PIPE_BUF-sized writes; events are well under 4 KiB).\n * - Read by streaming the file line-by-line and JSON.parse-ing each.\n * - On a corrupt line we skip and continue — the body files are the\n * source of truth; the log is a denormalised history index.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport readline from 'node:readline';\nimport { createReadStream, existsSync } from 'node:fs';\nimport type { MetadataEvent } from '@objectstack/metadata-core';\n\nexport class JsonlLog {\n constructor(private readonly file: string) {}\n\n async append(evt: MetadataEvent): Promise<void> {\n await fs.mkdir(path.dirname(this.file), { recursive: true });\n await fs.appendFile(this.file, JSON.stringify(evt) + '\\n', 'utf8');\n }\n\n /** Read all events in seq order (i.e. file order). */\n async *readAll(): AsyncIterable<MetadataEvent> {\n if (!existsSync(this.file)) return;\n const rl = readline.createInterface({\n input: createReadStream(this.file, { encoding: 'utf8' }),\n crlfDelay: Infinity,\n });\n try {\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n yield JSON.parse(line) as MetadataEvent;\n } catch {\n // Skip corrupt line.\n }\n }\n } finally {\n rl.close();\n }\n }\n\n /** Return the highest seq number in the log, or 0 if empty. */\n async highestSeq(): Promise<number> {\n let max = 0;\n for await (const evt of this.readAll()) {\n if (typeof evt.seq === 'number' && evt.seq > max) max = evt.seq;\n }\n return max;\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Mutex / event-broker primitives used by FileSystemRepository.\n *\n * `KeyedMutex` serializes operations on the same key (refKey). The\n * broker re-uses the same manual-AsyncIterator pattern as\n * InMemoryRepository so that consumer `return()` reliably unblocks.\n */\n\nimport type { MetadataEvent, WatchFilter } from '@objectstack/metadata-core';\n\nexport class KeyedMutex {\n private readonly tails = new Map<string, Promise<unknown>>();\n\n async run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const prev = this.tails.get(key) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n // Save the swallowed-error tail so successive runs don't reject on\n // an unrelated prior failure.\n const swallowed = next.catch(() => undefined);\n this.tails.set(key, swallowed);\n try {\n return await next;\n } finally {\n // Best-effort cleanup: drop the entry if nothing newer was queued.\n if (this.tails.get(key) === swallowed) {\n this.tails.delete(key);\n }\n }\n }\n}\n\n/**\n * One live `watch()` subscription, as a record rather than a bare event sink.\n *\n * Both halves live together because SHUTDOWN NEEDS THE SECOND ONE. A registry\n * of event sinks can only express shutdown as \"send an event\", and an event is\n * precisely what a filtered or numeric-`since` subscriber is entitled to drop\n * — and delivering one has never ended an iterator anyway. See invariant 8 in\n * `@objectstack/metadata-core`'s `repository.ts` (#11021, #11127).\n */\nexport interface BrokerSubscriber {\n filter: WatchFilter;\n closed: boolean;\n push(evt: MetadataEvent): void;\n /**\n * Ends this subscription's iterator: settles a parked `next()` with\n * `{ done: true }` and no value, and unregisters. The SAME routine\n * `iterator.return()` runs, so a consumer that breaks its loop and a\n * consumer whose repository shut down under it observe the same thing.\n */\n terminate(): void;\n}\n\nexport interface EventBroker {\n subscribe(sub: BrokerSubscriber): void;\n unsubscribe(sub: BrokerSubscriber): void;\n publish(evt: MetadataEvent): void;\n /**\n * Terminate every live subscription. This is what `FileSystemRepository`'s\n * repository-level `close()` owes a pending iterator (#11127): before it\n * existed, `close()` retired the chokidar watcher and the resync sweep and\n * stopped there, so the source that could settle a parked `next()` was gone\n * while the subscriber stayed registered with nothing left to settle it.\n *\n * Idempotent, and a no-op when nothing is watching.\n */\n terminateAll(): void;\n}\n\nexport function createBroker(matches: (evt: MetadataEvent, filter: WatchFilter) => boolean): EventBroker {\n const subs = new Set<BrokerSubscriber>();\n return {\n subscribe: (s) => { subs.add(s); },\n unsubscribe: (s) => { subs.delete(s); },\n publish: (evt) => {\n for (const s of subs) {\n if (s.closed) continue;\n if (!matches(evt, s.filter)) continue;\n s.push(evt);\n }\n },\n terminateAll: () => {\n // Snapshot and clear BEFORE terminating: `terminate()` unregisters\n // itself, and mutating a Set under its own iteration is how the second\n // subscriber gets skipped.\n const snapshot = Array.from(subs);\n subs.clear();\n for (const s of snapshot) {\n try {\n s.terminate();\n } catch {\n /* one wedged consumer must not strand the rest */\n }\n }\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Manual `AsyncIterator` factory for `repo.watch()`. Mirrors the\n * pattern used in `@objectstack/metadata-core`'s `InMemoryRepository`:\n * async generators do NOT run `finally` when paused on an unresolved\n * `await`, so we cannot use them to implement `watch()`.\n */\n\nimport type { MetadataEvent, WatchFilter } from '@objectstack/metadata-core';\nimport { type EventBroker, type BrokerSubscriber } from './sync.js';\n\nexport interface CreateWatchIteratorArgs {\n filter: WatchFilter;\n since: number | undefined;\n replay: MetadataEvent[];\n broker: EventBroker;\n /** Returns true if `evt.ref` matches `filter`. */\n matches: (evt: MetadataEvent, filter: WatchFilter) => boolean;\n branchKeyOf: (evt: MetadataEvent) => string;\n /**\n * Checked ONCE, immediately after this subscription is registered. True\n * means the repository shut down while `watch()`'s deferred log replay was\n * still in flight, so this subscription arrived after `close()` had already\n * swept the broker. It is terminated on arrival rather than left parked on a\n * broker nobody will publish to or drain again (#11127).\n */\n arrivesClosed?: () => boolean;\n}\n\nexport function createWatchIterable(\n args: CreateWatchIteratorArgs,\n): AsyncIterable<MetadataEvent> {\n const queue: MetadataEvent[] = [];\n let waiter: ((evt: IteratorResult<MetadataEvent>) => void) | null = null;\n let closed = false;\n const delivered = new Set<string>();\n const evtKey = (e: MetadataEvent) => `${args.branchKeyOf(e)}#${e.seq}`;\n\n const subscriber: BrokerSubscriber = {\n filter: args.filter,\n closed: false,\n // Assigned below, once `close` exists. Termination and the consumer's own\n // `return()` are ONE routine, deliberately: invariant 8 requires shutdown\n // to be indistinguishable from `iterator.return()`.\n terminate: () => undefined,\n push: (evt) => {\n if (subscriber.closed) return;\n const k = evtKey(evt);\n if (delivered.has(k)) return;\n if (waiter) {\n delivered.add(k);\n const w = waiter;\n waiter = null;\n w({ value: clone(evt), done: false });\n } else {\n queue.push(evt);\n }\n },\n };\n args.broker.subscribe(subscriber);\n\n const replay = [...args.replay].sort((a, b) => a.seq - b.seq);\n let replayIdx = 0;\n\n const drain = (): IteratorResult<MetadataEvent> | null => {\n while (replayIdx < replay.length) {\n const evt = replay[replayIdx++]!;\n if (typeof args.since === 'number' && evt.seq <= args.since) continue;\n const k = evtKey(evt);\n if (delivered.has(k)) continue;\n delivered.add(k);\n return { value: clone(evt), done: false };\n }\n while (queue.length > 0) {\n const evt = queue.shift()!;\n const k = evtKey(evt);\n if (delivered.has(k)) continue;\n delivered.add(k);\n return { value: clone(evt), done: false };\n }\n return null;\n };\n\n const close = (): IteratorResult<MetadataEvent> => {\n if (!closed) {\n closed = true;\n subscriber.closed = true;\n args.broker.unsubscribe(subscriber);\n if (waiter) {\n const w = waiter;\n waiter = null;\n w({ value: undefined, done: true });\n }\n }\n return { value: undefined, done: true };\n };\n\n // The terminator `repo.close()` runs. Same routine as `return()` below.\n subscriber.terminate = close;\n\n // Shutdown that landed while the deferred log replay was in flight — this\n // subscription missed the sweep, so it terminates on arrival (#11127).\n if (args.arrivesClosed?.()) close();\n\n const iterator: AsyncIterator<MetadataEvent> = {\n next: () => {\n if (closed) return Promise.resolve({ value: undefined, done: true });\n const immediate = drain();\n if (immediate) return Promise.resolve(immediate);\n return new Promise<IteratorResult<MetadataEvent>>((resolve) => {\n waiter = resolve;\n });\n },\n return: () => Promise.resolve(close()),\n throw: (err) => {\n close();\n return Promise.reject(err);\n },\n };\n return { [Symbol.asyncIterator]: () => iterator };\n}\n\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n"],"mappings":"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","names":["fs","existsSync","path","path","path","existsSync","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/repository.ts","../src/layout.ts","../src/jsonl-log.ts","../src/sync.ts","../src/watch-iterable.ts"],"mappings":"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","names":["fs","existsSync","path","path","path","existsSync","fs"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/metadata-fs",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.4.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "FileSystemRepository: Node-only Repository implementation backed by JSON files and a JSONL change log (ADR-0008).",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"chokidar": "^5.0.0",
|
|
34
|
-
"@objectstack/metadata-core": "17.
|
|
34
|
+
"@objectstack/metadata-core": "17.4.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^26.2.0",
|