feat(sim): F4.6f1 what a run leaves goes back into the document

The oracle SaveAfterRunRun saves Java's project after a run. The room writes
what a run leaves that Java keeps - files, running servers, virtual hosts,
mail servers' domains and accounts, mail programs' accounts and folders,
firewalls, DHCP clients' addresses - into the document as origin 'sim', at
most once a second, after each action and at the stop; writeRunState writes
only what differs. The command line now goes on in a folder made before a
restart, as Java's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 17:05:11 +00:00
co-authored by Claude Opus 5.5
parent 11f13bca84
commit 3d6655e736
15 changed files with 705 additions and 22 deletions
@@ -213,11 +213,17 @@ export function fileContentOfJavaType(rawType: string, content: string, path: st
export class VirtualFileSystem {
private store: Store;
private revisionValue = 0;
constructor() {
this.store = new Map([[keyOf('/'), { path: '/', content: { kind: 'directory' } }]]);
}
/** Counts the changes: different after each one (the simulation room writes a file system back when it changed). */
get revision(): number {
return this.revisionValue;
}
/** `init(entries:)`: shallow entries first; each parent must exist. */
static fromEntries(entries: readonly VirtualFileEntry[]): VirtualFileSystem {
const fileSystem = new VirtualFileSystem();
@@ -460,10 +466,12 @@ export class VirtualFileSystem {
const key = keyOf(path);
const existing = this.store.get(key);
this.store.set(key, { path: existing?.path ?? path, content });
this.revisionValue += 1;
}
private delete(path: string): void {
this.store.delete(keyOf(path));
this.revisionValue += 1;
}
private transaction(change: (candidate: VirtualFileSystem) => void): void {
@@ -471,6 +479,7 @@ export class VirtualFileSystem {
change(candidate);
candidate.validateQuotas();
this.store = candidate.store;
this.revisionValue += 1;
}
private persistedEntryCount(): number {
@@ -538,6 +547,7 @@ export class VirtualFileSystem {
candidate.set(destination, content);
candidate.validateQuotas();
this.store = candidate.store;
this.revisionValue += 1;
}
/** The subtree at `sourcePath`, shallow first. */