expo-tiddlywiki-filesystem-android-external-storage 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -568,6 +568,10 @@ class ExternalStorageModule : Module() {
568
568
  GitHelper.gitPush(gitRootDir, remoteName, localBranch, remoteBranch, force, headers)
569
569
  }
570
570
 
571
+ AsyncFunction("gitCreateBundle") { gitRootDir: String, remoteName: String, localBranch: String, remoteBranch: String ->
572
+ GitHelper.gitCreateBundle(gitRootDir, remoteName, localBranch, remoteBranch)
573
+ }
574
+
571
575
  AsyncFunction("gitFetch") { gitRootDir: String, remoteName: String, branch: String, headers: String? ->
572
576
  GitHelper.gitFetch(gitRootDir, remoteName, branch, headers)
573
577
  }
@@ -369,6 +369,80 @@ internal object GitHelper {
369
369
  return result.toString()
370
370
  }
371
371
 
372
+ // ─── Git bundle creation (for push via HTTP POST) ───────────────
373
+
374
+ /**
375
+ * Create a git bundle containing commits on localBranch that are ahead of
376
+ * remoteName/remoteBranch. Returns a base64-encoded bundle string, or
377
+ * a JSON error if there's nothing to bundle.
378
+ *
379
+ * This avoids JGit's broken SmartHttpPushConnection (which throws
380
+ * "Starting read stage without written request data pending is not supported"
381
+ * due to MultiRequestService not marking finalRequest=true for push).
382
+ *
383
+ * The bundle is sent by the JS layer via HTTP POST to the desktop's
384
+ * /receive-bundle endpoint, which runs `git fetch <bundle> master:mobile-incoming`.
385
+ */
386
+ fun gitCreateBundle(
387
+ gitRootDir: String,
388
+ remoteName: String,
389
+ localBranch: String,
390
+ remoteBranch: String
391
+ ): String {
392
+ val result = JSONObject()
393
+ try {
394
+ val repo = openRepo(gitRootDir)
395
+ try {
396
+ ensureProtocolV0(repo)
397
+ val localRef = repo.resolve("refs/heads/$localBranch")
398
+ ?: throw Exception("Local branch $localBranch not found")
399
+ val remoteRef = repo.resolve("refs/remotes/$remoteName/$remoteBranch")
400
+
401
+ val revWalk = RevWalk(repo)
402
+ try {
403
+ val localCommit = revWalk.parseCommit(localRef)
404
+
405
+ val bundleWriter = org.eclipse.jgit.transport.BundleWriter(repo)
406
+
407
+ // Include the local branch tip
408
+ bundleWriter.include("refs/heads/$localBranch", localRef)
409
+
410
+ // If we have a remote tracking ref, mark it as assumed (prerequisite).
411
+ // The receiving end must have this commit.
412
+ if (remoteRef != null) {
413
+ val remoteCommit = revWalk.parseCommit(remoteRef)
414
+ bundleWriter.assume(remoteCommit)
415
+ }
416
+
417
+ // Configure pack for low memory (Android)
418
+ val packConfig = org.eclipse.jgit.storage.pack.PackConfig(repo)
419
+ bundleWriter.setPackConfig(packConfig)
420
+
421
+ // Write bundle to memory
422
+ val baos = ByteArrayOutputStream()
423
+ bundleWriter.writeBundle(org.eclipse.jgit.lib.NullProgressMonitor.INSTANCE, baos)
424
+
425
+ val bundleBytes = baos.toByteArray()
426
+ val base64Bundle = Base64.encodeToString(bundleBytes, Base64.NO_WRAP)
427
+
428
+ result.put("ok", true)
429
+ result.put("bundle", base64Bundle)
430
+ result.put("bundleSize", bundleBytes.size)
431
+ android.util.Log.i("GitBundle", "Bundle created: ${bundleBytes.size} bytes, local=$localBranch remote=$remoteName/$remoteBranch")
432
+ } finally {
433
+ revWalk.close()
434
+ }
435
+ } finally {
436
+ repo.close()
437
+ }
438
+ } catch (e: Exception) {
439
+ result.put("ok", false)
440
+ result.put("error", e.message ?: "Unknown bundle error")
441
+ android.util.Log.e("GitBundle", "Bundle creation failed: ${e.message}", e)
442
+ }
443
+ return result.toString()
444
+ }
445
+
372
446
  // ─── Git fetch (JGit) ───────────────────────────────────────────
373
447
 
374
448
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-tiddlywiki-filesystem-android-external-storage",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "Expo native module for TidGi-Mobile: filesystem I/O + TiddlyWiki .tid/.meta/.json batch parsing + git status in Kotlin (Android) and Swift (iOS)",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",