Skip to content

Commit a531d34

Browse files
committed
fix(sdk): fs adapter flush() tracks in-flight writes; add to T13 contract suite
1 parent def5462 commit a531d34

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

packages/sdk/src/adapters/fs.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class FsAdapter implements PersistAdapter {
1616
private readonly root: string;
1717
private readonly maxVersions: number;
1818
private errorHandlers: Array<(e: PersistErrorEvent) => void> = [];
19+
private readonly inflightWrites = new Set<Promise<void>>();
20+
private versionCounter = 0;
1921

2022
constructor(opts: FsAdapterOptions) {
2123
this.root = opts.root;
@@ -32,6 +34,16 @@ class FsAdapter implements PersistAdapter {
3234
}
3335

3436
async write(path: string, content: string): Promise<void> {
37+
const p = this.doWrite(path, content);
38+
this.inflightWrites.add(p);
39+
try {
40+
await p;
41+
} finally {
42+
this.inflightWrites.delete(p);
43+
}
44+
}
45+
46+
private async doWrite(path: string, content: string): Promise<void> {
3547
try {
3648
const abs = this.abs(path);
3749
await mkdir(dirname(abs), { recursive: true });
@@ -42,7 +54,9 @@ class FsAdapter implements PersistAdapter {
4254
}
4355
}
4456

45-
async flush(): Promise<void> {}
57+
async flush(): Promise<void> {
58+
await Promise.all([...this.inflightWrites]);
59+
}
4660

4761
async listVersions(path: string): Promise<PersistVersionEntry[]> {
4862
const dir = this.versionsDir(path);
@@ -92,7 +106,8 @@ class FsAdapter implements PersistAdapter {
92106
private async appendVersion(path: string, content: string): Promise<void> {
93107
const dir = this.versionsDir(path);
94108
await mkdir(dir, { recursive: true });
95-
const key = String(Date.now());
109+
// Pad counter to 6 digits so lexicographic sort = insertion order within same ms.
110+
const key = `${Date.now()}_${String(this.versionCounter++).padStart(6, "0")}`;
96111
await writeFile(join(dir, `${key}.html`), content, "utf8");
97112
// prune oldest beyond maxVersions
98113
const all = (await readdir(dir)).filter((f) => f.endsWith(".html")).sort();

packages/sdk/src/adapters/persistAdapter.contract.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
* runPersistAdapterContract("s3", () => createS3Adapter({ bucket, prefix }))
1010
*/
1111

12+
import { mkdtempSync } from "node:fs";
13+
import { tmpdir } from "node:os";
14+
import { join } from "node:path";
1215
import { describe, it, expect, vi } from "vitest";
1316
import { createMemoryAdapter } from "./memory.js";
17+
import { createFsAdapter } from "./fs.js";
1418
import type { PersistAdapter } from "./types.js";
1519

1620
export function runPersistAdapterContract(
@@ -126,3 +130,8 @@ export function runPersistAdapterContract(
126130

127131
// Run the suite against the memory adapter immediately
128132
runPersistAdapterContract("memory", createMemoryAdapter);
133+
134+
// Run against the fs adapter — each test gets an isolated tmpdir
135+
runPersistAdapterContract("fs", () =>
136+
createFsAdapter({ root: mkdtempSync(join(tmpdir(), "hf-fs-test-")) }),
137+
);

0 commit comments

Comments
 (0)