craft-native 0.0.246 → 0.0.247

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.
@@ -54,6 +54,7 @@ async function verifyMobileMediaCache(options) {
54
54
  const scratch = await mkdtemp(join(tmpdir(), "craft-media-probe-"));
55
55
  const bytes = new Uint8Array(await Bun.file(join(fixtures, "demo.mp4")).arrayBuffer());
56
56
  const counts = new Map;
57
+ const resumed = new Set;
57
58
  const timers = new Set;
58
59
  const server = Bun.listen({
59
60
  hostname: "0.0.0.0",
@@ -72,6 +73,20 @@ async function verifyMobileMediaCache(options) {
72
73
  const path = socket.data.request.split(" ")[1];
73
74
  const n = (counts.get(path) || 0) + 1;
74
75
  counts.set(path, n);
76
+ const from = Number(/^range:\s*bytes=(\d+)-\s*$/im.exec(socket.data.request)?.[1] ?? Number.NaN);
77
+ if (path === "/android/restart.mp4" && n > 1 && from > 0 && from < bytes.length) {
78
+ resumed.add(path);
79
+ socket.write(`HTTP/1.1 206 Partial Content\r
80
+ Content-Type: video/mp4\r
81
+ Content-Range: bytes ${from}-${bytes.length - 1}/${bytes.length}\r
82
+ Content-Length: ${bytes.length - from}\r
83
+ Connection: close\r
84
+ \r
85
+ `);
86
+ socket.write(bytes.subarray(from));
87
+ socket.end();
88
+ return;
89
+ }
75
90
  const empty = path.endsWith("/empty.mp4");
76
91
  const partial = path.endsWith("/partial.mp4");
77
92
  const cut = (path.endsWith("/broken.mp4") || path.endsWith("/restart.mp4")) && n === 1;
@@ -207,6 +222,7 @@ include(":app")`);
207
222
  `);
208
223
  await Bun.write(join(android, "gradle.properties"), `org.gradle.jvmargs=-Xmx768m
209
224
  org.gradle.workers.max=2
225
+ android.useAndroidX=true
210
226
  `);
211
227
  await Bun.write(join(app, "build.gradle.kts"), `plugins { id("com.android.application");
212
228
  id("org.jetbrains.kotlin.android") }
@@ -264,11 +280,13 @@ ${await Bun.file(join(fixtures, "media-cache.kt")).text()}`);
264
280
  if (counts.get("/android/restart.mp4") !== 1)
265
281
  throw new Error("Android process did not start interrupted download");
266
282
  await probe("recover");
283
+ if (!resumed.has("/android/restart.mp4"))
284
+ throw new Error("Android did not resume the interrupted download from its part file");
267
285
  if (counts.get("/android/slow.mp4") !== 1)
268
286
  throw new Error("Android duplicate fetch: keep did not coalesce");
269
287
  if (counts.get("/android/account/slow.mp4") !== 2)
270
288
  throw new Error("Android account switch did not start a fresh transfer");
271
- print("PASS: Android emulator interruption, restart, retry, prune and cached video decode");
289
+ print("PASS: Android emulator interruption, resumed restart, retry, prune and cached video decode");
272
290
  }
273
291
  }
274
292
  } finally {
@@ -98,8 +98,10 @@ class DownloadProbe : android.app.Instrumentation() {
98
98
  check(!keep(broken), "truncated transfer fails")
99
99
  check(CraftNativeMedia.local(targetContext, broken) == null, "truncated transfer is not playable cache")
100
100
  val root = CraftNativeMedia.file(targetContext, broken).parentFile!!
101
- check(root.listFiles()?.none { it.name.endsWith(".part") } != false, "failed transfer cleans staging files")
102
- check(keep(broken), "same URL retries successfully")
101
+ val brokenTarget = CraftNativeMedia.file(targetContext, broken)
102
+ check(root.listFiles()?.none { it.name.endsWith(".part") && it.name != "${brokenTarget.name}.part" } != false, "a failed transfer leaves only its own part, to resume")
103
+ check(keep(broken), "same URL retries successfully, at once")
104
+ check(root.listFiles()?.none { it.name.endsWith(".part") } != false, "a finished transfer leaves no staging files")
103
105
  check(!keep("$base/partial.mp4"), "unsolicited partial response is refused")
104
106
  check(!keep("$base/empty.mp4"), "empty file is refused")
105
107
  val slow = "$base/slow.mp4"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craft-native",
3
- "version": "0.0.246",
3
+ "version": "0.0.247",
4
4
  "type": "module",
5
5
  "description": "Build desktop apps with web languages - TypeScript SDK for Craft",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",