Zip members were live-only: expandable while the source was connected, but the workspace snapshot dropped the archive (.zip became a plain file), so a classification made inside one vanished on reopen — and copy couldn't extract it anyway (it tried to walk the archive path as a real directory). Now zips are first-class: - snapshotTree/loadSnapshot persist the scanned archive subtree — zip-root + virtual folders + members carry isVirtual/zipPath/zipEntryPath, so the tree rebuilds on reopen and assignments inside an archive survive. An archive that was never opened persists as a lazy 'zip' node that reopens on demand. - scanner.ensureZipLoaded(rootHandle, zipPath) reloads an archive from the workspace root when the in-memory cache is cold (post-restore); scanZipNode falls back to it when a restored zip node has no live file object. - copy.js reads a member via scanner.extractZipMember (Blob from the archive) instead of a non-existent file handle; preview.js reloads the archive for a restored member before opening it. This also reconciles export/import with the snapshot: both now keep zip members, so a round-trip no longer leaves dangling in-archive assignments. Tests: zip subtree snapshot round-trip; copy extracts a member to the output (45). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| app.js | ||
| classify.js | ||
| copy.js | ||
| dnd.js | ||
| excel.js | ||
| filter.js | ||
| persist.js | ||
| preview.js | ||
| resize.js | ||
| scanner.js | ||
| selection.js | ||
| sort.js | ||
| spreadsheet.js | ||
| store.js | ||
| target-tree.js | ||
| tree.js | ||
| utils.js | ||
| validator.js | ||
| workspace.js | ||