@limrun/api 0.57.0 → 0.58.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 +13 -0
- package/ios-client.d.mts +23 -4
- package/ios-client.d.mts.map +1 -1
- package/ios-client.d.ts +23 -4
- package/ios-client.d.ts.map +1 -1
- package/ios-client.js +22 -9
- package/ios-client.js.map +1 -1
- package/ios-client.mjs +22 -9
- package/ios-client.mjs.map +1 -1
- package/package.json +1 -1
- package/src/ios-client.ts +86 -22
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/ios-client.ts
CHANGED
|
@@ -253,14 +253,18 @@ export type LsofEntry = {
|
|
|
253
253
|
path: string;
|
|
254
254
|
};
|
|
255
255
|
|
|
256
|
+
export type DuoDisplay = 'outer' | 'inner';
|
|
257
|
+
|
|
256
258
|
export type FoldDisplay = {
|
|
257
|
-
id:
|
|
259
|
+
id: DuoDisplay;
|
|
258
260
|
screenId: number;
|
|
259
261
|
trackId: string;
|
|
260
262
|
width: number;
|
|
261
263
|
height: number;
|
|
262
264
|
scale: number;
|
|
263
265
|
orientation: number;
|
|
266
|
+
/** True when this display presents content. Omitted if native activity is unavailable; transitions may activate both panels. */
|
|
267
|
+
active?: boolean;
|
|
264
268
|
};
|
|
265
269
|
|
|
266
270
|
export type DuoOrientation = 'portrait' | 'pud' | 'landscape-left' | 'landscape-right';
|
|
@@ -495,6 +499,8 @@ export type AppInstallationOptions = {
|
|
|
495
499
|
* HID primitives (`touchDown`/`touchMove`/`touchUp`, `keyDown`/`keyUp`,
|
|
496
500
|
* `buttonDown`/`buttonUp`) are deliberately unpaired so callers can build
|
|
497
501
|
* their own gestures (e.g. long-press = `touchDown` + `wait` + `touchUp`).
|
|
502
|
+
* Supply x2 and y2 together for a second touch, keeping the same contact count
|
|
503
|
+
* through down, move, and up. Both contacts use the selected display space.
|
|
498
504
|
*/
|
|
499
505
|
export type PerformAction =
|
|
500
506
|
| { type: 'tap'; x: number; y: number; screenWidth?: number; screenHeight?: number }
|
|
@@ -518,9 +524,33 @@ export type PerformAction =
|
|
|
518
524
|
| { type: 'openUrl'; url: string }
|
|
519
525
|
| { type: 'setOrientation'; orientation: 'Portrait' | 'Landscape' }
|
|
520
526
|
| { type: 'wait'; durationMs: number }
|
|
521
|
-
| {
|
|
522
|
-
|
|
523
|
-
|
|
527
|
+
| {
|
|
528
|
+
type: 'touchDown';
|
|
529
|
+
x: number;
|
|
530
|
+
y: number;
|
|
531
|
+
x2?: number;
|
|
532
|
+
y2?: number;
|
|
533
|
+
screenWidth?: number;
|
|
534
|
+
screenHeight?: number;
|
|
535
|
+
}
|
|
536
|
+
| {
|
|
537
|
+
type: 'touchMove';
|
|
538
|
+
x: number;
|
|
539
|
+
y: number;
|
|
540
|
+
x2?: number;
|
|
541
|
+
y2?: number;
|
|
542
|
+
screenWidth?: number;
|
|
543
|
+
screenHeight?: number;
|
|
544
|
+
}
|
|
545
|
+
| {
|
|
546
|
+
type: 'touchUp';
|
|
547
|
+
x: number;
|
|
548
|
+
y: number;
|
|
549
|
+
x2?: number;
|
|
550
|
+
y2?: number;
|
|
551
|
+
screenWidth?: number;
|
|
552
|
+
screenHeight?: number;
|
|
553
|
+
}
|
|
524
554
|
| { type: 'keyDown'; keyCode: number }
|
|
525
555
|
| { type: 'keyUp'; keyCode: number }
|
|
526
556
|
| {
|
|
@@ -577,7 +607,7 @@ export type IosMicrophoneStatus = {
|
|
|
577
607
|
*/
|
|
578
608
|
export type InstanceClient = {
|
|
579
609
|
/**
|
|
580
|
-
* Take a screenshot of the
|
|
610
|
+
* Take a screenshot of the active screen
|
|
581
611
|
* @returns A promise that resolves to the screenshot data with base64 image and dimensions
|
|
582
612
|
*/
|
|
583
613
|
screenshot: () => Promise<ScreenshotData>;
|
|
@@ -597,7 +627,7 @@ export type InstanceClient = {
|
|
|
597
627
|
elementTreeRaw: (point?: AccessibilityPoint) => Promise<string>;
|
|
598
628
|
|
|
599
629
|
/**
|
|
600
|
-
* Tap at the specified coordinates (uses
|
|
630
|
+
* Tap at the specified coordinates on the active screen (uses native screen dimensions)
|
|
601
631
|
* @param x X coordinate in points
|
|
602
632
|
* @param y Y coordinate in points
|
|
603
633
|
*/
|
|
@@ -764,13 +794,14 @@ export type InstanceClient = {
|
|
|
764
794
|
* @param direction Direction content moves: "up", "down", "left", "right"
|
|
765
795
|
* @param pixels Total pixels to scroll (finger movement distance)
|
|
766
796
|
* @param options Optional scroll options
|
|
797
|
+
* @param options.display Duo display to scroll, in upright screenshotDisplay points. Omit to use the active display.
|
|
767
798
|
* @param options.coordinate Starting coordinate [x, y]. Defaults to screen center.
|
|
768
799
|
* @param options.momentum 0.0-1.0 controlling scroll speed and inertia. 0 (default) = slow scroll, no momentum. 1 = fastest with max inertia.
|
|
769
800
|
*/
|
|
770
801
|
scroll: (
|
|
771
802
|
direction: 'up' | 'down' | 'left' | 'right',
|
|
772
803
|
pixels: number,
|
|
773
|
-
options?: { coordinate?: [number, number]; momentum?: number },
|
|
804
|
+
options?: { coordinate?: [number, number]; momentum?: number; display?: DuoDisplay },
|
|
774
805
|
) => Promise<void>;
|
|
775
806
|
|
|
776
807
|
/**
|
|
@@ -793,23 +824,31 @@ export type InstanceClient = {
|
|
|
793
824
|
* `options.timeoutMs` to override.
|
|
794
825
|
*
|
|
795
826
|
* @param actions The actions to run in order.
|
|
827
|
+
* @param options.display Duo display for coordinate taps, scrolls, and raw touches.
|
|
828
|
+
* Uses upright screenshotDisplay points. Omit to use the active display. Element actions follow the active display.
|
|
796
829
|
* @param options.timeoutMs Custom client-side timeout in milliseconds.
|
|
797
830
|
* @throws If any action fails — subsequent actions are not executed.
|
|
798
831
|
*/
|
|
799
832
|
performActions: (
|
|
800
833
|
actions: PerformAction[],
|
|
801
|
-
options?: { timeoutMs?: number },
|
|
834
|
+
options?: { timeoutMs?: number; display?: DuoDisplay },
|
|
802
835
|
) => Promise<PerformActionsResult>;
|
|
803
836
|
|
|
804
837
|
/**
|
|
805
|
-
* Start recording
|
|
838
|
+
* Start recording the active screen. Use stopRecording() to stop the recording.
|
|
839
|
+
* On Duo, follows native display activity and fits each panel into the initial
|
|
840
|
+
* canvas without stretching. Pass display to keep recording one panel.
|
|
806
841
|
* When provided, `quality` must be one of `5`, `6`, `7`, `8`, `9`, or `10`.
|
|
807
842
|
* The server default is `5`.
|
|
808
843
|
* With `persist`, the completed recording is uploaded to Limrun's bucket
|
|
809
844
|
* when the recording stops or the instance terminates; list it with
|
|
810
845
|
* `iosInstances.listRecordings`.
|
|
811
846
|
*/
|
|
812
|
-
startRecording: (options?: {
|
|
847
|
+
startRecording: (options?: {
|
|
848
|
+
quality?: RecordingQuality;
|
|
849
|
+
persist?: PersistOption;
|
|
850
|
+
display?: DuoDisplay;
|
|
851
|
+
}) => Promise<void>;
|
|
813
852
|
|
|
814
853
|
/**
|
|
815
854
|
* Stop the active server-side recording.
|
|
@@ -2108,12 +2147,9 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2108
2147
|
};
|
|
2109
2148
|
|
|
2110
2149
|
const tap = (x: number, y: number): Promise<void> => {
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
screenWidth: cachedDeviceInfo?.screenWidth,
|
|
2115
|
-
screenHeight: cachedDeviceInfo?.screenHeight,
|
|
2116
|
-
});
|
|
2150
|
+
// Connection-time dimensions can describe a different panel or orientation.
|
|
2151
|
+
// Native-point taps leave geometry selection to the server.
|
|
2152
|
+
return sendRequest<void>('tap', { x, y });
|
|
2117
2153
|
};
|
|
2118
2154
|
|
|
2119
2155
|
/**
|
|
@@ -2187,14 +2223,29 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2187
2223
|
// anchored drag lands in the wrong place in landscape. The server
|
|
2188
2224
|
// starts center-screen in rotated space, which halves the effective
|
|
2189
2225
|
// page but stays correct in every orientation.
|
|
2190
|
-
|
|
2226
|
+
let pageHeight = cachedDeviceInfo.screenHeight;
|
|
2227
|
+
let display: DuoDisplay | undefined;
|
|
2228
|
+
if (cachedDeviceInfo.model === 'iPhone Duo') {
|
|
2229
|
+
const state = await getFoldState();
|
|
2230
|
+
const activeDisplays = state?.displays.filter((candidate) => candidate.active) ?? [];
|
|
2231
|
+
if (activeDisplays.length !== 1) {
|
|
2232
|
+
throw new Error(
|
|
2233
|
+
'Scroll search requires exactly one active Duo display; retry after the fold settles.',
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
const active = activeDisplays[0]!;
|
|
2237
|
+
display = active.id;
|
|
2238
|
+
const rotated = active.orientation === 3 || active.orientation === 4;
|
|
2239
|
+
pageHeight = (rotated ? active.width : active.height) / active.scale;
|
|
2240
|
+
}
|
|
2241
|
+
const pagePixels = Math.round(pageHeight * 0.6);
|
|
2191
2242
|
for (const [direction, count] of [
|
|
2192
2243
|
['down', 3],
|
|
2193
2244
|
['up', 6],
|
|
2194
2245
|
] as const) {
|
|
2195
2246
|
for (let page = 0; page < count; page += 1) {
|
|
2196
2247
|
if (Date.now() >= deadline) break;
|
|
2197
|
-
await scroll(direction, pagePixels);
|
|
2248
|
+
await scroll(direction, pagePixels, display ? { display } : undefined);
|
|
2198
2249
|
// Let lazily-materializing cells appear before re-reading.
|
|
2199
2250
|
await sleep(300);
|
|
2200
2251
|
try {
|
|
@@ -2386,33 +2437,45 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2386
2437
|
const scroll = (
|
|
2387
2438
|
direction: 'up' | 'down' | 'left' | 'right',
|
|
2388
2439
|
pixels: number,
|
|
2389
|
-
options?: { coordinate?: [number, number]; momentum?: number },
|
|
2440
|
+
options?: { coordinate?: [number, number]; momentum?: number; display?: DuoDisplay },
|
|
2390
2441
|
): Promise<void> => {
|
|
2391
2442
|
return sendRequest<void>('scroll', {
|
|
2392
2443
|
direction,
|
|
2393
2444
|
pixels,
|
|
2394
2445
|
coordinate: options?.coordinate,
|
|
2395
2446
|
momentum: options?.momentum,
|
|
2447
|
+
display: options?.display,
|
|
2396
2448
|
});
|
|
2397
2449
|
};
|
|
2398
2450
|
|
|
2399
2451
|
const performActions = (
|
|
2400
2452
|
actions: PerformAction[],
|
|
2401
|
-
options?: { timeoutMs?: number },
|
|
2453
|
+
options?: { timeoutMs?: number; display?: DuoDisplay },
|
|
2402
2454
|
): Promise<PerformActionsResult> => {
|
|
2403
2455
|
// Batch duration is unbounded (user-supplied `wait` durations, plus
|
|
2404
2456
|
// per-action server work), so we grow the timeout with the batch
|
|
2405
2457
|
// rather than sticking to sendRequest's 30s default.
|
|
2406
2458
|
const waitMs = actions.reduce((acc, a) => acc + (a.type === 'wait' ? Math.max(0, a.durationMs) : 0), 0);
|
|
2407
2459
|
const timeoutMs = options?.timeoutMs ?? 30_000 + waitMs + actions.length * 2_000;
|
|
2408
|
-
return sendRequest<PerformActionsResult>(
|
|
2460
|
+
return sendRequest<PerformActionsResult>(
|
|
2461
|
+
'performActions',
|
|
2462
|
+
{ actions, display: options?.display },
|
|
2463
|
+
undefined,
|
|
2464
|
+
timeoutMs,
|
|
2465
|
+
);
|
|
2409
2466
|
};
|
|
2410
2467
|
|
|
2411
2468
|
const startRecording = async (opts?: {
|
|
2412
2469
|
quality?: RecordingQuality;
|
|
2413
2470
|
persist?: PersistOption;
|
|
2471
|
+
display?: DuoDisplay;
|
|
2414
2472
|
}): Promise<void> => {
|
|
2415
|
-
const request: {
|
|
2473
|
+
const request: {
|
|
2474
|
+
quality?: RecordingQuality;
|
|
2475
|
+
persist?: boolean;
|
|
2476
|
+
ttlSeconds?: number;
|
|
2477
|
+
display?: DuoDisplay;
|
|
2478
|
+
} = {
|
|
2416
2479
|
...persistFields(opts?.persist),
|
|
2417
2480
|
};
|
|
2418
2481
|
if (opts?.quality !== undefined) {
|
|
@@ -2421,6 +2484,7 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2421
2484
|
}
|
|
2422
2485
|
request.quality = opts.quality;
|
|
2423
2486
|
}
|
|
2487
|
+
if (opts?.display !== undefined) request.display = opts.display;
|
|
2424
2488
|
await sendRequest<void>('startVideoRecording', request);
|
|
2425
2489
|
};
|
|
2426
2490
|
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.58.0'; // x-release-please-version
|
package/version.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.58.0";
|
|
2
2
|
//# sourceMappingURL=version.d.mts.map
|
package/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.58.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/version.js
CHANGED
package/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.58.0'; // x-release-please-version
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|