@swmansion/argent 0.22.2-next.8 → 0.22.2-next.9

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/dist/cli-cmds.mjs CHANGED
@@ -2287,6 +2287,9 @@ var FAILURE_CODES = {
2287
2287
  SIMULATOR_SERVER_READY_TIMEOUT: "SIMULATOR_SERVER_READY_TIMEOUT",
2288
2288
  SIMULATOR_SERVER_PROCESS_ERROR: "SIMULATOR_SERVER_PROCESS_ERROR",
2289
2289
  SIMULATOR_SERVER_TERMINATED: "SIMULATOR_SERVER_TERMINATED",
2290
+ SIMULATOR_COMMAND_REJECTED: "SIMULATOR_COMMAND_REJECTED",
2291
+ SIMULATOR_COMMAND_ACK_TIMEOUT: "SIMULATOR_COMMAND_ACK_TIMEOUT",
2292
+ SIMULATOR_COMMAND_TRANSPORT_FAILED: "SIMULATOR_COMMAND_TRANSPORT_FAILED",
2290
2293
  AX_QUERY_TIMEOUT: "AX_QUERY_TIMEOUT",
2291
2294
  AX_DAEMON_READY_TIMEOUT: "AX_DAEMON_READY_TIMEOUT",
2292
2295
  AX_DAEMON_EXITED_BEFORE_READY: "AX_DAEMON_EXITED_BEFORE_READY",
@@ -7214,7 +7217,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
7214
7217
  var SESSION_ID2 = randomUUID5();
7215
7218
  function readCliVersion() {
7216
7219
  if (true) {
7217
- return "0.22.2-next.8";
7220
+ return "0.22.2-next.9";
7218
7221
  }
7219
7222
  return "0.0.0";
7220
7223
  }
@@ -15443,6 +15443,9 @@ var FAILURE_CODES = {
15443
15443
  SIMULATOR_SERVER_READY_TIMEOUT: "SIMULATOR_SERVER_READY_TIMEOUT",
15444
15444
  SIMULATOR_SERVER_PROCESS_ERROR: "SIMULATOR_SERVER_PROCESS_ERROR",
15445
15445
  SIMULATOR_SERVER_TERMINATED: "SIMULATOR_SERVER_TERMINATED",
15446
+ SIMULATOR_COMMAND_REJECTED: "SIMULATOR_COMMAND_REJECTED",
15447
+ SIMULATOR_COMMAND_ACK_TIMEOUT: "SIMULATOR_COMMAND_ACK_TIMEOUT",
15448
+ SIMULATOR_COMMAND_TRANSPORT_FAILED: "SIMULATOR_COMMAND_TRANSPORT_FAILED",
15446
15449
  AX_QUERY_TIMEOUT: "AX_QUERY_TIMEOUT",
15447
15450
  AX_DAEMON_READY_TIMEOUT: "AX_DAEMON_READY_TIMEOUT",
15448
15451
  AX_DAEMON_EXITED_BEFORE_READY: "AX_DAEMON_EXITED_BEFORE_READY",
@@ -16428,7 +16431,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16428
16431
  var SESSION_ID = randomUUID4();
16429
16432
  function readCliVersion() {
16430
16433
  if (true) {
16431
- return "0.22.2-next.8";
16434
+ return "0.22.2-next.9";
16432
16435
  }
16433
16436
  return "0.0.0";
16434
16437
  }
@@ -16471,6 +16471,9 @@ var FAILURE_CODES = {
16471
16471
  SIMULATOR_SERVER_READY_TIMEOUT: "SIMULATOR_SERVER_READY_TIMEOUT",
16472
16472
  SIMULATOR_SERVER_PROCESS_ERROR: "SIMULATOR_SERVER_PROCESS_ERROR",
16473
16473
  SIMULATOR_SERVER_TERMINATED: "SIMULATOR_SERVER_TERMINATED",
16474
+ SIMULATOR_COMMAND_REJECTED: "SIMULATOR_COMMAND_REJECTED",
16475
+ SIMULATOR_COMMAND_ACK_TIMEOUT: "SIMULATOR_COMMAND_ACK_TIMEOUT",
16476
+ SIMULATOR_COMMAND_TRANSPORT_FAILED: "SIMULATOR_COMMAND_TRANSPORT_FAILED",
16474
16477
  AX_QUERY_TIMEOUT: "AX_QUERY_TIMEOUT",
16475
16478
  AX_DAEMON_READY_TIMEOUT: "AX_DAEMON_READY_TIMEOUT",
16476
16479
  AX_DAEMON_EXITED_BEFORE_READY: "AX_DAEMON_EXITED_BEFORE_READY",
@@ -628,6 +628,9 @@ var init_failure_codes = __esm({
628
628
  SIMULATOR_SERVER_READY_TIMEOUT: "SIMULATOR_SERVER_READY_TIMEOUT",
629
629
  SIMULATOR_SERVER_PROCESS_ERROR: "SIMULATOR_SERVER_PROCESS_ERROR",
630
630
  SIMULATOR_SERVER_TERMINATED: "SIMULATOR_SERVER_TERMINATED",
631
+ SIMULATOR_COMMAND_REJECTED: "SIMULATOR_COMMAND_REJECTED",
632
+ SIMULATOR_COMMAND_ACK_TIMEOUT: "SIMULATOR_COMMAND_ACK_TIMEOUT",
633
+ SIMULATOR_COMMAND_TRANSPORT_FAILED: "SIMULATOR_COMMAND_TRANSPORT_FAILED",
631
634
  AX_QUERY_TIMEOUT: "AX_QUERY_TIMEOUT",
632
635
  AX_DAEMON_READY_TIMEOUT: "AX_DAEMON_READY_TIMEOUT",
633
636
  AX_DAEMON_EXITED_BEFORE_READY: "AX_DAEMON_EXITED_BEFORE_READY",
@@ -93890,7 +93893,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
93890
93893
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
93891
93894
  function readCliVersion() {
93892
93895
  if (true) {
93893
- return "0.22.2-next.8";
93896
+ return "0.22.2-next.9";
93894
93897
  }
93895
93898
  return "0.0.0";
93896
93899
  }
@@ -106325,33 +106328,127 @@ var DEFAULT_SCREENSHOT_SCALE = 0.25;
106325
106328
  var NO_IMAGE_ERROR = /no image to export/i;
106326
106329
  var FIRST_FRAME_WAIT_MS = 6e3;
106327
106330
  var FIRST_FRAME_POLL_MS = 250;
106331
+ var COMMAND_ACK_TIMEOUT_MS = 5e3;
106328
106332
  var connections = /* @__PURE__ */ new Map();
106329
106333
  var cmdId = 0;
106330
- function getOrCreateWs(api) {
106334
+ function failAllPending(conn, makeError) {
106335
+ const entries = [...conn.pending.values()];
106336
+ conn.pending.clear();
106337
+ for (const entry of entries) entry.settle(makeError(entry.cmd));
106338
+ }
106339
+ function transportError(cmd, apiUrl, detail) {
106340
+ return new FailureError(
106341
+ `simulator-server did not accept the '${cmd}' command: ${detail}. The command was NOT delivered to the device. Check that the simulator is still booted and the simulator-server for ${apiUrl} is running.`,
106342
+ {
106343
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_TRANSPORT_FAILED,
106344
+ failure_stage: "simulator_command_transport",
106345
+ failure_area: "tool_server",
106346
+ error_kind: "network",
106347
+ network_failure: "connection_reset",
106348
+ failure_command: "simulator_server"
106349
+ }
106350
+ );
106351
+ }
106352
+ function getOrCreateConnection(api) {
106331
106353
  const key2 = api.apiUrl;
106332
106354
  const existing = connections.get(key2);
106333
- if (existing && (existing.readyState === wrapper_default.OPEN || existing.readyState === wrapper_default.CONNECTING)) {
106355
+ if (existing && (existing.ws.readyState === wrapper_default.OPEN || existing.ws.readyState === wrapper_default.CONNECTING)) {
106334
106356
  return existing;
106335
106357
  }
106336
106358
  const { host } = new URL(api.apiUrl);
106337
106359
  const ws = new wrapper_default(`ws://${host}/ws`);
106338
- ws.on("error", () => connections.delete(key2));
106339
- ws.on("close", () => connections.delete(key2));
106340
- connections.set(key2, ws);
106341
- return ws;
106360
+ const conn = { ws, pending: /* @__PURE__ */ new Map() };
106361
+ ws.on("message", (data) => {
106362
+ const text = Buffer.isBuffer(data) ? data.toString() : Array.isArray(data) ? Buffer.concat(data).toString() : Buffer.from(data).toString();
106363
+ let ack;
106364
+ try {
106365
+ ack = JSON.parse(text);
106366
+ } catch {
106367
+ return;
106368
+ }
106369
+ if (ack.status !== "ok" && ack.status !== "error") return;
106370
+ if (ack.id != null && !conn.pending.has(ack.id)) return;
106371
+ const id = ack.id ?? conn.pending.keys().next().value;
106372
+ if (id == null) return;
106373
+ const entry = conn.pending.get(id);
106374
+ if (entry == null) return;
106375
+ conn.pending.delete(id);
106376
+ if (ack.status === "ok") {
106377
+ entry.settle();
106378
+ return;
106379
+ }
106380
+ entry.settle(
106381
+ new FailureError(
106382
+ `simulator-server rejected the '${entry.cmd}' command: ${ack.message ?? "unknown error"}. The command was NOT delivered to the device.`,
106383
+ {
106384
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_REJECTED,
106385
+ failure_stage: "simulator_command_rejected",
106386
+ failure_area: "tool_server",
106387
+ error_kind: "unknown",
106388
+ failure_command: "simulator_server"
106389
+ }
106390
+ )
106391
+ );
106392
+ });
106393
+ ws.on("error", (err) => {
106394
+ connections.delete(key2);
106395
+ failAllPending(conn, (cmd) => transportError(cmd, key2, err.message));
106396
+ });
106397
+ ws.on("close", () => {
106398
+ connections.delete(key2);
106399
+ failAllPending(conn, (cmd) => transportError(cmd, key2, "the connection closed"));
106400
+ });
106401
+ connections.set(key2, conn);
106402
+ return conn;
106342
106403
  }
106343
106404
  function sendCommand(api, cmd) {
106344
106405
  if (api.transport) {
106345
106406
  routeViaTransport(api.transport, cmd);
106346
- return;
106347
- }
106348
- const ws = getOrCreateWs(api);
106349
- const payload = JSON.stringify({ id: String(++cmdId), ...cmd });
106350
- if (ws.readyState === wrapper_default.OPEN) {
106351
- ws.send(payload);
106352
- } else {
106353
- ws.once("open", () => ws.send(payload));
106407
+ return Promise.resolve();
106354
106408
  }
106409
+ const conn = getOrCreateConnection(api);
106410
+ const id = String(++cmdId);
106411
+ const cmdName = typeof cmd.cmd === "string" ? cmd.cmd : "unknown";
106412
+ const payload = JSON.stringify({ id, ...cmd });
106413
+ return new Promise((resolve12, reject) => {
106414
+ let done = false;
106415
+ const settle = (err) => {
106416
+ if (done) return;
106417
+ done = true;
106418
+ clearTimeout(timer);
106419
+ conn.pending.delete(id);
106420
+ if (err) reject(err);
106421
+ else resolve12();
106422
+ };
106423
+ const timer = setTimeout(
106424
+ () => settleAndDropConnection(
106425
+ new FailureError(
106426
+ `simulator-server did not acknowledge the '${cmdName}' command within ${COMMAND_ACK_TIMEOUT_MS}ms. The command may not have reached the device \u2014 the simulator may be wedged or the simulator-server unresponsive.`,
106427
+ {
106428
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_ACK_TIMEOUT,
106429
+ failure_stage: "simulator_command_ack",
106430
+ failure_area: "tool_server",
106431
+ error_kind: "timeout",
106432
+ network_failure: "timeout",
106433
+ failure_command: "simulator_server"
106434
+ }
106435
+ )
106436
+ ),
106437
+ COMMAND_ACK_TIMEOUT_MS
106438
+ );
106439
+ timer.unref?.();
106440
+ const settleAndDropConnection = (err) => {
106441
+ settle(err);
106442
+ connections.delete(api.apiUrl);
106443
+ conn.ws.close();
106444
+ };
106445
+ conn.pending.set(id, { settle, cmd: cmdName });
106446
+ const write = () => conn.ws.send(payload, (err) => {
106447
+ if (err) settle(transportError(cmdName, api.apiUrl, err.message));
106448
+ });
106449
+ if (conn.ws.readyState === wrapper_default.OPEN) write();
106450
+ else conn.ws.once("open", write);
106451
+ });
106355
106452
  }
106356
106453
  function setPointerVisible(api, show, signal) {
106357
106454
  return pointerPost(api, { show }, signal);
@@ -119444,7 +119541,7 @@ Before tapping, determine the correct coordinates by using discovery tools \u201
119444
119541
  const api = services.simulatorServer;
119445
119542
  for (let i = 1; i <= clickCount; i++) {
119446
119543
  if (i > 1) await sleep2(MULTI_TAP_GAP_MS);
119447
- sendCommand(api, {
119544
+ await sendCommand(api, {
119448
119545
  cmd: "touch",
119449
119546
  type: "Down",
119450
119547
  x: params.x,
@@ -119453,7 +119550,7 @@ Before tapping, determine the correct coordinates by using discovery tools \u201
119453
119550
  second_y: null
119454
119551
  });
119455
119552
  await sleep2(TAP_HOLD_MS);
119456
- sendCommand(api, {
119553
+ await sendCommand(api, {
119457
119554
  cmd: "touch",
119458
119555
  type: "Up",
119459
119556
  x: params.x,
@@ -119538,20 +119635,24 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119538
119635
  let lastY = 0;
119539
119636
  for (let i = 0; i <= steps; i++) {
119540
119637
  if (ctx?.signal?.aborted) {
119541
- if (i > 0) {
119542
- sendCommand(api, {
119543
- cmd: "touch",
119544
- type: "Up",
119545
- x: lastX,
119546
- y: lastY,
119547
- second_x: null,
119548
- second_y: null
119549
- });
119550
- }
119551
119638
  const err = new Error(
119552
119639
  `gesture-swipe aborted - cancelled mid-gesture after ${i} of ${steps + 1} frames`
119553
119640
  );
119554
119641
  err.name = "AbortError";
119642
+ if (i > 0) {
119643
+ try {
119644
+ await sendCommand(api, {
119645
+ cmd: "touch",
119646
+ type: "Up",
119647
+ x: lastX,
119648
+ y: lastY,
119649
+ second_x: null,
119650
+ second_y: null
119651
+ });
119652
+ } catch (liftErr) {
119653
+ err.cause = liftErr;
119654
+ }
119655
+ }
119555
119656
  throw err;
119556
119657
  }
119557
119658
  const t = i / steps;
@@ -119560,7 +119661,7 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119560
119661
  const y = params.fromY + (params.toY - params.fromY) * progress;
119561
119662
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
119562
119663
  if (type === "Up") {
119563
- sendCommand(api, {
119664
+ await sendCommand(api, {
119564
119665
  cmd: "touch",
119565
119666
  type: "Move",
119566
119667
  x,
@@ -119569,7 +119670,7 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119569
119670
  second_y: null
119570
119671
  });
119571
119672
  }
119572
- sendCommand(api, {
119673
+ await sendCommand(api, {
119573
119674
  cmd: "touch",
119574
119675
  type,
119575
119676
  x,
@@ -119812,7 +119913,7 @@ function interpolateEvents(events, steps) {
119812
119913
  return result;
119813
119914
  }
119814
119915
  function sendTouchEvent(api, type, x, y, x2, y2) {
119815
- sendCommand(api, {
119916
+ return sendCommand(api, {
119816
119917
  cmd: "touch",
119817
119918
  type,
119818
119919
  x,
@@ -119883,7 +119984,7 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
119883
119984
  const events = params.interpolate && params.interpolate > 0 ? interpolateEvents(params.events, params.interpolate) : params.events;
119884
119985
  for (const event2 of events) {
119885
119986
  await sleep6(event2.delayMs ?? 16);
119886
- sendCommand(api, {
119987
+ await sendCommand(api, {
119887
119988
  cmd: "touch",
119888
119989
  type: event2.type,
119889
119990
  x: event2.x,
@@ -119966,7 +120067,7 @@ Use when you need to zoom in or out on a map, image, or zoomable view. Returns {
119966
120067
  const y2 = cy + halfDist * sinA;
119967
120068
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
119968
120069
  if (i === 0) timestampMs = Date.now();
119969
- sendTouchEvent(api, type, x1, y1, x2, y2);
120070
+ await sendTouchEvent(api, type, x1, y1, x2, y2);
119970
120071
  if (i < steps) await sleep(16);
119971
120072
  }
119972
120073
  return { pinched: true, timestampMs };
@@ -120044,11 +120145,17 @@ Size the orbit with radius, or with radiusX and radiusY together (the pair overr
120044
120145
  let lastY2 = 0;
120045
120146
  for (let i = 0; i <= steps; i++) {
120046
120147
  if (ctx?.signal?.aborted) {
120047
- if (i > 0) sendTouchEvent(api, "Up", lastX1, lastY1, lastX2, lastY2);
120048
120148
  const err = new Error(
120049
120149
  `gesture-rotate aborted \u2014 cancelled mid-gesture after ${i} of ${steps + 1} frames`
120050
120150
  );
120051
120151
  err.name = "AbortError";
120152
+ if (i > 0) {
120153
+ try {
120154
+ await sendTouchEvent(api, "Up", lastX1, lastY1, lastX2, lastY2);
120155
+ } catch (liftErr) {
120156
+ err.cause = liftErr;
120157
+ }
120158
+ }
120052
120159
  throw err;
120053
120160
  }
120054
120161
  const t = i / steps;
@@ -120060,7 +120167,7 @@ Size the orbit with radius, or with radiusX and radiusY together (the pair overr
120060
120167
  const y2 = params.centerY - radiusY * Math.sin(angleRad);
120061
120168
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
120062
120169
  if (i === 0) timestampMs = Date.now();
120063
- sendTouchEvent(api, type, x1, y1, x2, y2);
120170
+ await sendTouchEvent(api, type, x1, y1, x2, y2);
120064
120171
  lastX1 = x1;
120065
120172
  lastY1 = y1;
120066
120173
  lastX2 = x2;
@@ -120129,13 +120236,13 @@ Fails if the device backend is not reachable \u2014 the simulator-server for iOS
120129
120236
  return { pressed: params.button };
120130
120237
  }
120131
120238
  const api = services.simulatorServer;
120132
- sendCommand(api, {
120239
+ await sendCommand(api, {
120133
120240
  cmd: "button",
120134
120241
  direction: "Down",
120135
120242
  button: params.button
120136
120243
  });
120137
120244
  await sleep7(50);
120138
- sendCommand(api, { cmd: "button", direction: "Up", button: params.button });
120245
+ await sendCommand(api, { cmd: "button", direction: "Up", button: params.button });
120139
120246
  return { pressed: params.button };
120140
120247
  }
120141
120248
  };
@@ -120946,7 +121053,7 @@ Returns { orientation }. Fails if the target device is not booted.`,
120946
121053
  }),
120947
121054
  async execute(services, params) {
120948
121055
  const api = services.simulatorServer;
120949
- sendCommand(api, { cmd: "rotate", direction: params.orientation });
121056
+ await sendCommand(api, { cmd: "rotate", direction: params.orientation });
120950
121057
  return { orientation: params.orientation };
120951
121058
  }
120952
121059
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.22.2-next.8",
3
+ "version": "0.22.2-next.9",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",