@limrun/api 0.58.1 → 0.59.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 +12 -0
- package/ios-client.d.mts +53 -4
- package/ios-client.d.mts.map +1 -1
- package/ios-client.d.ts +53 -4
- package/ios-client.d.ts.map +1 -1
- package/ios-client.js +55 -29
- package/ios-client.js.map +1 -1
- package/ios-client.mjs +55 -29
- package/ios-client.mjs.map +1 -1
- package/package.json +1 -1
- package/src/ios-client.ts +126 -39
- 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
|
@@ -405,13 +405,53 @@ export type DetoxLaunchRuntime = {
|
|
|
405
405
|
|
|
406
406
|
export type LaunchAppRuntime = DetoxLaunchRuntime;
|
|
407
407
|
|
|
408
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Why a launched or watched app shut down.
|
|
410
|
+
* - `crash`: the process died on a fatal signal; `crash` details are attached.
|
|
411
|
+
* - `exit`: the process ended without a crash and was not stopped through the SDK.
|
|
412
|
+
* - `terminated`: the app was stopped via {@link InstanceClient.terminateApp} or a relaunch.
|
|
413
|
+
*/
|
|
414
|
+
export type AppExitReason = 'crash' | 'exit' | 'terminated';
|
|
409
415
|
|
|
410
|
-
type
|
|
416
|
+
export type AppCrashInfo = {
|
|
417
|
+
processName: string;
|
|
418
|
+
pid: number;
|
|
419
|
+
/** Exception type and signal, for example `EXC_BAD_ACCESS (SIGSEGV) at 0x10`. */
|
|
420
|
+
shortMsg: string;
|
|
421
|
+
/** The crash message the app left, such as an uncaught exception's reason, else `shortMsg`. */
|
|
422
|
+
longMsg: string;
|
|
411
423
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
424
|
+
* The crashed thread's frames, with symbol names for the app's own code, followed by the
|
|
425
|
+
* binary images they belong to. Symbolicate file and line with your dSYM, for example
|
|
426
|
+
* `atos -o App.dSYM -l <load address> <frame address>`.
|
|
414
427
|
*/
|
|
428
|
+
stackTrace: string;
|
|
429
|
+
timeMillis: number;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
export type AppExitInfo = {
|
|
433
|
+
bundleId: string;
|
|
434
|
+
reason: AppExitReason;
|
|
435
|
+
crash?: AppCrashInfo;
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Called when the app shuts down. For a launched app the logs array contains one entry per
|
|
440
|
+
* stdout/stderr line that launch produced; a watched app reports no logs. `info` carries the
|
|
441
|
+
* exit reason plus crash details when applicable.
|
|
442
|
+
*/
|
|
443
|
+
export type LaunchAppExitCallback = (logs: string[], info: AppExitInfo) => Promise<void> | void;
|
|
444
|
+
|
|
445
|
+
/** Handle for an app watch registered via {@link InstanceClient.watchApp}. */
|
|
446
|
+
export type AppWatch = {
|
|
447
|
+
/** Identifier of this watch on the server. */
|
|
448
|
+
execId: string;
|
|
449
|
+
/** Cancels the watch; the onExit callback will not be invoked afterwards. */
|
|
450
|
+
stop: () => Promise<void>;
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
type LaunchAppExitOptions = {
|
|
454
|
+
/** Called once when the launched app exits, crashes, or is terminated. */
|
|
415
455
|
onExit?: LaunchAppExitCallback;
|
|
416
456
|
};
|
|
417
457
|
|
|
@@ -722,6 +762,20 @@ export type InstanceClient = {
|
|
|
722
762
|
*/
|
|
723
763
|
terminateApp: (bundleId: string) => Promise<void>;
|
|
724
764
|
|
|
765
|
+
/**
|
|
766
|
+
* Watch an app's exit or crash without launching it through {@link launchApp}, for example
|
|
767
|
+
* an app opened with {@link openUrl} or already running. The callback fires once, with the
|
|
768
|
+
* exit reason and crash details, the next time any process of the app exits. Watched apps
|
|
769
|
+
* report no logs.
|
|
770
|
+
*
|
|
771
|
+
* The app does not need to be running yet: if it starts later, it is picked up automatically.
|
|
772
|
+
*
|
|
773
|
+
* @param bundleId Bundle identifier of the app to watch
|
|
774
|
+
* @param onExit Called once when the watched app shuts down
|
|
775
|
+
* @returns A handle whose `stop()` cancels the watch
|
|
776
|
+
*/
|
|
777
|
+
watchApp: (bundleId: string, onExit: LaunchAppExitCallback) => Promise<AppWatch>;
|
|
778
|
+
|
|
725
779
|
/**
|
|
726
780
|
* Fetch the last N lines of app logs (combined stdout/stderr)
|
|
727
781
|
* @param bundleId Bundle identifier of the app
|
|
@@ -1330,6 +1384,17 @@ type SimctlRequest = {
|
|
|
1330
1384
|
/**
|
|
1331
1385
|
* Generic server response with optional error
|
|
1332
1386
|
*/
|
|
1387
|
+
/** appExit as the server sends it; its logs field is an array, unlike appLogTailResult's. */
|
|
1388
|
+
type AppExitMessage = {
|
|
1389
|
+
type: 'appExit';
|
|
1390
|
+
execId: string;
|
|
1391
|
+
bundleId: string;
|
|
1392
|
+
reason?: AppExitReason;
|
|
1393
|
+
crash?: AppCrashInfo;
|
|
1394
|
+
logs?: string[];
|
|
1395
|
+
logLineCount?: number;
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1333
1398
|
type ServerResponse = {
|
|
1334
1399
|
state?: FoldState;
|
|
1335
1400
|
type: string;
|
|
@@ -1818,14 +1883,8 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
1818
1883
|
return false;
|
|
1819
1884
|
}
|
|
1820
1885
|
|
|
1821
|
-
const { execId, bundleId
|
|
1822
|
-
if (
|
|
1823
|
-
typeof execId !== 'string' ||
|
|
1824
|
-
typeof bundleId !== 'string' ||
|
|
1825
|
-
typeof logLineCount !== 'number' ||
|
|
1826
|
-
!Number.isInteger(logLineCount) ||
|
|
1827
|
-
logLineCount < 0
|
|
1828
|
-
) {
|
|
1886
|
+
const { execId, bundleId } = message;
|
|
1887
|
+
if (typeof execId !== 'string' || typeof bundleId !== 'string') {
|
|
1829
1888
|
logger.warn('Received malformed appExit message:', message);
|
|
1830
1889
|
return true;
|
|
1831
1890
|
}
|
|
@@ -1865,6 +1924,8 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
1865
1924
|
toggleKeyboardResult: () => undefined,
|
|
1866
1925
|
launchAppResult: () => undefined,
|
|
1867
1926
|
terminateAppResult: () => undefined,
|
|
1927
|
+
watchAppResult: () => undefined,
|
|
1928
|
+
unwatchAppResult: () => undefined,
|
|
1868
1929
|
appLogTailResult: (msg) => msg.logs ?? '',
|
|
1869
1930
|
listAppsResult: (msg) => JSON.parse(msg.apps || '[]') as InstalledApp[],
|
|
1870
1931
|
listOpenFilesResult: (msg) => msg.files || [],
|
|
@@ -2071,6 +2132,7 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2071
2132
|
toggleKeyboard,
|
|
2072
2133
|
launchApp,
|
|
2073
2134
|
terminateApp,
|
|
2135
|
+
watchApp,
|
|
2074
2136
|
appLogTail,
|
|
2075
2137
|
streamAppLog,
|
|
2076
2138
|
streamSyslog,
|
|
@@ -2310,33 +2372,7 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2310
2372
|
const onExit = launchOptions.onExit;
|
|
2311
2373
|
const execId = onExit ? generateId() : undefined;
|
|
2312
2374
|
if (execId && onExit) {
|
|
2313
|
-
registerServerNotification('appExit', execId,
|
|
2314
|
-
const { bundleId, logLineCount } = message;
|
|
2315
|
-
if (
|
|
2316
|
-
typeof bundleId !== 'string' ||
|
|
2317
|
-
typeof logLineCount !== 'number' ||
|
|
2318
|
-
!Number.isInteger(logLineCount) ||
|
|
2319
|
-
logLineCount < 0
|
|
2320
|
-
) {
|
|
2321
|
-
logger.warn(`Received malformed appExit payload for execId ${execId}:`, message);
|
|
2322
|
-
return;
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
let logs: string[] = [];
|
|
2326
|
-
try {
|
|
2327
|
-
logs = splitAppLogTail(
|
|
2328
|
-
await sendRequest<string>('appLogTail', { bundleId, lines: logLineCount }),
|
|
2329
|
-
);
|
|
2330
|
-
} catch (error) {
|
|
2331
|
-
logger.error(`Failed to fetch app logs for exit execId ${execId}:`, error);
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
try {
|
|
2335
|
-
await onExit(logs);
|
|
2336
|
-
} catch (error) {
|
|
2337
|
-
logger.error(`Error in onExit callback for execId ${execId}:`, error);
|
|
2338
|
-
}
|
|
2339
|
-
});
|
|
2375
|
+
registerServerNotification('appExit', execId, appExitHandler(execId, onExit));
|
|
2340
2376
|
}
|
|
2341
2377
|
return sendRequest<void>('launchApp', {
|
|
2342
2378
|
bundleId,
|
|
@@ -2351,6 +2387,57 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
|
|
|
2351
2387
|
});
|
|
2352
2388
|
};
|
|
2353
2389
|
|
|
2390
|
+
/** Delivers one appExit to the callback, fetching the logs from servers that predate inline logs. */
|
|
2391
|
+
const appExitHandler =
|
|
2392
|
+
(execId: string, onExit: LaunchAppExitCallback): ServerNotificationHandler =>
|
|
2393
|
+
async (response) => {
|
|
2394
|
+
const message = response as unknown as AppExitMessage;
|
|
2395
|
+
let logs: string[] = [];
|
|
2396
|
+
if (Array.isArray(message.logs)) {
|
|
2397
|
+
logs = message.logs.map(String);
|
|
2398
|
+
} else if (Number.isInteger(message.logLineCount) && (message.logLineCount ?? 0) > 0) {
|
|
2399
|
+
try {
|
|
2400
|
+
logs = splitAppLogTail(
|
|
2401
|
+
await sendRequest<string>('appLogTail', {
|
|
2402
|
+
bundleId: message.bundleId,
|
|
2403
|
+
lines: message.logLineCount,
|
|
2404
|
+
}),
|
|
2405
|
+
);
|
|
2406
|
+
} catch (error) {
|
|
2407
|
+
logger.error(`Failed to fetch app logs for exit execId ${execId}:`, error);
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
const info: AppExitInfo = {
|
|
2411
|
+
bundleId: message.bundleId,
|
|
2412
|
+
// Servers before exit reasons only reported that the app ended.
|
|
2413
|
+
reason: message.reason ?? 'exit',
|
|
2414
|
+
...(message.crash ? { crash: message.crash } : {}),
|
|
2415
|
+
};
|
|
2416
|
+
try {
|
|
2417
|
+
await onExit(logs, info);
|
|
2418
|
+
} catch (error) {
|
|
2419
|
+
logger.error(`Error in onExit callback for execId ${execId}:`, error);
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
|
|
2423
|
+
const watchApp = async (bundleId: string, onExit: LaunchAppExitCallback): Promise<AppWatch> => {
|
|
2424
|
+
const execId = generateId();
|
|
2425
|
+
registerServerNotification('appExit', execId, appExitHandler(execId, onExit));
|
|
2426
|
+
try {
|
|
2427
|
+
await sendRequest<void>('watchApp', { bundleId, execId });
|
|
2428
|
+
} catch (error) {
|
|
2429
|
+
deleteServerNotification('appExit', execId);
|
|
2430
|
+
throw error;
|
|
2431
|
+
}
|
|
2432
|
+
return {
|
|
2433
|
+
execId,
|
|
2434
|
+
stop: async () => {
|
|
2435
|
+
deleteServerNotification('appExit', execId);
|
|
2436
|
+
await sendRequest<void>('unwatchApp', { execId });
|
|
2437
|
+
},
|
|
2438
|
+
};
|
|
2439
|
+
};
|
|
2440
|
+
|
|
2354
2441
|
const terminateApp = (bundleId: string): Promise<void> => {
|
|
2355
2442
|
return sendRequest<void>('terminateApp', { bundleId });
|
|
2356
2443
|
};
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.59.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.59.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.59.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.59.0'; // x-release-please-version
|
|
2
2
|
//# sourceMappingURL=version.mjs.map
|