feat(browse): navigate into a .zip via the server, no whole-zip download
When browse runs against zddc-server, expanding a top-level .zip now fetches "<…>.zip/" as a normal directory listing (the server extracts members on demand) instead of downloading the entire archive and parsing it with JSZip in the browser. Members open/preview via their real server URLs like any file. Nested zips (a .zip inside a .zip) and FS-API (offline) mode keep the existing JSZip path; offline gets migrated to a shared adapter in the next change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5e4d4fefb3
commit
735fed89c2
1 changed files with 31 additions and 6 deletions
|
|
@ -280,18 +280,43 @@
|
||||||
// table); the tree.setSort() method still works but only via
|
// table); the tree.setSort() method still works but only via
|
||||||
// programmatic callers — there's no UI for changing sort yet.
|
// programmatic callers — there's no UI for changing sort yet.
|
||||||
|
|
||||||
|
// True when this zip node lives inside another zip (so its bytes
|
||||||
|
// can't be fetched as a standalone server resource — we go through
|
||||||
|
// the parent JSZip / inner-zip download path instead). In server
|
||||||
|
// mode the URL of a zip-member-inside-a-zip contains ".zip/"; in
|
||||||
|
// FS-API mode zipParentId is set.
|
||||||
|
function zipNestedInsideZip(node) {
|
||||||
|
if (node.zipParentId != null) return true;
|
||||||
|
if (state.source === 'server') {
|
||||||
|
return pathFor(node).toLowerCase().indexOf('.zip/') !== -1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Load a folder's children (lazy; idempotent re-loads). Dispatches
|
// Load a folder's children (lazy; idempotent re-loads). Dispatches
|
||||||
// by node kind:
|
// by node kind:
|
||||||
// - regular folder → server JSON listing OR FS-API enumeration
|
// - regular folder → server JSON listing OR FS-API enumeration
|
||||||
// - zip file → fetch+JSZip; entries become virtual children
|
// - top-level zip, server mode → server's virtual-directory listing
|
||||||
|
// of the zip's members (no whole-zip
|
||||||
|
// download — zddc-server extracts on demand)
|
||||||
|
// - zip otherwise → fetch+JSZip; entries become virtual children
|
||||||
// - zip child dir → already-listed entries from the parent zip
|
// - zip child dir → already-listed entries from the parent zip
|
||||||
// (zips are enumerated whole, so child dirs
|
// (the whole zip was enumerated when it
|
||||||
// are pre-populated when the zip expands)
|
// expanded, so child dirs are pre-seeded)
|
||||||
async function loadChildren(node) {
|
async function loadChildren(node) {
|
||||||
if (node.loaded) return;
|
if (node.loaded) return;
|
||||||
try {
|
try {
|
||||||
if (node.isZip) {
|
if (node.isZip) {
|
||||||
|
if (state.source === 'server' && !zipNestedInsideZip(node)) {
|
||||||
|
// zddc-server serves "<…>.zip/" as a virtual
|
||||||
|
// directory: GET it as a listing, GET a member URL
|
||||||
|
// to extract just that file. Same shape as any
|
||||||
|
// server directory, so no JSZip on the client.
|
||||||
|
setChildren(node.id,
|
||||||
|
await loader.fetchServerChildren(pathFor(node) + '/'));
|
||||||
|
} else {
|
||||||
await loadZipChildren(node);
|
await loadZipChildren(node);
|
||||||
|
}
|
||||||
} else if (node._zipSyntheticDir) {
|
} else if (node._zipSyntheticDir) {
|
||||||
// Synthetic dir node materialized when a zip's entry
|
// Synthetic dir node materialized when a zip's entry
|
||||||
// list referenced "a/b/file" but had no "a/" entry.
|
// list referenced "a/b/file" but had no "a/" entry.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue