@appium/coresim 1.3.0 → 1.5.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/binding.gyp +7 -1
  3. package/lib/src/commands/process.d.ts.map +1 -1
  4. package/lib/src/commands/process.js +3 -4
  5. package/lib/src/commands/process.js.map +1 -1
  6. package/lib/src/commands/spawn.d.ts +9 -5
  7. package/lib/src/commands/spawn.d.ts.map +1 -1
  8. package/lib/src/commands/spawn.js +9 -5
  9. package/lib/src/commands/spawn.js.map +1 -1
  10. package/lib/src/commands/video-recording.d.ts +50 -0
  11. package/lib/src/commands/video-recording.d.ts.map +1 -0
  12. package/lib/src/commands/video-recording.js +98 -0
  13. package/lib/src/commands/video-recording.js.map +1 -0
  14. package/lib/src/commands/video-stream.d.ts +44 -0
  15. package/lib/src/commands/video-stream.d.ts.map +1 -0
  16. package/lib/src/commands/video-stream.js +240 -0
  17. package/lib/src/commands/video-stream.js.map +1 -0
  18. package/lib/src/index.d.ts +2 -1
  19. package/lib/src/index.d.ts.map +1 -1
  20. package/lib/src/index.js +1 -0
  21. package/lib/src/index.js.map +1 -1
  22. package/lib/src/native-simctl.d.ts +4 -0
  23. package/lib/src/native-simctl.d.ts.map +1 -1
  24. package/lib/src/native-simctl.js +9 -0
  25. package/lib/src/native-simctl.js.map +1 -1
  26. package/lib/src/types.d.ts +72 -0
  27. package/lib/src/types.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/prebuilds/darwin-arm64/@appium+coresim.node +0 -0
  30. package/src/commands/process.ts +3 -4
  31. package/src/commands/spawn.ts +9 -5
  32. package/src/commands/video-recording.ts +128 -0
  33. package/src/commands/video-stream.ts +274 -0
  34. package/src/coresim.mm +310 -4
  35. package/src/index.ts +4 -0
  36. package/src/native/sim_screenshot.h +10 -0
  37. package/src/native/sim_screenshot.mm +11 -6
  38. package/src/native/sim_video_recording.h +27 -0
  39. package/src/native/sim_video_recording.mm +87 -0
  40. package/src/native/sim_video_stream.h +61 -0
  41. package/src/native/sim_video_stream.mm +427 -0
  42. package/src/native-simctl.ts +10 -0
  43. package/src/types.ts +76 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [1.5.0](https://github.com/appium/coresim/compare/v1.4.0...v1.5.0) (2026-09-22)
2
+
3
+ ### Features
4
+
5
+ * Add video recording API ([#17](https://github.com/appium/coresim/issues/17)) ([d399403](https://github.com/appium/coresim/commit/d399403c1d329f303ab51726fa382313cf09ad0f))
6
+
7
+ ## [1.4.0](https://github.com/appium/coresim/compare/v1.3.0...v1.4.0) (2026-09-19)
8
+
9
+ ### Features
10
+
11
+ * resolve bare command names in spawnProcess against the runtime's bin dirs ([#16](https://github.com/appium/coresim/issues/16)) ([155654d](https://github.com/appium/coresim/commit/155654d1b2ac1235445cd511c0f7a0d49038bf26))
12
+
1
13
  ## [1.3.0](https://github.com/appium/coresim/compare/v1.2.1...v1.3.0) (2026-09-19)
2
14
 
3
15
  ### Features
package/binding.gyp CHANGED
@@ -13,7 +13,9 @@
13
13
  "src/native/tcc_privacy.mm",
14
14
  "src/native/sim_pasteboard.mm",
15
15
  "src/native/sim_process.mm",
16
- "src/native/sim_screenshot.mm"
16
+ "src/native/sim_screenshot.mm",
17
+ "src/native/sim_video_recording.mm",
18
+ "src/native/sim_video_stream.mm"
17
19
  ],
18
20
  "include_dirs": [
19
21
  "<!@(node -p \"require('node-addon-api').include\")"
@@ -42,9 +44,13 @@
42
44
  "OTHER_LDFLAGS": [
43
45
  "-framework", "Foundation",
44
46
  "-framework", "AppKit",
47
+ "-framework", "AVFoundation",
45
48
  "-framework", "CoreImage",
49
+ "-framework", "CoreMedia",
50
+ "-framework", "CoreVideo",
46
51
  "-framework", "ImageIO",
47
52
  "-framework", "IOSurface",
53
+ "-framework", "VideoToolbox",
48
54
  "-lsqlite3"
49
55
  ]
50
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/commands/process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAGhD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACvD,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACnD;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1F;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA6C/F"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/commands/process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAGhD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACvD,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACnD;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE1F;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA4C/F"}
@@ -20,10 +20,9 @@ export async function getRuntimeRootPath(udid) {
20
20
  */
21
21
  export async function listProcesses(udid) {
22
22
  return runCatchingAsync(async () => {
23
- // spawnProcess() resolves this against the guest runtime root itself (see CLAUDE.md) — the
24
- // guest runtime ships its own launchctl, distinct from the host's /bin/launchctl.
25
- const launchctlPath = '/bin/launchctl';
26
- const proc = await this.spawnProcess(udid, launchctlPath, { arguments: [launchctlPath, 'list'] });
23
+ // Bare name: spawnProcess() resolves it against the guest runtime's own bin dirs, distinct
24
+ // from the host's /bin/launchctl (see CLAUDE.md).
25
+ const proc = await this.spawnProcess(udid, 'launchctl', { arguments: ['launchctl', 'list'] });
27
26
  let stdout = '';
28
27
  let stderr = '';
29
28
  proc.stdout.on('data', (chunk) => {
@@ -1 +1 @@
1
- {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/commands/process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/commands/process.ts"],"names":[],"mappings":"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"}
@@ -39,11 +39,15 @@ export declare class SpawnedProcess extends EventEmitter<SpawnedProcessEvents> {
39
39
  * exit code/signal — see {@link SpawnedProcess}.
40
40
  *
41
41
  * @param udid — UDID of the target device
42
- * @param path — path to the executable to spawn, relative to the Simulator's own runtime root
43
- * (e.g. `/usr/bin/log`) — resolved and confined there, so this cannot be used to spawn an
44
- * arbitrary host executable. A leading `/` is tolerated (still resolved relative to the runtime
45
- * root, not the host's own `/`). Throws if `path` would resolve outside the runtime (e.g. via
46
- * `..`). Not auto-prepended to `options.arguments`.
42
+ * @param path — path to the executable to spawn. A bare name with no `/` (e.g. `launchctl`) is
43
+ * resolved by searching the Simulator runtime's standard bin dirs (`usr/bin`, `bin`, `usr/sbin`,
44
+ * `sbin`, `usr/local/bin`), mirroring `simctl spawn`'s own bare-name resolution — there's no way
45
+ * to query the guest's actual `$PATH`, so this is a fixed best-effort list, and throws if nothing
46
+ * matches. Anything containing `/` is instead resolved relative to the Simulator's own runtime
47
+ * root (e.g. `/usr/bin/log`) and confined there, so this cannot be used to spawn an arbitrary host
48
+ * executable. A leading `/` is tolerated (still resolved relative to the runtime root, not the
49
+ * host's own `/`). Throws if `path` would resolve outside the runtime (e.g. via `..`). Not
50
+ * auto-prepended to `options.arguments`.
47
51
  * @param options — see {@link SpawnOptions}
48
52
  * @returns a handle to the spawned process
49
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/commands/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAGhC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAG9C,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;KAC3F;CACF;AAYD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAOlE,QAAQ,CAAC,GAAG,EAAE,MAAM;IANtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC/B,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAQ;gBAG9B,GAAG,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM;IAiBlB,kEAAkE;IAClE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;OAKG;IACH,IAAI,CAAC,MAAM,GAAE,MAAM,CAAC,OAAO,GAAG,MAAkB,GAAG,OAAO;CAa3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,cAAc,CAAC,CA+BzB"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/commands/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAGhC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAG9C,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;KAC3F;CACF;AAYD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAOlE,QAAQ,CAAC,GAAG,EAAE,MAAM;IANtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC/B,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAQ;gBAG9B,GAAG,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM;IAiBlB,kEAAkE;IAClE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;OAKG;IACH,IAAI,CAAC,MAAM,GAAE,MAAM,CAAC,OAAO,GAAG,MAAkB,GAAG,OAAO;CAa3D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,cAAc,CAAC,CA+BzB"}
@@ -68,11 +68,15 @@ export class SpawnedProcess extends EventEmitter {
68
68
  * exit code/signal — see {@link SpawnedProcess}.
69
69
  *
70
70
  * @param udid — UDID of the target device
71
- * @param path — path to the executable to spawn, relative to the Simulator's own runtime root
72
- * (e.g. `/usr/bin/log`) — resolved and confined there, so this cannot be used to spawn an
73
- * arbitrary host executable. A leading `/` is tolerated (still resolved relative to the runtime
74
- * root, not the host's own `/`). Throws if `path` would resolve outside the runtime (e.g. via
75
- * `..`). Not auto-prepended to `options.arguments`.
71
+ * @param path — path to the executable to spawn. A bare name with no `/` (e.g. `launchctl`) is
72
+ * resolved by searching the Simulator runtime's standard bin dirs (`usr/bin`, `bin`, `usr/sbin`,
73
+ * `sbin`, `usr/local/bin`), mirroring `simctl spawn`'s own bare-name resolution — there's no way
74
+ * to query the guest's actual `$PATH`, so this is a fixed best-effort list, and throws if nothing
75
+ * matches. Anything containing `/` is instead resolved relative to the Simulator's own runtime
76
+ * root (e.g. `/usr/bin/log`) and confined there, so this cannot be used to spawn an arbitrary host
77
+ * executable. A leading `/` is tolerated (still resolved relative to the runtime root, not the
78
+ * host's own `/`). Throws if `path` would resolve outside the runtime (e.g. via `..`). Not
79
+ * auto-prepended to `options.arguments`.
76
80
  * @param options — see {@link SpawnOptions}
77
81
  * @returns a handle to the spawned process
78
82
  */
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/commands/spawn.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/commands/spawn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { NativeSimctl } from '../native-simctl.js';
2
+ import type { VideoRecordingOptions } from '../types.js';
3
+ declare module '../native-simctl.js' {
4
+ interface NativeSimctl {
5
+ startVideoRecording(udid: string, outputFile: string, options?: VideoRecordingOptions): Promise<void>;
6
+ stopVideoRecording(udid: string): Promise<void>;
7
+ isVideoRecording(udid: string): Promise<boolean>;
8
+ }
9
+ }
10
+ /**
11
+ * Starts recording the device's display to `outputFile` — the native equivalent of `simctl io
12
+ * <udid> recordVideo`. Resolves once the first frame has actually been recorded, so it's always
13
+ * safe to call {@link stopVideoRecording} immediately after. Only one recording may be active per
14
+ * device at a time; starting a second one while the first is still running rejects. Rejects with
15
+ * `NativeSimUnavailableError` if this CoreSimulator predates the private capture API — confirmed
16
+ * missing on Xcode 16.4's, present on Xcode 26.5+ (Apple documents no exact version floor).
17
+ *
18
+ * @param udid — UDID of the device to record; must be booted
19
+ * @param outputFile — filesystem path to write the video to; resolved against `process.cwd()` if
20
+ * relative, since the native layer requires an absolute path
21
+ * @param options — `displayId`, `codec`, `mask` — see {@link VideoRecordingOptions}
22
+ * @throws {Error} if a recording is already in progress for this device
23
+ */
24
+ export declare function startVideoRecording(this: NativeSimctl, udid: string, outputFile: string, options?: VideoRecordingOptions): Promise<void>;
25
+ /**
26
+ * Stops a recording previously started by {@link startVideoRecording} on the same device.
27
+ * Resolves once the video file has been finalized on disk and is safe to read. If `start` is still
28
+ * in flight (e.g. a concurrent caller stopping as soon as {@link isVideoRecording} turns `true`),
29
+ * waits for it to settle first — issuing the native stop call any earlier is a silent CoreSimulator
30
+ * race (see CLAUDE.md).
31
+ *
32
+ * Safe to call concurrently or to retry after a failure: every concurrent call for the same
33
+ * recording shares a single in-flight native stop call rather than each issuing its own (which
34
+ * could otherwise stop whatever *new* recording has since started on this device instead), and a
35
+ * failed stop — even one that failed before ever reaching the native recorder, e.g. a transient
36
+ * device-lookup error — leaves the recording tracked as still active so a retry can reach the
37
+ * native call rather than the caller losing the ability to stop it at all.
38
+ *
39
+ * @param udid — UDID of the device to stop recording
40
+ * @throws {Error} if no recording is currently in progress for this device
41
+ */
42
+ export declare function stopVideoRecording(this: NativeSimctl, udid: string): Promise<void>;
43
+ /**
44
+ * Whether a recording started by {@link startVideoRecording} is currently active for this device.
45
+ * Pure local state — no CoreSimulator dispatch — so this never rejects with a native error.
46
+ *
47
+ * @param udid — UDID of the device to check
48
+ */
49
+ export declare function isVideoRecording(this: NativeSimctl, udid: string): Promise<boolean>;
50
+ //# sourceMappingURL=video-recording.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-recording.d.ts","sourceRoot":"","sources":["../../../src/commands/video-recording.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,aAAa,CAAC;AAGvD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACtG,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAClD;CACF;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BxF;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF"}
@@ -0,0 +1,98 @@
1
+ import path from 'node:path';
2
+ import { runCatchingAsync } from '../utils/index.js';
3
+ // Tracks which devices currently have an active recording — module-level since the constraint (at
4
+ // most one per device) is CoreSimulator's own, not per-NativeSimctl-instance.
5
+ const activeRecordings = new Map();
6
+ /**
7
+ * Starts recording the device's display to `outputFile` — the native equivalent of `simctl io
8
+ * <udid> recordVideo`. Resolves once the first frame has actually been recorded, so it's always
9
+ * safe to call {@link stopVideoRecording} immediately after. Only one recording may be active per
10
+ * device at a time; starting a second one while the first is still running rejects. Rejects with
11
+ * `NativeSimUnavailableError` if this CoreSimulator predates the private capture API — confirmed
12
+ * missing on Xcode 16.4's, present on Xcode 26.5+ (Apple documents no exact version floor).
13
+ *
14
+ * @param udid — UDID of the device to record; must be booted
15
+ * @param outputFile — filesystem path to write the video to; resolved against `process.cwd()` if
16
+ * relative, since the native layer requires an absolute path
17
+ * @param options — `displayId`, `codec`, `mask` — see {@link VideoRecordingOptions}
18
+ * @throws {Error} if a recording is already in progress for this device
19
+ */
20
+ export async function startVideoRecording(udid, outputFile, options = {}) {
21
+ const key = udid.toLowerCase();
22
+ if (activeRecordings.has(key)) {
23
+ throw new Error(`A video recording is already in progress for device '${udid}'`);
24
+ }
25
+ const absoluteOutputFile = path.resolve(outputFile);
26
+ const startPromise = runCatchingAsync(async () => (await this._findDevice(udid)).startVideoRecording(absoluteOutputFile, options));
27
+ // Marked before the native call resolves, not after, so a concurrent startVideoRecording for the
28
+ // same device is rejected immediately instead of racing this one — rolled back below on failure.
29
+ const state = { start: startPromise };
30
+ activeRecordings.set(key, state);
31
+ try {
32
+ await startPromise;
33
+ }
34
+ catch (e) {
35
+ // Only clear our own entry — a concurrent stopVideoRecording (see below) may already have.
36
+ if (activeRecordings.get(key) === state) {
37
+ activeRecordings.delete(key);
38
+ }
39
+ throw e;
40
+ }
41
+ }
42
+ /**
43
+ * Stops a recording previously started by {@link startVideoRecording} on the same device.
44
+ * Resolves once the video file has been finalized on disk and is safe to read. If `start` is still
45
+ * in flight (e.g. a concurrent caller stopping as soon as {@link isVideoRecording} turns `true`),
46
+ * waits for it to settle first — issuing the native stop call any earlier is a silent CoreSimulator
47
+ * race (see CLAUDE.md).
48
+ *
49
+ * Safe to call concurrently or to retry after a failure: every concurrent call for the same
50
+ * recording shares a single in-flight native stop call rather than each issuing its own (which
51
+ * could otherwise stop whatever *new* recording has since started on this device instead), and a
52
+ * failed stop — even one that failed before ever reaching the native recorder, e.g. a transient
53
+ * device-lookup error — leaves the recording tracked as still active so a retry can reach the
54
+ * native call rather than the caller losing the ability to stop it at all.
55
+ *
56
+ * @param udid — UDID of the device to stop recording
57
+ * @throws {Error} if no recording is currently in progress for this device
58
+ */
59
+ export async function stopVideoRecording(udid) {
60
+ const key = udid.toLowerCase();
61
+ const state = activeRecordings.get(key);
62
+ if (!state) {
63
+ throw new Error(`No video recording is in progress for device '${udid}'`);
64
+ }
65
+ try {
66
+ await state.start;
67
+ }
68
+ catch {
69
+ // start itself failed — its own catch already cleaned up activeRecordings; nothing to stop.
70
+ throw new Error(`No video recording is in progress for device '${udid}'`);
71
+ }
72
+ const stopPromise = (state.stop ??= runCatchingAsync(async () => (await this._findDevice(udid)).stopVideoRecording()));
73
+ try {
74
+ await stopPromise;
75
+ }
76
+ catch (e) {
77
+ // Only clear our own attempt, and only if it's still the current one — a future call must be
78
+ // able to retry the native stop rather than replaying this same rejection forever, but must
79
+ // not clobber a newer attempt another concurrent caller may have already started instead.
80
+ if (state.stop === stopPromise) {
81
+ state.stop = undefined;
82
+ }
83
+ throw e;
84
+ }
85
+ if (activeRecordings.get(key) === state) {
86
+ activeRecordings.delete(key);
87
+ }
88
+ }
89
+ /**
90
+ * Whether a recording started by {@link startVideoRecording} is currently active for this device.
91
+ * Pure local state — no CoreSimulator dispatch — so this never rejects with a native error.
92
+ *
93
+ * @param udid — UDID of the device to check
94
+ */
95
+ export async function isVideoRecording(udid) {
96
+ return activeRecordings.has(udid.toLowerCase());
97
+ }
98
+ //# sourceMappingURL=video-recording.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-recording.js","sourceRoot":"","sources":["../../../src/commands/video-recording.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { NativeSimctl } from '../native-simctl.js';
3
+ import type { VideoAccessUnit, VideoStreamOptions } from '../types.js';
4
+ declare module '../native-simctl.js' {
5
+ interface NativeSimctl {
6
+ startVideoStream(udid: string, options?: VideoStreamOptions): Promise<VideoStream>;
7
+ }
8
+ }
9
+ /**
10
+ * A live video stream from `NativeSimctl.startVideoStream` — encodes the device's display in real
11
+ * time via VideoToolbox, unlike `startVideoRecording`, which drives CoreSimulator's own private,
12
+ * file-only recorder. Mirrors `appium-ios-remotexpc`'s `ScreenStreamCapture` shape
13
+ * (`accessUnits()`/`stop()`) for API consistency; the transport is otherwise unrelated.
14
+ */
15
+ export declare class VideoStream extends EventEmitter {
16
+ readonly codec: 'h264' | 'hevc';
17
+ private handle;
18
+ private readonly stopController;
19
+ private stopPromise;
20
+ private readonly queue;
21
+ private activeConsumers;
22
+ /**
23
+ * Yields each encoded access unit as it's produced, until {@link stop} is called or the stream
24
+ * errors (in which case the error is thrown out of the loop). Pass `signal` to stop iterating
25
+ * without treating that as an error. Mirrors `ScreenStreamCapture.accessUnits()`'s shape.
26
+ *
27
+ * Only one active consumer is supported at a time — a second concurrent call rejects rather
28
+ * than silently sharing (and corrupting) the first one's single internal waiter slot.
29
+ */
30
+ accessUnits(signal?: AbortSignal): AsyncGenerator<VideoAccessUnit>;
31
+ /** Stops the stream and releases the underlying encoder. Idempotent, including concurrently. */
32
+ stop(): Promise<void>;
33
+ }
34
+ /**
35
+ * Starts encoding the device's display in real time. Resolves once the encoder has actually
36
+ * started; the returned {@link VideoStream}'s `accessUnits()` then yields each frame as it
37
+ * arrives. Independent of `startVideoRecording`/`stopVideoRecording` — both, and any number of
38
+ * concurrent streams, can run on the same device at once.
39
+ *
40
+ * @param udid — UDID of the device to stream; must be booted
41
+ * @param options — `displayId`, `codec`, `fps`, `bitrate` — see {@link VideoStreamOptions}
42
+ */
43
+ export declare function startVideoStream(this: NativeSimctl, udid: string, options?: VideoStreamOptions): Promise<VideoStream>;
44
+ //# sourceMappingURL=video-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-stream.d.ts","sourceRoot":"","sources":["../../../src/commands/video-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAKzC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAA0B,eAAe,EAAE,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAG9F,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;KACpF;CACF;AA2ID;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,YAAY;aAWf,KAAK,EAAE,MAAM,GAAG,MAAM;IAVlD,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,WAAW,CAA4B;IAI/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6D;IACnF,OAAO,CAAC,eAAe,CAAK;IAiC5B;;;;;;;OAOG;IACI,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,eAAe,CAAC;IAmBzE,gGAAgG;IAC1F,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAuBtB"}
@@ -0,0 +1,240 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { logger } from '@appium/support';
3
+ import { wrapNativeError } from '../errors.js';
4
+ import { runCatchingAsync } from '../utils/index.js';
5
+ const log = logger.getLogger('CoreSim');
6
+ // Matches the native side's own ThreadSafeFunction queue bound (see coresim.mm's
7
+ // kAccessUnitQueueSize) — kept here too since the native bound alone provides no real
8
+ // backpressure: _handleAccessUnit's emit-equivalent push always returns immediately, regardless of
9
+ // how slow the actual accessUnits() consumer is, so without a bound of its own this queue could
10
+ // otherwise grow without limit while a slow consumer falls behind.
11
+ const MAX_BUFFERED_UNITS = 60;
12
+ const SINGLE_CONSUMER_ERROR = 'VideoStream.accessUnits() supports only one active consumer at a time — a second concurrent call rejects.';
13
+ /** `wrapNativeError` always throws — this just gets its thrown value back as a plain return, to emit rather than raise it. */
14
+ function toTypedError(err) {
15
+ try {
16
+ wrapNativeError(err);
17
+ }
18
+ catch (wrapped) {
19
+ return wrapped;
20
+ }
21
+ }
22
+ /**
23
+ * Single-consumer FIFO between native's per-frame callback and `accessUnits()`. Unlike routing
24
+ * through `EventEmitter`, a unit pushed before any consumer has started iterating is retained
25
+ * (fixing the encoder's own first-frame/keyframe otherwise being lost to a startup race) rather
26
+ * than silently dropped.
27
+ *
28
+ * Bounded at `MAX_BUFFERED_UNITS`, but codec-aware about *how* it sheds load once a slow consumer
29
+ * falls behind: since frames only reference earlier frames they were encoded against (no
30
+ * `AllowFrameReordering`), dropping an arbitrary interframe would orphan every later one from its
31
+ * reference chain, corrupting decode from that point on even though delivery looks unbroken.
32
+ * Overflow instead clears the backlog entirely and enters a resync state, discarding every
33
+ * further interframe (not buffering them) until the next keyframe — self-decodable on its own —
34
+ * lets delivery resume cleanly.
35
+ */
36
+ class AccessUnitQueue {
37
+ onOverflow;
38
+ buffer = [];
39
+ waiter;
40
+ ended = false;
41
+ error;
42
+ resyncing = false;
43
+ /** @param onOverflow — called once when overflow first forces a resync, e.g. to request a fresh keyframe. */
44
+ constructor(onOverflow) {
45
+ this.onOverflow = onOverflow;
46
+ }
47
+ push(unit) {
48
+ if (this.ended) {
49
+ return;
50
+ }
51
+ if (this.resyncing) {
52
+ if (!unit.isKeyFrame) {
53
+ return; // still waiting for a self-decodable point to resume delivery from
54
+ }
55
+ this.resyncing = false;
56
+ }
57
+ if (this.waiter) {
58
+ const { resolve } = this.waiter;
59
+ this.waiter = undefined;
60
+ resolve({ value: unit, done: false });
61
+ return;
62
+ }
63
+ this.buffer.push(unit);
64
+ if (this.buffer.length > MAX_BUFFERED_UNITS) {
65
+ this.buffer.length = 0;
66
+ this.resyncing = true;
67
+ this.onOverflow?.();
68
+ }
69
+ }
70
+ /** Ends the queue with an error — any pending or future `next()` rejects with it. */
71
+ fail(err) {
72
+ if (this.ended) {
73
+ return;
74
+ }
75
+ this.ended = true;
76
+ this.error = err;
77
+ this.buffer.length = 0;
78
+ if (this.waiter) {
79
+ const { reject } = this.waiter;
80
+ this.waiter = undefined;
81
+ reject(err);
82
+ }
83
+ }
84
+ /** Ends the queue cleanly — any pending or future `next()` resolves `done`. */
85
+ end() {
86
+ if (this.ended) {
87
+ return;
88
+ }
89
+ this.ended = true;
90
+ this.buffer.length = 0;
91
+ if (this.waiter) {
92
+ const { resolve } = this.waiter;
93
+ this.waiter = undefined;
94
+ resolve({ value: undefined, done: true });
95
+ }
96
+ }
97
+ /**
98
+ * Resolves `done` (not rejects) if `signal` aborts while waiting, mirroring `events.on()`.
99
+ * Checks cancellation/end *before* dequeuing, so an already-aborted signal or an already-ended
100
+ * queue never hands out a stale buffered unit — an aborted consumer, or a fresh iterator started
101
+ * after `stop()`, must see the boundary immediately rather than draining leftovers first.
102
+ */
103
+ next(signal) {
104
+ if (signal.aborted) {
105
+ return Promise.resolve({ value: undefined, done: true });
106
+ }
107
+ if (this.ended) {
108
+ return this.error ? Promise.reject(this.error) : Promise.resolve({ value: undefined, done: true });
109
+ }
110
+ const buffered = this.buffer.shift();
111
+ if (buffered !== undefined) {
112
+ return Promise.resolve({ value: buffered, done: false });
113
+ }
114
+ return new Promise((resolve, reject) => {
115
+ const onAbort = () => {
116
+ this.waiter = undefined;
117
+ resolve({ value: undefined, done: true });
118
+ };
119
+ signal.addEventListener('abort', onAbort, { once: true });
120
+ this.waiter = {
121
+ resolve: (result) => {
122
+ signal.removeEventListener('abort', onAbort);
123
+ resolve(result);
124
+ },
125
+ reject: (err) => {
126
+ signal.removeEventListener('abort', onAbort);
127
+ reject(err);
128
+ },
129
+ };
130
+ });
131
+ }
132
+ }
133
+ /**
134
+ * A live video stream from `NativeSimctl.startVideoStream` — encodes the device's display in real
135
+ * time via VideoToolbox, unlike `startVideoRecording`, which drives CoreSimulator's own private,
136
+ * file-only recorder. Mirrors `appium-ios-remotexpc`'s `ScreenStreamCapture` shape
137
+ * (`accessUnits()`/`stop()`) for API consistency; the transport is otherwise unrelated.
138
+ */
139
+ export class VideoStream extends EventEmitter {
140
+ codec;
141
+ handle;
142
+ stopController = new AbortController();
143
+ stopPromise;
144
+ // Requests a fresh keyframe on resync so delivery can resume immediately rather than waiting
145
+ // for the next periodic one — `handle` may not be attached yet on a startup-time overflow
146
+ // (vanishingly unlikely given MAX_BUFFERED_UNITS), in which case this is just a no-op.
147
+ queue = new AccessUnitQueue(() => this.handle?.requestKeyFrame());
148
+ activeConsumers = 0;
149
+ /** @internal */
150
+ constructor(codec) {
151
+ super();
152
+ this.codec = codec;
153
+ }
154
+ /** @internal */
155
+ _handleAccessUnit(unit) {
156
+ this.queue.push(unit);
157
+ }
158
+ /**
159
+ * @internal
160
+ * An active `accessUnits()` consumer receives the error via the queue itself (thrown out of its
161
+ * `for await` loop, per that method's contract) rather than the `'error'` event, so `emit` is
162
+ * only used for an explicit external listener; with neither, it's logged instead of lost.
163
+ */
164
+ _handleError(err) {
165
+ const error = toTypedError(err);
166
+ this.queue.fail(error);
167
+ if (this.listenerCount('error') > 0) {
168
+ this.emit('error', error);
169
+ }
170
+ else if (this.activeConsumers === 0) {
171
+ log.error(`Unhandled VideoStream error: ${error.stack ?? error}`);
172
+ }
173
+ }
174
+ /** @internal */
175
+ _attachHandle(handle) {
176
+ this.handle = handle;
177
+ }
178
+ /**
179
+ * Yields each encoded access unit as it's produced, until {@link stop} is called or the stream
180
+ * errors (in which case the error is thrown out of the loop). Pass `signal` to stop iterating
181
+ * without treating that as an error. Mirrors `ScreenStreamCapture.accessUnits()`'s shape.
182
+ *
183
+ * Only one active consumer is supported at a time — a second concurrent call rejects rather
184
+ * than silently sharing (and corrupting) the first one's single internal waiter slot.
185
+ */
186
+ async *accessUnits(signal) {
187
+ if (this.activeConsumers > 0) {
188
+ throw new Error(SINGLE_CONSUMER_ERROR);
189
+ }
190
+ const combined = signal ? AbortSignal.any([signal, this.stopController.signal]) : this.stopController.signal;
191
+ this.activeConsumers++;
192
+ try {
193
+ for (;;) {
194
+ const result = await this.queue.next(combined);
195
+ if (result.done) {
196
+ return;
197
+ }
198
+ yield result.value;
199
+ }
200
+ }
201
+ finally {
202
+ this.activeConsumers--;
203
+ }
204
+ }
205
+ /** Stops the stream and releases the underlying encoder. Idempotent, including concurrently. */
206
+ async stop() {
207
+ this.stopPromise ??= (async () => {
208
+ this.stopController.abort();
209
+ this.queue.end();
210
+ await this.handle?.stop();
211
+ })();
212
+ return this.stopPromise;
213
+ }
214
+ }
215
+ /**
216
+ * Starts encoding the device's display in real time. Resolves once the encoder has actually
217
+ * started; the returned {@link VideoStream}'s `accessUnits()` then yields each frame as it
218
+ * arrives. Independent of `startVideoRecording`/`stopVideoRecording` — both, and any number of
219
+ * concurrent streams, can run on the same device at once.
220
+ *
221
+ * @param udid — UDID of the device to stream; must be booted
222
+ * @param options — `displayId`, `codec`, `fps`, `bitrate` — see {@link VideoStreamOptions}
223
+ */
224
+ export async function startVideoStream(udid, options = {}) {
225
+ // The native poller clamps below 1 fps to 1 fps rather than actually polling that slowly, so a
226
+ // sub-1 value here would silently poll far more often than requested — rejected instead.
227
+ if (options.fps !== undefined && (!Number.isFinite(options.fps) || options.fps < 1)) {
228
+ throw new RangeError(`fps must be a finite number >= 1, got ${options.fps}`);
229
+ }
230
+ if (options.bitrate !== undefined &&
231
+ (!Number.isFinite(options.bitrate) || options.bitrate <= 0 || options.bitrate > 2 ** 31 - 1)) {
232
+ throw new RangeError(`bitrate must be a positive number no greater than ${2 ** 31 - 1}, got ${options.bitrate}`);
233
+ }
234
+ const device = await runCatchingAsync(() => this._findDevice(udid));
235
+ const stream = new VideoStream(options.codec === 'hevc' ? 'hevc' : 'h264');
236
+ const handle = await runCatchingAsync(() => device.startVideoStream(options, (unit) => stream._handleAccessUnit(unit), (err) => stream._handleError(err)));
237
+ stream._attachHandle(handle);
238
+ return stream;
239
+ }
240
+ //# sourceMappingURL=video-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-stream.js","sourceRoot":"","sources":["../../../src/commands/video-stream.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  export { NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError } from './errors.js';
2
2
  export { NativeSimctl } from './native-simctl.js';
3
3
  export { SpawnedProcess } from './commands/spawn.js';
4
+ export { VideoStream } from './commands/video-stream.js';
4
5
  export type { AppContainerType } from './commands/app.js';
5
6
  export type { BiometricName } from './commands/biometric.js';
6
- export { SimBootStatus, SimDeviceState, type ApnsAlert, type ApnsPayload, type ApnsSound, type PushNotificationPayload, type ScreenshotOptions, type SimBootInfo, type SimDeviceInfo, type SimDeviceTypeInfo, type SimDisplayInfo, type SimPermissionService, type SimPermissionStatus, type SimProcessInfo, type SimRuntimeInfo, type SpawnOptions, } from './types.js';
7
+ export { SimBootStatus, SimDeviceState, type ApnsAlert, type ApnsPayload, type ApnsSound, type PushNotificationPayload, type ScreenshotOptions, type SimBootInfo, type SimDeviceInfo, type SimDeviceTypeInfo, type SimDisplayInfo, type SimPermissionService, type SimPermissionStatus, type SimProcessInfo, type SimRuntimeInfo, type SpawnOptions, type VideoAccessUnit, type VideoRecordingOptions, type VideoStreamOptions, } from './types.js';
7
8
  //# sourceMappingURL=index.d.ts.map