@appium/coresim 1.14.0 → 1.15.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.15.0](https://github.com/appium/appium-ios/compare/@appium/coresim@1.14.1...@appium/coresim@1.15.0) (2026-11-07)
7
+
8
+ ### Features
9
+
10
+ * add opt-in boot-scoped screenshot display cache ([#51](https://github.com/appium/appium-ios/issues/51)) ([692a1f7](https://github.com/appium/appium-ios/commit/692a1f77bfbc64a18184a83282a8d2695ffe8d0a))
11
+
12
+
13
+ ## [1.14.1](https://github.com/appium/appium-ios/compare/@appium/coresim@1.14.0...@appium/coresim@1.14.1) (2026-11-06)
14
+
15
+ ### Bug Fixes
16
+
17
+ * **coresim:** include the failure reason and underlying errors in operation errors ([#163](https://github.com/appium/appium-ios/issues/163)) ([0032a91](https://github.com/appium/appium-ios/commit/0032a918d11d6d883f2896b907b0fbca2a734353))
18
+
19
+
6
20
  ## [1.14.0](https://github.com/appium/appium-ios/compare/@appium/coresim@1.13.2...@appium/coresim@1.14.0) (2026-10-24)
7
21
 
8
22
  ### Features
@@ -10,7 +10,8 @@ declare module '../native-simctl.js' {
10
10
  * Captures a device display as an image — the native equivalent of `simctl io <udid> screenshot`
11
11
  * (see native/sim_screenshot.mm for how this reads the framebuffer directly, with no temp file or
12
12
  * subprocess). Rejects if the resolved display has no renderable surface yet (e.g. not booted).
13
- * Display selection follows {@link validateDisplayId} and {@link resolveDisplayPortId}.
13
+ * Display selection follows {@link validateDisplayId}; numeric IDs resolve to display port UUIDs.
14
+ * See {@link ScreenshotOptions.cacheDisplayId} for optional boot-scoped numeric-ID caching.
14
15
  *
15
16
  * @param udid — UDID of the device to capture; must be booted
16
17
  * @param options — `format` (defaults to `'png'`), `displayId`,
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/commands/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,aAAa,CAAC;AAGnE,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;KACtD;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAajB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAE7F"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/commands/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,aAAa,CAAC;AAInE,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,YAAY;QACpB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;KACtD;CACF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAE7F"}
@@ -1,9 +1,12 @@
1
- import { resolveDisplayPortId, runCatchingAsync, validateDisplayId } from '../utils/index.js';
1
+ import { NativeSimDisplayResolutionError } from '../errors.js';
2
+ import { beginDisplaySelection } from '../utils/display-cache.js';
3
+ import { runCatchingAsync, validateDisplayId } from '../utils/index.js';
2
4
  /**
3
5
  * Captures a device display as an image — the native equivalent of `simctl io <udid> screenshot`
4
6
  * (see native/sim_screenshot.mm for how this reads the framebuffer directly, with no temp file or
5
7
  * subprocess). Rejects if the resolved display has no renderable surface yet (e.g. not booted).
6
- * Display selection follows {@link validateDisplayId} and {@link resolveDisplayPortId}.
8
+ * Display selection follows {@link validateDisplayId}; numeric IDs resolve to display port UUIDs.
9
+ * See {@link ScreenshotOptions.cacheDisplayId} for optional boot-scoped numeric-ID caching.
7
10
  *
8
11
  * @param udid — UDID of the device to capture; must be booted
9
12
  * @param options — `format` (defaults to `'png'`), `displayId`,
@@ -16,11 +19,10 @@ export async function getScreenshot(udid, options = {}) {
16
19
  throw new RangeError(`quality must be a number between 0 and 100, got ${options.quality}`);
17
20
  }
18
21
  validateDisplayId(options.displayId);
19
- return runCatchingAsync(async () => {
20
- const device = await this._findDevice(udid);
21
- const displayId = await resolveDisplayPortId(device, options.displayId);
22
- return await device.screenshot({ ...options, displayId });
23
- });
22
+ if (options.cacheDisplayId !== undefined && typeof options.cacheDisplayId !== 'boolean') {
23
+ throw new TypeError('cacheDisplayId must be a boolean');
24
+ }
25
+ return runCatchingAsync(async () => await captureScreenshot(this, udid, options));
24
26
  }
25
27
  /**
26
28
  * Lists the device's renderable displays — the same information `simctl io <udid> enumerate`
@@ -32,4 +34,26 @@ export async function getScreenshot(udid, options = {}) {
32
34
  export async function getDisplays(udid) {
33
35
  return runCatchingAsync(async () => (await this._findDevice(udid)).getDisplays());
34
36
  }
37
+ /** Capture policy stays here; display resolution and cache ownership are operation-independent. */
38
+ async function captureScreenshot(client, udid, { cacheDisplayId, ...options }) {
39
+ const selection = await beginDisplaySelection(client, udid, options.displayId, cacheDisplayId);
40
+ if (selection.cachedPortId !== undefined) {
41
+ try {
42
+ const result = await runCatchingAsync(async () => selection.device.screenshot({ ...options, displayId: selection.cachedPortId }));
43
+ if (selection.commit(selection.cachedPortId)) {
44
+ return result;
45
+ }
46
+ }
47
+ catch (err) {
48
+ if (!(err instanceof NativeSimDisplayResolutionError)) {
49
+ throw err;
50
+ }
51
+ }
52
+ // Retry a missing cached port or a capture spanning a reboot once, using the same numeric ID.
53
+ }
54
+ const displayId = await selection.resolveFresh();
55
+ const result = await selection.device.screenshot({ ...options, displayId });
56
+ selection.commit(displayId);
57
+ return result;
58
+ }
35
59
  //# sourceMappingURL=screenshot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/commands/screenshot.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAS5F;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAEjC,IAAY,EACZ,UAA6B,EAAE;IAE/B,IACE,OAAO,CAAC,OAAO,KAAK,SAAS;QAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,EACnF,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,mDAAmD,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,gBAAgB,CAAC,KAAK,IAAI,EAAE;QACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACxE,OAAO,MAAM,MAAM,CAAC,UAAU,CAAC,EAAC,GAAG,OAAO,EAAE,SAAS,EAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAqB,IAAY;IAChE,OAAO,gBAAgB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACpF,CAAC"}
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/commands/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,cAAc,CAAC;AAG7D,OAAO,EAAC,qBAAqB,EAAC,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAStE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAEjC,IAAY,EACZ,UAA6B,EAAE;IAE/B,IACE,OAAO,CAAC,OAAO,KAAK,SAAS;QAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC,EACnF,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,mDAAmD,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACxF,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,gBAAgB,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAqB,IAAY;IAChE,OAAO,gBAAgB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,mGAAmG;AACnG,KAAK,UAAU,iBAAiB,CAC9B,MAAoB,EACpB,IAAY,EACZ,EAAC,cAAc,EAAE,GAAG,OAAO,EAAoB;IAE/C,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC/F,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,IAAI,EAAE,CAC/C,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAC,GAAG,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,YAAY,EAAC,CAAC,CAC7E,CAAC;YACF,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7C,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,GAAG,YAAY,+BAA+B,CAAC,EAAE,CAAC;gBACtD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QACD,8FAA8F;IAChG,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,YAAY,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAC,GAAG,OAAO,EAAE,SAAS,EAAC,CAAC,CAAC;IAC1E,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -4,10 +4,8 @@ export declare class NativeSimError extends Error {
4
4
  constructor(message: string);
5
5
  }
6
6
  /**
7
- * The class/selector a call needed doesn't exist on the currently loaded CoreSimulator.framework,
8
- * or a dynamic dispatch raised an NSException that got caught instead of crashing the process.
9
- * Distinct from {@link NativeSimOperationError}: this means "not supported on this simulator
10
- * runtime", not "the call ran and Apple's own code rejected it".
7
+ * A required class, selector, or framework is unavailable.
8
+ * Objective-C exceptions use {@link NativeSimDispatchError} instead.
11
9
  */
12
10
  export declare class NativeSimUnavailableError extends NativeSimError {
13
11
  readonly kind: string;
@@ -34,18 +32,28 @@ export declare class NativeSimDispatchError extends NativeSimError {
34
32
  */
35
33
  constructor(message: string, exceptionName: string, reason: string);
36
34
  }
37
- /** The call reached CoreSimulator and Apple's own code rejected it (a structured `NSError`). */
35
+ /** A structured `NSError` from CoreSimulator or the native addon, preserving its domain and code. */
38
36
  export declare class NativeSimOperationError extends NativeSimError {
39
37
  readonly domain: string;
40
38
  readonly code: number;
41
39
  name: string;
42
40
  /**
43
- * @param message — `NSError.localizedDescription`
41
+ * @param message — `NSError.localizedDescription`, followed by its failure reason and underlying errors
44
42
  * @param domain — `NSError.domain`
45
43
  * @param code — `NSError.code`
46
44
  */
47
45
  constructor(message: string, domain: string, code: number);
48
46
  }
49
- /** Re-throws a raw error surfaced by the native addon as the matching typed {@link NativeSimError}. */
47
+ /**
48
+ * A requested display port is missing or no renderable port exists.
49
+ * Classified by native/nserror_bridge.mm using native/screenshot_errors.h.
50
+ */
51
+ export declare class NativeSimDisplayResolutionError extends NativeSimOperationError {
52
+ name: string;
53
+ }
54
+ /**
55
+ * Converts native bridge error names to typed errors; domain/code remain diagnostic metadata.
56
+ * Already-typed errors pass through unchanged.
57
+ */
50
58
  export declare function wrapNativeError(err: unknown): never;
51
59
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,qBAAa,cAAe,SAAQ,KAAK;IACvB,IAAI,SAAoB;gBAE5B,OAAO,EAAE,MAAM;CAG5B;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,cAAc;aAWzC,IAAI,EAAE,MAAM;aACZ,OAAO,EAAE,MAAM;aACf,gBAAgB,EAAE,MAAM;IAZ1B,IAAI,SAA+B;IAEnD;;;;;OAKG;gBAED,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM;CAI3C;AAED,iGAAiG;AACjG,qBAAa,sBAAuB,SAAQ,cAAc;aAUtC,aAAa,EAAE,MAAM;aACrB,MAAM,EAAE,MAAM;IAVhB,IAAI,SAA4B;IAEhD;;;;OAIG;gBAED,OAAO,EAAE,MAAM,EACC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM;CAIjC;AAED,gGAAgG;AAChG,qBAAa,uBAAwB,SAAQ,cAAc;aAUvC,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;IAVd,IAAI,SAA6B;IAEjD;;;;OAIG;gBAED,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAI/B;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAqBnD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,qBAAa,cAAe,SAAQ,KAAK;IACvB,IAAI,SAAoB;gBAE5B,OAAO,EAAE,MAAM;CAG5B;AAED;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,cAAc;aAWzC,IAAI,EAAE,MAAM;aACZ,OAAO,EAAE,MAAM;aACf,gBAAgB,EAAE,MAAM;IAZ1B,IAAI,SAA+B;IAEnD;;;;;OAKG;gBAED,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM;CAI3C;AAED,iGAAiG;AACjG,qBAAa,sBAAuB,SAAQ,cAAc;aAUtC,aAAa,EAAE,MAAM;aACrB,MAAM,EAAE,MAAM;IAVhB,IAAI,SAA4B;IAEhD;;;;OAIG;gBAED,OAAO,EAAE,MAAM,EACC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM;CAIjC;AAED,qGAAqG;AACrG,qBAAa,uBAAwB,SAAQ,cAAc;aAUvC,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;IAVd,IAAI,SAA6B;IAEjD;;;;OAIG;gBAED,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAI/B;AAED;;;GAGG;AACH,qBAAa,+BAAgC,SAAQ,uBAAuB;IAC1D,IAAI,SAAqC;CAC1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAuBnD"}
package/lib/src/errors.js CHANGED
@@ -6,10 +6,8 @@ export class NativeSimError extends Error {
6
6
  }
7
7
  }
8
8
  /**
9
- * The class/selector a call needed doesn't exist on the currently loaded CoreSimulator.framework,
10
- * or a dynamic dispatch raised an NSException that got caught instead of crashing the process.
11
- * Distinct from {@link NativeSimOperationError}: this means "not supported on this simulator
12
- * runtime", not "the call ran and Apple's own code rejected it".
9
+ * A required class, selector, or framework is unavailable.
10
+ * Objective-C exceptions use {@link NativeSimDispatchError} instead.
13
11
  */
14
12
  export class NativeSimUnavailableError extends NativeSimError {
15
13
  kind;
@@ -45,13 +43,13 @@ export class NativeSimDispatchError extends NativeSimError {
45
43
  this.reason = reason;
46
44
  }
47
45
  }
48
- /** The call reached CoreSimulator and Apple's own code rejected it (a structured `NSError`). */
46
+ /** A structured `NSError` from CoreSimulator or the native addon, preserving its domain and code. */
49
47
  export class NativeSimOperationError extends NativeSimError {
50
48
  domain;
51
49
  code;
52
50
  name = 'NativeSimOperationError';
53
51
  /**
54
- * @param message — `NSError.localizedDescription`
52
+ * @param message — `NSError.localizedDescription`, followed by its failure reason and underlying errors
55
53
  * @param domain — `NSError.domain`
56
54
  * @param code — `NSError.code`
57
55
  */
@@ -61,7 +59,17 @@ export class NativeSimOperationError extends NativeSimError {
61
59
  this.code = code;
62
60
  }
63
61
  }
64
- /** Re-throws a raw error surfaced by the native addon as the matching typed {@link NativeSimError}. */
62
+ /**
63
+ * A requested display port is missing or no renderable port exists.
64
+ * Classified by native/nserror_bridge.mm using native/screenshot_errors.h.
65
+ */
66
+ export class NativeSimDisplayResolutionError extends NativeSimOperationError {
67
+ name = 'NativeSimDisplayResolutionError';
68
+ }
69
+ /**
70
+ * Converts native bridge error names to typed errors; domain/code remain diagnostic metadata.
71
+ * Already-typed errors pass through unchanged.
72
+ */
65
73
  export function wrapNativeError(err) {
66
74
  if (err instanceof NativeSimError) {
67
75
  throw err;
@@ -73,6 +81,8 @@ export function wrapNativeError(err) {
73
81
  throw new NativeSimUnavailableError(message, String(error.kind ?? ''), String(error.missing ?? ''), String(error.frameworkVersion ?? ''));
74
82
  case 'NativeSimDispatchError':
75
83
  throw new NativeSimDispatchError(message, String(error.exceptionName ?? ''), String(error.reason ?? ''));
84
+ case 'NativeSimDisplayResolutionError':
85
+ throw new NativeSimDisplayResolutionError(message, String(error.domain ?? ''), Number(error.code ?? 0));
76
86
  case 'NativeSimOperationError':
77
87
  throw new NativeSimOperationError(message, String(error.domain ?? ''), Number(error.code ?? 0));
78
88
  default:
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvB,IAAI,GAAG,gBAAgB,CAAC;IAExC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,yBAA0B,SAAQ,cAAc;IAWzC;IACA;IACA;IAZF,IAAI,GAAG,2BAA2B,CAAC;IAEnD;;;;;OAKG;IACH,YACE,OAAe,EACC,IAAY,EACZ,OAAe,EACf,gBAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,qBAAgB,GAAhB,gBAAgB,CAAQ;IAG1C,CAAC;CACF;AAED,iGAAiG;AACjG,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAUtC;IACA;IAVF,IAAI,GAAG,wBAAwB,CAAC;IAEhD;;;;OAIG;IACH,YACE,OAAe,EACC,aAAqB,EACrB,MAAc;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,kBAAa,GAAb,aAAa,CAAQ;QACrB,WAAM,GAAN,MAAM,CAAQ;IAGhC,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,uBAAwB,SAAQ,cAAc;IAUvC;IACA;IAVF,IAAI,GAAG,yBAAyB,CAAC;IAEjD;;;;OAIG;IACH,YACE,OAAe,EACC,MAAc,EACd,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;IAG9B,CAAC;CACF;AAED,uGAAuG;AACvG,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;QAClC,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,GAAsC,CAAC;IACrD,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9C,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;QACpB,KAAK,2BAA2B;YAC9B,MAAM,IAAI,yBAAyB,CACjC,OAAO,EACP,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,EACxB,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,EAC3B,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CACrC,CAAC;QACJ,KAAK,wBAAwB;YAC3B,MAAM,IAAI,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3G,KAAK,yBAAyB;YAC5B,MAAM,IAAI,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAClG;YACE,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvB,IAAI,GAAG,gBAAgB,CAAC;IAExC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,yBAA0B,SAAQ,cAAc;IAWzC;IACA;IACA;IAZF,IAAI,GAAG,2BAA2B,CAAC;IAEnD;;;;;OAKG;IACH,YACE,OAAe,EACC,IAAY,EACZ,OAAe,EACf,gBAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,qBAAgB,GAAhB,gBAAgB,CAAQ;IAG1C,CAAC;CACF;AAED,iGAAiG;AACjG,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAUtC;IACA;IAVF,IAAI,GAAG,wBAAwB,CAAC;IAEhD;;;;OAIG;IACH,YACE,OAAe,EACC,aAAqB,EACrB,MAAc;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,kBAAa,GAAb,aAAa,CAAQ;QACrB,WAAM,GAAN,MAAM,CAAQ;IAGhC,CAAC;CACF;AAED,qGAAqG;AACrG,MAAM,OAAO,uBAAwB,SAAQ,cAAc;IAUvC;IACA;IAVF,IAAI,GAAG,yBAAyB,CAAC;IAEjD;;;;OAIG;IACH,YACE,OAAe,EACC,MAAc,EACd,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;IAG9B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,+BAAgC,SAAQ,uBAAuB;IAC1D,IAAI,GAAG,iCAAiC,CAAC;CAC1D;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;QAClC,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,GAAsC,CAAC;IACrD,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9C,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;QACpB,KAAK,2BAA2B;YAC9B,MAAM,IAAI,yBAAyB,CACjC,OAAO,EACP,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,EACxB,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,EAC3B,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CACrC,CAAC;QACJ,KAAK,wBAAwB;YAC3B,MAAM,IAAI,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3G,KAAK,iCAAiC;YACpC,MAAM,IAAI,+BAA+B,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1G,KAAK,yBAAyB;YAC5B,MAAM,IAAI,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAClG;YACE,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- export { NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError } from './errors.js';
1
+ export { NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError, NativeSimDisplayResolutionError, } from './errors.js';
2
2
  export { NativeSimctl, type NativeSimctlOptions } from './native-simctl.js';
3
3
  export { SpawnedProcess } from './commands/spawn.js';
4
4
  export { VideoStream } from './commands/video-stream.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,uBAAuB,EAAC,MAAM,aAAa,CAAC;AACvH,OAAO,EAAC,YAAY,EAAE,KAAK,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,YAAY,EAAE,KAAK,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AACrD,YAAY,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC"}
package/lib/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError } from './errors.js';
1
+ export { NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError, NativeSimDisplayResolutionError, } from './errors.js';
2
2
  export { NativeSimctl } from './native-simctl.js';
3
3
  export { SpawnedProcess } from './commands/spawn.js';
4
4
  export { VideoStream } from './commands/video-stream.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,uBAAuB,EAAC,MAAM,aAAa,CAAC;AACvH,OAAO,EAAC,YAAY,EAA2B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,GAuBf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,YAAY,EAA2B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,GAuBf,MAAM,YAAY,CAAC"}
@@ -110,6 +110,13 @@ export interface DisplayOptions {
110
110
  }
111
111
  /** Options for `NativeSimctl.getScreenshot`. */
112
112
  export interface ScreenshotOptions extends DisplayOptions {
113
+ /**
114
+ * Cache numeric display-ID lookups per client/device while the observed boot marker is unchanged.
115
+ * Defaults to `false`, which clears the selection. Missing boot metadata disables caching.
116
+ * Missing cached ports retry once with fresh resolution. Disable during display-topology changes.
117
+ * @see https://github.com/appium/appium-ios/pull/51 for boot-marker limitations and validation.
118
+ */
119
+ cacheDisplayId?: boolean;
113
120
  /** Image encoding — defaults to `'png'`. */
114
121
  format?: 'png' | 'jpeg';
115
122
  /**
@@ -369,6 +376,8 @@ export interface NativeDeviceHandle {
369
376
  udid(): string;
370
377
  name(): string;
371
378
  state(): number;
379
+ /** Last boot's Unix timestamp in milliseconds, or null if never booted; may throw if unsupported. */
380
+ lastBootedAt(): number | null;
372
381
  deviceTypeIdentifier(): string;
373
382
  runtimeIdentifier(): string;
374
383
  runtimeRootPath(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,oBAAY,cAAc;IACxB,QAAQ,IAAI;IACZ,QAAQ,IAAI;IACZ,OAAO,IAAI;IACX,MAAM,IAAI;IACV,YAAY,IAAI;CACjB;AAED,kGAAkG;AAClG,oBAAY,iBAAiB;IAC3B,QAAQ,IAAI;IACZ,kBAAkB,IAAI;IACtB,cAAc,IAAI;IAClB,aAAa,IAAI;CAClB;AAED,uGAAuG;AACvG,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,gHAAgH;IAChH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wGAAwG;IACxG,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,+GAA+G;AAC/G,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wGAAwG;AACxG,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,oBAAY,aAAa;IACvB,OAAO,IAAI;IACX,sBAAsB,IAAI;IAC1B,kBAAkB,IAAI;IACtB,uDAAuD;IACvD,QAAQ,aAAa;CACtB;AAED,uGAAuG;AACvG,MAAM,WAAW,WAAW;IAC1B,8FAA8F;IAC9F,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7E;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,cAAc,GACd,YAAY,GACZ,QAAQ,GACR,eAAe,GACf,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,GACR,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oGAAoG;IACpG,EAAE,EAAE,MAAM,CAAC;IACX,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+FAA+F;IAC/F,YAAY,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,gDAAgD;AAChD,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,sDAAsD;AACtD,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qDAAqD;AACrD,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,mDAAmD;AACnD,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,kDAAkD;AAClD,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,uGAAuG;IACvG,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,oGAAoG;AACpG,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,yIAAyI;IACzI,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mGAAmG;AACnG,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC5B,iBAAiB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,UAAU,CAAC;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,WAAW,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAKD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;AAE3F,iGAAiG;AACjG,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,6BAA6B,GAAG,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAClF,MAAM,MAAM,wBAAwB,GAAG,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,qGAAqG;IACrG,eAAe,IAAI,IAAI,CAAC;CACzB;AAED,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAEvE,yFAAyF;AACzF,MAAM,WAAW,sBAAsB;IACrC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,oFAAoF;IACpF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,mHAAmH;AACnH,MAAM,WAAW,kBAAkB;IAGjC,IAAI,IAAI,MAAM,CAAC;IACf,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,qGAAqG;IACrG,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,IAAI,MAAM,CAAC;IAC/B,iBAAiB,IAAI,MAAM,CAAC;IAC5B,eAAe,IAAI,MAAM,CAAC;IAC1B,QAAQ,IAAI,MAAM,CAAC;IACnB,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,aAAa,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChF,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5E,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/E,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,UAAU,CAAC,OAAO,CAAC,EAAE;QAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvG,WAAW,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAKzC,mBAAmB,CACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EACH;QACE,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;QACrC,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GACD,SAAS,EACb,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACvC,gBAAgB,CACd,OAAO,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,SAAS,EACnH,YAAY,EAAE,6BAA6B,EAC3C,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,eAAe,CACb,OAAO,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,EACzF,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,SAAS,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACrH;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,OAAO,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACzC,YAAY,CAAC,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,+EAA+E;AAC/E,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACnD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAChE,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACrD,iBAAiB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;CAChD;AAED,uHAAuH;AACvH,MAAM,WAAW,mBAAmB;IAClC,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAChF,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC;;;;;OAKG;IACH,mBAAmB,IAAI,IAAI,CAAC;CAC7B"}
@@ -0,0 +1,13 @@
1
+ import type { NativeSimctl } from '../native-simctl.js';
2
+ import { type DisplayId, type NativeDeviceHandle } from '../types.js';
3
+ /** One operation's display selection. Call commit only after the operation succeeds. */
4
+ export interface DisplaySelection {
5
+ device: NativeDeviceHandle;
6
+ cachedPortId?: string;
7
+ resolveFresh(): Promise<string | undefined>;
8
+ /** Returns whether the observed boot is unchanged, even if another operation owns the cache. */
9
+ commit(portId: string | undefined): boolean;
10
+ }
11
+ /** Reserves write ownership while retaining the mapping; uncached selections invalidate it. */
12
+ export declare function beginDisplaySelection(client: NativeSimctl, udid: string, displayId: DisplayId | undefined, useCache?: boolean): Promise<DisplaySelection>;
13
+ //# sourceMappingURL=display-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-cache.d.ts","sourceRoot":"","sources":["../../../src/utils/display-cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAkBpF,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,gGAAgG;IAChG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CAC7C;AAED,+FAA+F;AAC/F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAoE3B"}
@@ -0,0 +1,92 @@
1
+ import { LRUCache } from 'lru-cache';
2
+ import { SimDeviceState } from '../types.js';
3
+ import { resolveDisplayPortId } from './display.js';
4
+ const MAX_CACHED_DEVICES = 32;
5
+ const displayCaches = new WeakMap();
6
+ /** Reserves write ownership while retaining the mapping; uncached selections invalidate it. */
7
+ export async function beginDisplaySelection(client, udid, displayId, useCache = false) {
8
+ const key = udid.toLowerCase();
9
+ let cache = displayCaches.get(client);
10
+ const cacheable = useCache && typeof displayId === 'number';
11
+ let cached;
12
+ const owner = Symbol('display-cache-owner');
13
+ let entry;
14
+ if (cacheable) {
15
+ if (!cache) {
16
+ cache = new LRUCache({ max: MAX_CACHED_DEVICES });
17
+ displayCaches.set(client, cache);
18
+ }
19
+ entry = cache.get(key) ?? { owner, generation: Symbol('display-cache-generation') };
20
+ cached = entry.display;
21
+ entry.owner = owner;
22
+ cache.set(key, entry);
23
+ }
24
+ else {
25
+ cache?.delete(key);
26
+ }
27
+ let generation = entry?.generation;
28
+ const invalidateCached = () => {
29
+ if (entry && cached && cache?.peek(key) === entry && entry.display === cached) {
30
+ entry.display = undefined;
31
+ entry.generation = Symbol('display-cache-generation');
32
+ if (entry.owner === owner) {
33
+ generation = entry.generation;
34
+ }
35
+ }
36
+ };
37
+ const device = await client._findDevice(udid);
38
+ let bootMarker = cacheable ? readBootMarker(device) : null;
39
+ const cachedPortId = bootMarker !== null && cached && cached.screenId === displayId && cached.bootMarker === bootMarker
40
+ ? cached.portId
41
+ : undefined;
42
+ if (cached && (bootMarker === null || cached.bootMarker !== bootMarker)) {
43
+ invalidateCached();
44
+ }
45
+ return {
46
+ device,
47
+ cachedPortId,
48
+ async resolveFresh() {
49
+ if (cachedPortId !== undefined) {
50
+ invalidateCached();
51
+ }
52
+ bootMarker = cacheable ? readBootMarker(device) : null;
53
+ return await resolveDisplayPortId(device, displayId);
54
+ },
55
+ commit(portId) {
56
+ const sameBoot = bootMarker !== null && readBootMarker(device) === bootMarker;
57
+ if (!sameBoot) {
58
+ invalidateCached();
59
+ }
60
+ if (sameBoot &&
61
+ bootMarker !== null &&
62
+ cacheable &&
63
+ portId &&
64
+ entry &&
65
+ cache?.peek(key) === entry &&
66
+ entry.owner === owner &&
67
+ entry.generation === generation) {
68
+ entry.display = { screenId: displayId, portId, bootMarker };
69
+ }
70
+ return sameBoot;
71
+ },
72
+ };
73
+ }
74
+ /**
75
+ * Returns a boot marker only while the device is Booted. Unsupported or unreadable metadata
76
+ * disables caching. The timestamp persists after shutdown and is not a guaranteed unique UUID.
77
+ */
78
+ function readBootMarker(device) {
79
+ try {
80
+ if (device.state() !== SimDeviceState.Booted) {
81
+ return null;
82
+ }
83
+ const marker = device.lastBootedAt();
84
+ return marker !== null && Number.isFinite(marker) && marker > 0 && device.state() === SimDeviceState.Booted
85
+ ? marker
86
+ : null;
87
+ }
88
+ catch {
89
+ return null;
90
+ }
91
+ }
92
+ //# sourceMappingURL=display-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-cache.js","sourceRoot":"","sources":["../../../src/utils/display-cache.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appium/coresim",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "Native bindings to CoreSimulator.framework for Apple platform simulator control",
5
5
  "bugs": {
6
6
  "url": "https://github.com/appium/appium-ios/issues"
@@ -49,6 +49,7 @@
49
49
  "dependencies": {
50
50
  "@appium/support": "^7.2.0",
51
51
  "asyncbox": "^6.5.0",
52
+ "lru-cache": "^11.5.3",
52
53
  "node-addon-api": "^8.5.0",
53
54
  "node-gyp-build": "^4.8.4"
54
55
  },
@@ -62,5 +63,5 @@
62
63
  "npm": ">=10"
63
64
  },
64
65
  "gypfile": true,
65
- "gitHead": "1e3ecf666350a1868a196e84bf09cc1fe116cc4a"
66
+ "gitHead": "943e2efdb5d8b26a704d0cef58cb5eec0f37076c"
66
67
  }
@@ -1,6 +1,8 @@
1
+ import {NativeSimDisplayResolutionError} from '../errors.js';
1
2
  import type {NativeSimctl} from '../native-simctl.js';
2
3
  import type {ScreenshotOptions, SimDisplayInfo} from '../types.js';
3
- import {resolveDisplayPortId, runCatchingAsync, validateDisplayId} from '../utils/index.js';
4
+ import {beginDisplaySelection} from '../utils/display-cache.js';
5
+ import {runCatchingAsync, validateDisplayId} from '../utils/index.js';
4
6
 
5
7
  declare module '../native-simctl.js' {
6
8
  interface NativeSimctl {
@@ -13,7 +15,8 @@ declare module '../native-simctl.js' {
13
15
  * Captures a device display as an image — the native equivalent of `simctl io <udid> screenshot`
14
16
  * (see native/sim_screenshot.mm for how this reads the framebuffer directly, with no temp file or
15
17
  * subprocess). Rejects if the resolved display has no renderable surface yet (e.g. not booted).
16
- * Display selection follows {@link validateDisplayId} and {@link resolveDisplayPortId}.
18
+ * Display selection follows {@link validateDisplayId}; numeric IDs resolve to display port UUIDs.
19
+ * See {@link ScreenshotOptions.cacheDisplayId} for optional boot-scoped numeric-ID caching.
17
20
  *
18
21
  * @param udid — UDID of the device to capture; must be booted
19
22
  * @param options — `format` (defaults to `'png'`), `displayId`,
@@ -32,11 +35,10 @@ export async function getScreenshot(
32
35
  throw new RangeError(`quality must be a number between 0 and 100, got ${options.quality}`);
33
36
  }
34
37
  validateDisplayId(options.displayId);
35
- return runCatchingAsync(async () => {
36
- const device = await this._findDevice(udid);
37
- const displayId = await resolveDisplayPortId(device, options.displayId);
38
- return await device.screenshot({...options, displayId});
39
- });
38
+ if (options.cacheDisplayId !== undefined && typeof options.cacheDisplayId !== 'boolean') {
39
+ throw new TypeError('cacheDisplayId must be a boolean');
40
+ }
41
+ return runCatchingAsync(async () => await captureScreenshot(this, udid, options));
40
42
  }
41
43
 
42
44
  /**
@@ -49,3 +51,31 @@ export async function getScreenshot(
49
51
  export async function getDisplays(this: NativeSimctl, udid: string): Promise<SimDisplayInfo[]> {
50
52
  return runCatchingAsync(async () => (await this._findDevice(udid)).getDisplays());
51
53
  }
54
+
55
+ /** Capture policy stays here; display resolution and cache ownership are operation-independent. */
56
+ async function captureScreenshot(
57
+ client: NativeSimctl,
58
+ udid: string,
59
+ {cacheDisplayId, ...options}: ScreenshotOptions,
60
+ ): Promise<Buffer> {
61
+ const selection = await beginDisplaySelection(client, udid, options.displayId, cacheDisplayId);
62
+ if (selection.cachedPortId !== undefined) {
63
+ try {
64
+ const result = await runCatchingAsync(async () =>
65
+ selection.device.screenshot({...options, displayId: selection.cachedPortId}),
66
+ );
67
+ if (selection.commit(selection.cachedPortId)) {
68
+ return result;
69
+ }
70
+ } catch (err) {
71
+ if (!(err instanceof NativeSimDisplayResolutionError)) {
72
+ throw err;
73
+ }
74
+ }
75
+ // Retry a missing cached port or a capture spanning a reboot once, using the same numeric ID.
76
+ }
77
+ const displayId = await selection.resolveFresh();
78
+ const result = await selection.device.screenshot({...options, displayId});
79
+ selection.commit(displayId);
80
+ return result;
81
+ }
package/src/coresim.mm CHANGED
@@ -606,6 +606,17 @@ class NativeDevice : public Napi::ObjectWrap<NativeDevice> {
606
606
  return Napi::Number::New(info.Env(), static_cast<double>(DeviceState(device_)));
607
607
  });
608
608
  }
609
+ // The observed boot timestamp is local metadata, like state. Missing/unsupported metadata
610
+ // disables the optional JS cache; callers must not treat it as a unique session UUID.
611
+ Napi::Value LastBootedAt(const Napi::CallbackInfo& info) {
612
+ return CatchToJs(info.Env(), [&]() -> Napi::Value {
613
+ NSDate* date = DeviceLastBootedAt(device_);
614
+ if (date == nil) {
615
+ return info.Env().Null();
616
+ }
617
+ return Napi::Number::New(info.Env(), date.timeIntervalSince1970 * 1000.0);
618
+ });
619
+ }
609
620
  // deviceType/runtime are legitimately nil for a device whose runtime profile is no longer
610
621
  // installed (shows as "unavailable" in `simctl list devices`) — not an error, just unknown.
611
622
  Napi::Value DeviceTypeIdentifier(const Napi::CallbackInfo& info) {
@@ -1773,6 +1784,7 @@ void NativeDevice::Init(Napi::Env env) {
1773
1784
  InstanceMethod<&NativeDevice::Udid>("udid"),
1774
1785
  InstanceMethod<&NativeDevice::Name>("name"),
1775
1786
  InstanceMethod<&NativeDevice::State>("state"),
1787
+ InstanceMethod<&NativeDevice::LastBootedAt>("lastBootedAt"),
1776
1788
  InstanceMethod<&NativeDevice::DeviceTypeIdentifier>("deviceTypeIdentifier"),
1777
1789
  InstanceMethod<&NativeDevice::RuntimeIdentifier>("runtimeIdentifier"),
1778
1790
  InstanceMethod<&NativeDevice::RuntimeRootPath>("runtimeRootPath"),
package/src/errors.ts CHANGED
@@ -8,10 +8,8 @@ export class NativeSimError extends Error {
8
8
  }
9
9
 
10
10
  /**
11
- * The class/selector a call needed doesn't exist on the currently loaded CoreSimulator.framework,
12
- * or a dynamic dispatch raised an NSException that got caught instead of crashing the process.
13
- * Distinct from {@link NativeSimOperationError}: this means "not supported on this simulator
14
- * runtime", not "the call ran and Apple's own code rejected it".
11
+ * A required class, selector, or framework is unavailable.
12
+ * Objective-C exceptions use {@link NativeSimDispatchError} instead.
15
13
  */
16
14
  export class NativeSimUnavailableError extends NativeSimError {
17
15
  public override name = 'NativeSimUnavailableError';
@@ -50,12 +48,12 @@ export class NativeSimDispatchError extends NativeSimError {
50
48
  }
51
49
  }
52
50
 
53
- /** The call reached CoreSimulator and Apple's own code rejected it (a structured `NSError`). */
51
+ /** A structured `NSError` from CoreSimulator or the native addon, preserving its domain and code. */
54
52
  export class NativeSimOperationError extends NativeSimError {
55
53
  public override name = 'NativeSimOperationError';
56
54
 
57
55
  /**
58
- * @param message — `NSError.localizedDescription`
56
+ * @param message — `NSError.localizedDescription`, followed by its failure reason and underlying errors
59
57
  * @param domain — `NSError.domain`
60
58
  * @param code — `NSError.code`
61
59
  */
@@ -68,7 +66,18 @@ export class NativeSimOperationError extends NativeSimError {
68
66
  }
69
67
  }
70
68
 
71
- /** Re-throws a raw error surfaced by the native addon as the matching typed {@link NativeSimError}. */
69
+ /**
70
+ * A requested display port is missing or no renderable port exists.
71
+ * Classified by native/nserror_bridge.mm using native/screenshot_errors.h.
72
+ */
73
+ export class NativeSimDisplayResolutionError extends NativeSimOperationError {
74
+ public override name = 'NativeSimDisplayResolutionError';
75
+ }
76
+
77
+ /**
78
+ * Converts native bridge error names to typed errors; domain/code remain diagnostic metadata.
79
+ * Already-typed errors pass through unchanged.
80
+ */
72
81
  export function wrapNativeError(err: unknown): never {
73
82
  if (err instanceof NativeSimError) {
74
83
  throw err;
@@ -85,6 +94,8 @@ export function wrapNativeError(err: unknown): never {
85
94
  );
86
95
  case 'NativeSimDispatchError':
87
96
  throw new NativeSimDispatchError(message, String(error.exceptionName ?? ''), String(error.reason ?? ''));
97
+ case 'NativeSimDisplayResolutionError':
98
+ throw new NativeSimDisplayResolutionError(message, String(error.domain ?? ''), Number(error.code ?? 0));
88
99
  case 'NativeSimOperationError':
89
100
  throw new NativeSimOperationError(message, String(error.domain ?? ''), Number(error.code ?? 0));
90
101
  default:
package/src/index.ts CHANGED
@@ -1,4 +1,10 @@
1
- export {NativeSimError, NativeSimUnavailableError, NativeSimDispatchError, NativeSimOperationError} from './errors.js';
1
+ export {
2
+ NativeSimError,
3
+ NativeSimUnavailableError,
4
+ NativeSimDispatchError,
5
+ NativeSimOperationError,
6
+ NativeSimDisplayResolutionError,
7
+ } from './errors.js';
2
8
  export {NativeSimctl, type NativeSimctlOptions} from './native-simctl.js';
3
9
  export {SpawnedProcess} from './commands/spawn.js';
4
10
  export {VideoStream} from './commands/video-stream.js';
@@ -11,6 +11,10 @@
11
11
 
12
12
  namespace coresim {
13
13
 
14
+ // localizedDescription is often generic ("Simulator device failed to install the application."), so
15
+ // the failure reason and the NSUnderlyingErrorKey chain are appended.
16
+ std::string DescribeNSError(NSError* error);
17
+
14
18
  // Thrown by async work lambdas (see async_bridge.h) when a native call fails via an NSError**
15
19
  // out-param rather than raising. domain/code/message are captured immediately at throw time
16
20
  // (never the NSError* itself), since this only ever needs to survive within the same background
@@ -18,7 +22,7 @@ namespace coresim {
18
22
  class NSErrorException : public std::runtime_error {
19
23
  public:
20
24
  explicit NSErrorException(NSError* error)
21
- : std::runtime_error(error.localizedDescription ? error.localizedDescription.UTF8String : "Operation failed"),
25
+ : std::runtime_error(DescribeNSError(error)),
22
26
  domain(error.domain ? error.domain.UTF8String : ""),
23
27
  code(error.code) {}
24
28
 
@@ -26,8 +30,9 @@ class NSErrorException : public std::runtime_error {
26
30
  long long code;
27
31
  };
28
32
 
29
- // Converts an NSError into a JS Error with {name: 'NativeSimOperationError', domain, code,
30
- // message} — errors.ts wraps this into NativeSimError. Built from an already-caught
33
+ // Converts an NSError into a named JS Error with domain/code/message. Display resolution
34
+ // failures use NativeSimDisplayResolutionError; other failures use NativeSimOperationError.
35
+ // errors.ts wraps the name into the matching class. Built from an already-caught
31
36
  // NSErrorException's extracted fields, never a live NSError*: this only ever runs in OnOK (main
32
37
  // thread), after the exception already crossed out of the background thread's try/catch.
33
38
  Napi::Error NSErrorExceptionToJsError(Napi::Env env, const NSErrorException& error);
@@ -1,10 +1,45 @@
1
1
  #include "nserror_bridge.h"
2
2
 
3
+ #include "screenshot_errors.h"
4
+
3
5
  namespace coresim {
4
6
 
7
+ std::string DescribeNSError(NSError* error) {
8
+ constexpr NSUInteger kMaxErrorDepth = 10;
9
+ NSMutableArray<NSString*>* parts = [NSMutableArray array];
10
+ NSError* current = error;
11
+ for (NSUInteger depth = 0; current != nil && depth < kMaxErrorDepth; ++depth) {
12
+ for (NSString* text in @[ current.localizedDescription ?: @"", current.localizedFailureReason ?: @"" ]) {
13
+ NSString* trimmed = [text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
14
+ NSUInteger known = [parts indexOfObjectPassingTest:^BOOL(NSString* part, NSUInteger, BOOL*) {
15
+ return [part containsString:trimmed];
16
+ }];
17
+ if (trimmed.length == 0 || known != NSNotFound) {
18
+ continue;
19
+ }
20
+ NSIndexSet* covered = [parts indexesOfObjectsPassingTest:^BOOL(NSString* part, NSUInteger, BOOL*) {
21
+ return [trimmed containsString:part];
22
+ }];
23
+ [parts removeObjectsAtIndexes:covered];
24
+ [parts addObject:trimmed];
25
+ }
26
+ id underlying = current.userInfo[NSUnderlyingErrorKey];
27
+ current = [underlying isKindOfClass:NSError.class] ? underlying : nil;
28
+ }
29
+ NSMutableArray<NSString*>* sentences = [NSMutableArray arrayWithCapacity:parts.count];
30
+ for (NSString* part in parts) {
31
+ BOOL terminated = [part hasSuffix:@"."] || [part hasSuffix:@"!"] || [part hasSuffix:@"?"];
32
+ [sentences addObject:terminated ? part : [part stringByAppendingString:@"."]];
33
+ }
34
+ return sentences.count > 0 ? [sentences componentsJoinedByString:@" "].UTF8String : "Operation failed";
35
+ }
36
+
5
37
  Napi::Error NSErrorExceptionToJsError(Napi::Env env, const NSErrorException& error) {
6
38
  Napi::Error jsError = Napi::Error::New(env, error.what());
7
- jsError.Set("name", "NativeSimOperationError");
39
+ const bool isDisplayResolutionError =
40
+ error.domain == kScreenshotErrorDomain &&
41
+ (error.code == kScreenshotDisplayNotFound || error.code == kScreenshotNoRenderableDisplay);
42
+ jsError.Set("name", isDisplayResolutionError ? "NativeSimDisplayResolutionError" : "NativeSimOperationError");
8
43
  jsError.Set("domain", error.domain);
9
44
  jsError.Set("code", static_cast<double>(error.code));
10
45
  return jsError;
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ namespace coresim {
4
+
5
+ inline constexpr const char* kScreenshotErrorDomain = "io.appium.coresim.Screenshot";
6
+
7
+ enum ScreenshotErrorCode {
8
+ kScreenshotNoIOClient = 1,
9
+ kScreenshotDisplayNotFound = 2,
10
+ kScreenshotNoRenderableDisplay = 3,
11
+ kScreenshotSurfaceUnavailable = 4,
12
+ kScreenshotImageCreationFailed = 5,
13
+ kScreenshotRenderingFailed = 6,
14
+ kScreenshotEncoderCreationFailed = 7,
15
+ kScreenshotEncodingFailed = 8,
16
+ kScreenshotNoCaptureServiceIOClient = 11,
17
+ };
18
+
19
+ } // namespace coresim
@@ -7,15 +7,14 @@
7
7
 
8
8
  #include "objc_runtime.h"
9
9
  #include "safe_dispatch.h"
10
+ #include "screenshot_errors.h"
10
11
 
11
12
  namespace coresim {
12
13
 
13
14
  namespace {
14
15
 
15
- NSString* const kScreenshotErrorDomain = @"io.appium.coresim.Screenshot";
16
-
17
- NSError* MakeError(NSInteger code, NSString* message) {
18
- return [NSError errorWithDomain:kScreenshotErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : message}];
16
+ NSError* MakeError(ScreenshotErrorCode code, NSString* message) {
17
+ return [NSError errorWithDomain:@(kScreenshotErrorDomain) code:code userInfo:@{NSLocalizedDescriptionKey : message}];
19
18
  }
20
19
 
21
20
  id IdGetter(id target, const std::string& selectorName) {
@@ -56,7 +55,7 @@ NSString* const kCandidateDescriptorKey = @"descriptor";
56
55
  NSArray<NSDictionary*>* RenderableDisplayCandidates(id device, NSError** error) {
57
56
  id ioClient = IdGetter(device, "io");
58
57
  if (ioClient == nil) {
59
- *error = MakeError(1, @"Device has no IO client available — is it booted?");
58
+ *error = MakeError(kScreenshotNoIOClient, @"Device has no IO client available — is it booted?");
60
59
  return nil;
61
60
  }
62
61
 
@@ -97,7 +96,8 @@ id ResolveDisplayDescriptor(NSArray<NSDictionary*>* candidates, NSString* displa
97
96
  return candidate[kCandidateDescriptorKey];
98
97
  }
99
98
  }
100
- *error = MakeError(2, [NSString stringWithFormat:@"No display with id '%@' was found on this device", displayId]);
99
+ *error = MakeError(kScreenshotDisplayNotFound,
100
+ [NSString stringWithFormat:@"No display with id '%@' was found on this device", displayId]);
101
101
  return nil;
102
102
  }
103
103
  id fallback = nil;
@@ -110,7 +110,7 @@ id ResolveDisplayDescriptor(NSArray<NSDictionary*>* candidates, NSString* displa
110
110
  }
111
111
  }
112
112
  if (fallback == nil) {
113
- *error = MakeError(3, @"No renderable display port was found on this device");
113
+ *error = MakeError(kScreenshotNoRenderableDisplay, @"No renderable display port was found on this device");
114
114
  }
115
115
  return fallback;
116
116
  }
@@ -159,7 +159,7 @@ id ResolveScreenCaptureService(id device, NSError** error) {
159
159
  "startRecordingFromScreen:maskPolicy:assetWriterOutputSettings:outputFile:completionQueue:completionHandler:";
160
160
  id ioClient = IdGetter(device, "io");
161
161
  if (ioClient == nil) {
162
- *error = MakeError(11, @"Device has no IO client available — is it booted?");
162
+ *error = MakeError(kScreenshotNoCaptureServiceIOClient, @"Device has no IO client available — is it booted?");
163
163
  return nil;
164
164
  }
165
165
  NSArray* ports = IdGetter(ioClient, "ioPorts");
@@ -214,7 +214,7 @@ NSData* EncodeImage(CGImageRef cgImage, ScreenshotFormat format, NSNumber* jpegQ
214
214
  CGImageDestinationRef destination =
215
215
  CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, (__bridge CFStringRef)uti, 1, NULL);
216
216
  if (destination == nullptr) {
217
- *error = MakeError(7, @"Failed to create an image encoder");
217
+ *error = MakeError(kScreenshotEncoderCreationFailed, @"Failed to create an image encoder");
218
218
  return nil;
219
219
  }
220
220
  // kCGImageDestinationLossyCompressionQuality is meaningless for PNG (always lossless) — ImageIO
@@ -228,7 +228,7 @@ NSData* EncodeImage(CGImageRef cgImage, ScreenshotFormat format, NSNumber* jpegQ
228
228
  BOOL ok = CGImageDestinationFinalize(destination);
229
229
  CFRelease(destination);
230
230
  if (!ok) {
231
- *error = MakeError(8, @"Failed to encode the image");
231
+ *error = MakeError(kScreenshotEncodingFailed, @"Failed to encode the image");
232
232
  return nil;
233
233
  }
234
234
  return imageData;
@@ -243,14 +243,14 @@ NSData* CaptureScreenshot(id device, NSString* displayId, ScreenshotFormat forma
243
243
 
244
244
  id surfaceObj = RenderableSurface(descriptor);
245
245
  if (surfaceObj == nil) {
246
- *error = MakeError(4, @"The device's display surface is not available yet");
246
+ *error = MakeError(kScreenshotSurfaceUnavailable, @"The device's display surface is not available yet");
247
247
  return nil;
248
248
  }
249
249
 
250
250
  IOSurfaceRef surfaceRef = (__bridge IOSurfaceRef)surfaceObj;
251
251
  CIImage* ciImage = [CIImage imageWithIOSurface:surfaceRef];
252
252
  if (ciImage == nil) {
253
- *error = MakeError(5, @"Failed to wrap the device's display surface as an image");
253
+ *error = MakeError(kScreenshotImageCreationFailed, @"Failed to wrap the device's display surface as an image");
254
254
  return nil;
255
255
  }
256
256
 
@@ -260,7 +260,7 @@ NSData* CaptureScreenshot(id device, NSString* displayId, ScreenshotFormat forma
260
260
  static CIContext* context = [CIContext contextWithOptions:nil];
261
261
  CGImageRef cgImage = [context createCGImage:ciImage fromRect:ciImage.extent];
262
262
  if (cgImage == nil) {
263
- *error = MakeError(6, @"Failed to render the device's display surface");
263
+ *error = MakeError(kScreenshotRenderingFailed, @"Failed to render the device's display surface");
264
264
  return nil;
265
265
  }
266
266
 
package/src/types.ts CHANGED
@@ -137,6 +137,13 @@ export interface DisplayOptions {
137
137
 
138
138
  /** Options for `NativeSimctl.getScreenshot`. */
139
139
  export interface ScreenshotOptions extends DisplayOptions {
140
+ /**
141
+ * Cache numeric display-ID lookups per client/device while the observed boot marker is unchanged.
142
+ * Defaults to `false`, which clears the selection. Missing boot metadata disables caching.
143
+ * Missing cached ports retry once with fresh resolution. Disable during display-topology changes.
144
+ * @see https://github.com/appium/appium-ios/pull/51 for boot-marker limitations and validation.
145
+ */
146
+ cacheDisplayId?: boolean;
140
147
  /** Image encoding — defaults to `'png'`. */
141
148
  format?: 'png' | 'jpeg';
142
149
  /**
@@ -423,6 +430,8 @@ export interface NativeDeviceHandle {
423
430
  udid(): string;
424
431
  name(): string;
425
432
  state(): number;
433
+ /** Last boot's Unix timestamp in milliseconds, or null if never booted; may throw if unsupported. */
434
+ lastBootedAt(): number | null;
426
435
  deviceTypeIdentifier(): string;
427
436
  runtimeIdentifier(): string;
428
437
  runtimeRootPath(): string;
@@ -0,0 +1,123 @@
1
+ import {LRUCache} from 'lru-cache';
2
+
3
+ import type {NativeSimctl} from '../native-simctl.js';
4
+ import {SimDeviceState, type DisplayId, type NativeDeviceHandle} from '../types.js';
5
+ import {resolveDisplayPortId} from './display.js';
6
+
7
+ const MAX_CACHED_DEVICES = 32;
8
+ interface CachedDisplay {
9
+ screenId: number;
10
+ portId: string;
11
+ bootMarker: number;
12
+ }
13
+ interface DisplayCacheEntry {
14
+ display?: CachedDisplay;
15
+ // New operations supersede writers without discarding the mapping.
16
+ owner: symbol;
17
+ // Invalidation also revokes pending writers that observed the old mapping.
18
+ generation: symbol;
19
+ }
20
+ const displayCaches = new WeakMap<NativeSimctl, LRUCache<string, DisplayCacheEntry>>();
21
+
22
+ /** One operation's display selection. Call commit only after the operation succeeds. */
23
+ export interface DisplaySelection {
24
+ device: NativeDeviceHandle;
25
+ cachedPortId?: string;
26
+ resolveFresh(): Promise<string | undefined>;
27
+ /** Returns whether the observed boot is unchanged, even if another operation owns the cache. */
28
+ commit(portId: string | undefined): boolean;
29
+ }
30
+
31
+ /** Reserves write ownership while retaining the mapping; uncached selections invalidate it. */
32
+ export async function beginDisplaySelection(
33
+ client: NativeSimctl,
34
+ udid: string,
35
+ displayId: DisplayId | undefined,
36
+ useCache: boolean = false,
37
+ ): Promise<DisplaySelection> {
38
+ const key = udid.toLowerCase();
39
+ let cache = displayCaches.get(client);
40
+ const cacheable = useCache && typeof displayId === 'number';
41
+ let cached: CachedDisplay | undefined;
42
+ const owner = Symbol('display-cache-owner');
43
+ let entry: DisplayCacheEntry | undefined;
44
+ if (cacheable) {
45
+ if (!cache) {
46
+ cache = new LRUCache<string, DisplayCacheEntry>({max: MAX_CACHED_DEVICES});
47
+ displayCaches.set(client, cache);
48
+ }
49
+ entry = cache.get(key) ?? {owner, generation: Symbol('display-cache-generation')};
50
+ cached = entry.display;
51
+ entry.owner = owner;
52
+ cache.set(key, entry);
53
+ } else {
54
+ cache?.delete(key);
55
+ }
56
+ let generation = entry?.generation;
57
+ const invalidateCached = () => {
58
+ if (entry && cached && cache?.peek(key) === entry && entry.display === cached) {
59
+ entry.display = undefined;
60
+ entry.generation = Symbol('display-cache-generation');
61
+ if (entry.owner === owner) {
62
+ generation = entry.generation;
63
+ }
64
+ }
65
+ };
66
+ const device = await client._findDevice(udid);
67
+ let bootMarker = cacheable ? readBootMarker(device) : null;
68
+ const cachedPortId =
69
+ bootMarker !== null && cached && cached.screenId === displayId && cached.bootMarker === bootMarker
70
+ ? cached.portId
71
+ : undefined;
72
+ if (cached && (bootMarker === null || cached.bootMarker !== bootMarker)) {
73
+ invalidateCached();
74
+ }
75
+ return {
76
+ device,
77
+ cachedPortId,
78
+ async resolveFresh() {
79
+ if (cachedPortId !== undefined) {
80
+ invalidateCached();
81
+ }
82
+ bootMarker = cacheable ? readBootMarker(device) : null;
83
+ return await resolveDisplayPortId(device, displayId);
84
+ },
85
+ commit(portId) {
86
+ const sameBoot = bootMarker !== null && readBootMarker(device) === bootMarker;
87
+ if (!sameBoot) {
88
+ invalidateCached();
89
+ }
90
+ if (
91
+ sameBoot &&
92
+ bootMarker !== null &&
93
+ cacheable &&
94
+ portId &&
95
+ entry &&
96
+ cache?.peek(key) === entry &&
97
+ entry.owner === owner &&
98
+ entry.generation === generation
99
+ ) {
100
+ entry.display = {screenId: displayId, portId, bootMarker};
101
+ }
102
+ return sameBoot;
103
+ },
104
+ };
105
+ }
106
+
107
+ /**
108
+ * Returns a boot marker only while the device is Booted. Unsupported or unreadable metadata
109
+ * disables caching. The timestamp persists after shutdown and is not a guaranteed unique UUID.
110
+ */
111
+ function readBootMarker(device: NativeDeviceHandle): number | null {
112
+ try {
113
+ if (device.state() !== SimDeviceState.Booted) {
114
+ return null;
115
+ }
116
+ const marker = device.lastBootedAt();
117
+ return marker !== null && Number.isFinite(marker) && marker > 0 && device.state() === SimDeviceState.Booted
118
+ ? marker
119
+ : null;
120
+ } catch {
121
+ return null;
122
+ }
123
+ }