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:
@@ -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. */
|
||||
|
||||
@@ -164,3 +164,24 @@ describe('virtual file system', () => {
|
||||
expect(fileSystem.upgradeLegacyDefaultImages()).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a file system's revision", () => {
|
||||
it('changes with every change, a removal too, and not with a reading', () => {
|
||||
const files = new VirtualFileSystem();
|
||||
const seen = [files.revision];
|
||||
files.createDirectory('/a');
|
||||
seen.push(files.revision);
|
||||
files.writeTextFile('/a/b.txt', 'x');
|
||||
seen.push(files.revision);
|
||||
files.renameInPlace('/a/b.txt', 'c.txt');
|
||||
seen.push(files.revision);
|
||||
files.deleteItem('/a/c.txt');
|
||||
seen.push(files.revision);
|
||||
files.allEntries();
|
||||
files.contains('/a');
|
||||
seen.push(files.revision);
|
||||
expect(new Set(seen.slice(0, 5)).size).toBe(5);
|
||||
expect(seen[5]).toBe(seen[4]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user