Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions packages/sdk/src/adapters/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class FsAdapter implements PersistAdapter {
private readonly root: string;
private readonly maxVersions: number;
private errorHandlers: Array<(e: PersistErrorEvent) => void> = [];
private readonly inflightWrites = new Set<Promise<void>>();
private versionCounter = 0;

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

async write(path: string, content: string): Promise<void> {
const p = this.doWrite(path, content);
this.inflightWrites.add(p);
try {
await p;
} finally {
this.inflightWrites.delete(p);
}
}

private async doWrite(path: string, content: string): Promise<void> {
try {
const abs = this.abs(path);
await mkdir(dirname(abs), { recursive: true });
Expand All @@ -42,7 +54,9 @@ class FsAdapter implements PersistAdapter {
}
}

async flush(): Promise<void> {}
async flush(): Promise<void> {
await Promise.all([...this.inflightWrites]);
}

async listVersions(path: string): Promise<PersistVersionEntry[]> {
const dir = this.versionsDir(path);
Expand Down Expand Up @@ -92,7 +106,8 @@ class FsAdapter implements PersistAdapter {
private async appendVersion(path: string, content: string): Promise<void> {
const dir = this.versionsDir(path);
await mkdir(dir, { recursive: true });
const key = String(Date.now());
// Pad counter to 6 digits so lexicographic sort = insertion order within same ms.
const key = `${Date.now()}_${String(this.versionCounter++).padStart(6, "0")}`;
await writeFile(join(dir, `${key}.html`), content, "utf8");
// prune oldest beyond maxVersions
const all = (await readdir(dir)).filter((f) => f.endsWith(".html")).sort();
Expand Down
9 changes: 9 additions & 0 deletions packages/sdk/src/adapters/persistAdapter.contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
* runPersistAdapterContract("s3", () => createS3Adapter({ bucket, prefix }))
*/

import { mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, it, expect, vi } from "vitest";
import { createMemoryAdapter } from "./memory.js";
import { createFsAdapter } from "./fs.js";
import type { PersistAdapter } from "./types.js";

export function runPersistAdapterContract(
Expand Down Expand Up @@ -126,3 +130,8 @@ export function runPersistAdapterContract(

// Run the suite against the memory adapter immediately
runPersistAdapterContract("memory", createMemoryAdapter);

// Run against the fs adapter — each test gets an isolated tmpdir
runPersistAdapterContract("fs", () =>
createFsAdapter({ root: mkdtempSync(join(tmpdir(), "hf-fs-test-")) }),
);
Loading