Skip to content

feat: native replacement for JSZip#2376

Open
RohitKushvaha01 wants to merge 9 commits into
Acode-Foundation:mainfrom
RohitKushvaha01:replace_jsZip
Open

feat: native replacement for JSZip#2376
RohitKushvaha01 wants to merge 9 commits into
Acode-Foundation:mainfrom
RohitKushvaha01:replace_jsZip

Conversation

@RohitKushvaha01

Copy link
Copy Markdown
Member

No description provided.

@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces the pure-JS jszip npm package with a native Cordova plugin (JsZip-Java) that offloads ZIP operations to Android's java.util.zip stack, eliminating the JavaScript heap burden for large archives.

  • New Cordova plugin (src/plugins/jszip-java/) introduces a Java backend (JsZip.java) that manages per-instance temp files in the Android cache directory, streams ZIP content to JS in 256 KB chunks, and includes path-traversal guards in both extractToDir and extractZipFileToDir.
  • Call-site migration in installPlugin.js and fileBrowser.js drops the import JSZip from \"jszip\" statement and switches to window.JSZip, which is injected synchronously by the Cordova plugin's <clobbers> directive before deviceready.
  • Previously reported bugs (lost this context in remove/folder, result.data access in generateAsync, and uncommented debug logging) are all addressed in this version."

Confidence Score: 5/5

Safe to merge; the core JS-to-Java bridge wiring is correct and the previously reported blocking bugs are fixed.

The three previously flagged blocking issues (this-context loss in remove/folder, result.data undefined in generateAsync, and uncommented debug logging) are all resolved. The two remaining findings are minor defensive hardening: a missing setTime on an effectively unreachable code path in generateZip, and a theoretical thread-pool race between the fire-and-forget create call and subsequent native operations. Neither causes observable failures under normal usage.

The JSZip constructor in src/plugins/jszip-java/www/JsZip.js and the directory-entry branch of generateZip in src/plugins/jszip-java/src/android/JsZip.java are worth a second look.

Important Files Changed

Filename Overview
src/plugins/jszip-java/www/JsZip.js New JS shim implementing the JSZip API over Cordova exec; previous this-context and result.data bugs are fixed; a narrow create→load race remains as a minor concern.
src/plugins/jszip-java/src/android/JsZip.java New Cordova plugin Java backend; implements create/addFile/load/generate/extract/destroy with temp-file buffering; path-traversal guard present; debug logging is commented out; ZipEntry timestamp is dropped when a directory path lacks a trailing slash (unreachable in practice via JS).
src/lib/installPlugin.js Replaces import JSZip from "jszip" with window.JSZip; all JSZip usage (loadAsync, files, .async) is compatible with the new plugin's API surface.
src/pages/fileBrowser/fileBrowser.js Replaces import JSZip from "jszip" with window.JSZip; both static loadAsync and instance-based new JSZip() usages match the new plugin's API.
src/plugins/jszip-java/plugin.xml Standard Cordova plugin manifest; clobbers window.JSZip so the shim is available synchronously before deviceready.
package.json Adds JsZip-Java local package and com.foxdebug.acode.rk.zip Cordova plugin; the jszip npm dependency was not removed (noted in a previous review comment).

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant JS as JS (JsZip.js)
    participant CB as Cordova Bridge
    participant TP as Thread Pool
    participant JV as JsZip.java

    Note over JS,JV: new JSZip() — fire-and-forget create
    JS->>CB: exec(null, null, JsZip, create, [id])
    CB->>TP: submit create task

    Note over JS,JV: loadAsync(data) — at least 2 microtask ticks later
    JS->>CB: exec(resolve, reject, JsZip, load, [id, payload, opts])
    CB->>TP: submit load task

    TP->>JV: createInstance(id) → instances.put(id, ...)
    TP->>JV: loadZip(id, ...) → instances.get(id) → OK

    Note over JS,JV: generateAsync — waits for all pending, then streams zip
    JS->>CB: exec(onResult, reject, JsZip, generate, [id, prefix, opts])
    CB->>TP: submit generateZip task
    TP->>JV: generateZip → streamFile 256 KB chunks with keepCallback
    JV-->>CB: PluginResult OK chunk x N keepCallback true
    CB-->>JS: result instanceof ArrayBuffer → chunks.push(result)
    JV-->>CB: PluginResult OK done true keepCallback false
    CB-->>JS: result.done → merge chunks → _convertOutput → resolve
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant JS as JS (JsZip.js)
    participant CB as Cordova Bridge
    participant TP as Thread Pool
    participant JV as JsZip.java

    Note over JS,JV: new JSZip() — fire-and-forget create
    JS->>CB: exec(null, null, JsZip, create, [id])
    CB->>TP: submit create task

    Note over JS,JV: loadAsync(data) — at least 2 microtask ticks later
    JS->>CB: exec(resolve, reject, JsZip, load, [id, payload, opts])
    CB->>TP: submit load task

    TP->>JV: createInstance(id) → instances.put(id, ...)
    TP->>JV: loadZip(id, ...) → instances.get(id) → OK

    Note over JS,JV: generateAsync — waits for all pending, then streams zip
    JS->>CB: exec(onResult, reject, JsZip, generate, [id, prefix, opts])
    CB->>TP: submit generateZip task
    TP->>JV: generateZip → streamFile 256 KB chunks with keepCallback
    JV-->>CB: PluginResult OK chunk x N keepCallback true
    CB-->>JS: result instanceof ArrayBuffer → chunks.push(result)
    JV-->>CB: PluginResult OK done true keepCallback false
    CB-->>JS: result.done → merge chunks → _convertOutput → resolve
Loading

Reviews (4): Last reviewed commit: "fix: issues" | Re-trigger Greptile

Comment thread src/plugins/jszip-java/www/JsZip.js Outdated
Comment thread src/plugins/jszip-java/src/android/JsZip.java Outdated
Comment thread src/plugins/jszip-java/src/android/JsZip.java Outdated
Comment thread src/plugins/jszip-java/src/android/JsZip.java Outdated
@RohitKushvaha01 RohitKushvaha01 marked this pull request as draft June 24, 2026 11:13
@RohitKushvaha01 RohitKushvaha01 marked this pull request as ready for review June 24, 2026 11:33
Comment thread src/plugins/jszip-java/www/JsZip.js
Comment thread src/plugins/jszip-java/www/JsZip.js Outdated
@RohitKushvaha01 RohitKushvaha01 moved this from Backlog to Done in The Code Board - Acode Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant