Every open passes through a real loading window — the walk moves off the main actor
Phase 2 of the decision surface: the pre-snapshot loading state ruled 2026-07-29 (02 § Launch and window lifecycle), built. The board window appears immediately at its saved frame, titled with the registry record's cached name, its content a centered spinner behind an injectable ~200ms grace — no skeletons, and the first snapshot snaps in place. The tree walk runs off-main via BoardStoreRegistry.acquireOffMain (per-board single-flight keyed by file identity — concurrent opens of one root share a walk, restoration of many boards is genuinely parallel), landing in BoardStore's new designated init(rootURL:loaded:); the self-walking init survives as a convenience for its ~470 callers. ⌘W during the walk is real: configureWindow split into a loading half (frame restore, frame tracking, close interception — installed before the walk) and a store half (toolbar, widget, hideTitle, undo — installed at the snap), and the walk lives in an explicitly held BoardOpenWalk so the user's close and SwiftUI's teardown end in one cancel(). Cancellation is discard-on-completion: nil from acquireOffMain means nothing was built, nothing retained, and no open-now flag was ever set. Failure keeps today's sequence exactly: record the launch failure, welcome's row carries it, the window retires. Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -178,6 +178,31 @@ struct BoardStoreTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test("A store built from a pre-walked result is the store the walking init would have built")
|
||||
func prewalkedInitMatchesTheWalkingInit() async throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
|
||||
// The two inits the board window's loading state put side by side: the walk on this actor,
|
||||
// and the same walk run somewhere else and handed over (`BoardStoreRegistry.acquireOffMain`
|
||||
// runs it on a detached task). If these ever disagreed, an open would show a different board
|
||||
// depending on which actor walked it.
|
||||
let walkedHere = try BoardStore(rootURL: fixture.root)
|
||||
let result = try BoardLoader.load(boardRoot: fixture.root)
|
||||
let walkedElsewhere = BoardStore(rootURL: fixture.root, loaded: result)
|
||||
|
||||
#expect(walkedElsewhere.rootURL == walkedHere.rootURL)
|
||||
#expect(walkedElsewhere.snapshot == walkedHere.snapshot)
|
||||
#expect(walkedElsewhere.loadWarnings == walkedHere.loadWarnings)
|
||||
#expect(walkedElsewhere.defects.count == walkedHere.defects.count)
|
||||
// The rest of the opening posture, which is what a second init could quietly get wrong.
|
||||
#expect(walkedElsewhere.reloadFailure == nil)
|
||||
#expect(walkedElsewhere.readOnlyLock == nil)
|
||||
#expect(!walkedElsewhere.isReadOnly)
|
||||
#expect(walkedElsewhere.selection == .empty)
|
||||
#expect(walkedElsewhere.reloadGeneration == 0)
|
||||
}
|
||||
|
||||
// MARK: Reloading
|
||||
|
||||
@Test("A foreign tree change reloads and the snapshot shows the external edit")
|
||||
|
||||
Reference in New Issue
Block a user