@palgroup/simstream 0.6.0 → 0.8.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/dist/index.d.ts CHANGED
@@ -41,10 +41,24 @@ export interface DeviceKind {
41
41
  count: number;
42
42
  free: number;
43
43
  }
44
+ /**
45
+ * Which of a simulator's two apps something is.
46
+ *
47
+ * ‼️ A PREVIEW HOST IS NOT THE APP. `preview` is a build whose @main is generated: it carries every
48
+ * screen the project was written with and swaps between them live, which is what to look at while a
49
+ * screen is being built. `app` is the person's own binary, launched from their own @main — the only
50
+ * one that runs their launch sequence, their delegate, their deep links and their navigation, and so
51
+ * the only one that is the app rather than a picture of it.
52
+ *
53
+ * Nothing in a .app says which it is, so whoever built it says so when they push it.
54
+ */
55
+ export type SimMode = 'app' | 'preview';
44
56
  export interface AppStatus {
45
57
  /** Empty when nothing has been pushed to this simulator yet. */
46
58
  phase?: 'downloading' | 'installing' | 'launching' | 'ready' | 'failed';
47
59
  bundle?: string;
60
+ /** Which of the two this install is, when the push said so. */
61
+ mode?: SimMode;
48
62
  /** Present only with phase 'failed', and it says what went wrong rather than that it did. */
49
63
  error?: string;
50
64
  elapsed?: string;
@@ -61,6 +75,11 @@ export interface StartOptions {
61
75
  device?: string;
62
76
  /** Launch it once installed. Default true. */
63
77
  launch?: boolean;
78
+ /**
79
+ * Which of the simulator's two apps `app` is. Say so whenever you intend to push the other one
80
+ * too: an unlabelled build runs perfectly well and simply cannot be switched away from.
81
+ */
82
+ mode?: SimMode;
64
83
  /**
65
84
  * Wait for a device when the fleet is full or this customer is at its limit, instead of
66
85
  * failing. The wait is usually seconds — a session ends every time somebody closes a tab.
@@ -93,6 +112,20 @@ export interface CustomerUsage {
93
112
  live: number;
94
113
  cost: number;
95
114
  }
115
+ /** What a simulator says about its own two apps. */
116
+ export interface SessionMode {
117
+ /** What is on screen. Absent on a simulator holding one unlabelled build. */
118
+ running?: SimMode;
119
+ /** What it can be switched to, right now. */
120
+ holds: SimMode[];
121
+ /** The bundle id on screen, so two launches of the same mode are tellable apart. */
122
+ bundle?: string;
123
+ /**
124
+ * Whether what is on screen takes live screen selection. False in `app` mode, and that is not a
125
+ * fault: the person's own binary carries no listener of ours.
126
+ */
127
+ live: boolean;
128
+ }
96
129
  export type SimStreamErrorCode = 'unauthorized' | 'quota' | 'capacity' | 'timeout' | 'gone' | 'http';
97
130
  export declare class SimStreamError extends Error {
98
131
  readonly code: SimStreamErrorCode;
@@ -128,6 +161,7 @@ export declare class SimStream {
128
161
  pushBuild(app: string, opts?: {
129
162
  version?: string;
130
163
  launch?: boolean;
164
+ mode?: SimMode;
131
165
  }): Promise<{
132
166
  hosts: number;
133
167
  version?: string;
@@ -183,6 +217,35 @@ export declare class SimStream {
183
217
  screen?: string;
184
218
  variant?: string;
185
219
  }): Promise<void>;
220
+ /**
221
+ * Which of the simulator's two apps is on screen, and what it can be switched to.
222
+ *
223
+ * ‼️ THIS IS A LAUNCH, AND showPreview IS A MESSAGE. Picking a screen lands inside the process
224
+ * that is already running and arrives in a frame. Switching mode is a different bundle with a
225
+ * different bundle id, so it costs a terminate and a start — a second or two, because both builds
226
+ * are already on the device, rather than the build it would otherwise mean.
227
+ *
228
+ * `setMode` is rejected when that simulator was never given the build being asked for, and the
229
+ * message says which of the two it IS holding — "no app build" and "no build at all" send you to
230
+ * different places. Push both, labelled, and the switch is always available.
231
+ */
232
+ mode(session: string): Promise<SessionMode>;
233
+ /**
234
+ * Run the person's own app, or go back to the preview host.
235
+ *
236
+ * See `mode()` for reading where a session stands without moving it — which is what a panel
237
+ * drawing the toggle needs on load, because POSTing the mode it GUESSES is current is a relaunch
238
+ * every time the guess is wrong.
239
+ */
240
+ setMode(session: string, mode: SimMode): Promise<SessionMode>;
241
+ /**
242
+ * Press one of the simulator's hardware buttons.
243
+ *
244
+ * ‼️ A VIEWER EMBEDDED IN A PANEL CANNOT REACH THESE. The viewer page carries touch and keyboard,
245
+ * but home, lock and siri are the device's own buttons and live outside the screen it draws — so a
246
+ * customer showing the simulator inside their own product has no way to send them without this.
247
+ */
248
+ pressButton(session: string, button: 'home' | 'lock' | 'siri'): Promise<void>;
186
249
  /**
187
250
  * The language and theme the app renders in, changed live.
188
251
  *
package/dist/index.js CHANGED
@@ -56,6 +56,7 @@ class SimStream {
56
56
  const body = {
57
57
  app: opts.app,
58
58
  launch: opts.launch,
59
+ mode: opts.mode,
59
60
  queue: opts.wait === true,
60
61
  device: opts.device,
61
62
  };
@@ -95,6 +96,7 @@ class SimStream {
95
96
  app,
96
97
  version: opts.version,
97
98
  launch: opts.launch,
99
+ mode: opts.mode,
98
100
  });
99
101
  if (res.status !== 200)
100
102
  throw await this.errorFor(res);
@@ -163,6 +165,49 @@ class SimStream {
163
165
  if (res.status !== 200)
164
166
  throw await this.errorFor(res);
165
167
  }
168
+ /**
169
+ * Which of the simulator's two apps is on screen, and what it can be switched to.
170
+ *
171
+ * ‼️ THIS IS A LAUNCH, AND showPreview IS A MESSAGE. Picking a screen lands inside the process
172
+ * that is already running and arrives in a frame. Switching mode is a different bundle with a
173
+ * different bundle id, so it costs a terminate and a start — a second or two, because both builds
174
+ * are already on the device, rather than the build it would otherwise mean.
175
+ *
176
+ * `setMode` is rejected when that simulator was never given the build being asked for, and the
177
+ * message says which of the two it IS holding — "no app build" and "no build at all" send you to
178
+ * different places. Push both, labelled, and the switch is always available.
179
+ */
180
+ async mode(session) {
181
+ const res = await this.request('GET', `/api/session/mode?session=${encodeURIComponent(session)}`);
182
+ if (res.status !== 200)
183
+ throw await this.errorFor(res);
184
+ return (await res.json());
185
+ }
186
+ /**
187
+ * Run the person's own app, or go back to the preview host.
188
+ *
189
+ * See `mode()` for reading where a session stands without moving it — which is what a panel
190
+ * drawing the toggle needs on load, because POSTing the mode it GUESSES is current is a relaunch
191
+ * every time the guess is wrong.
192
+ */
193
+ async setMode(session, mode) {
194
+ const res = await this.request('POST', '/api/session/mode', { session, mode });
195
+ if (res.status !== 200)
196
+ throw await this.errorFor(res);
197
+ return (await res.json());
198
+ }
199
+ /**
200
+ * Press one of the simulator's hardware buttons.
201
+ *
202
+ * ‼️ A VIEWER EMBEDDED IN A PANEL CANNOT REACH THESE. The viewer page carries touch and keyboard,
203
+ * but home, lock and siri are the device's own buttons and live outside the screen it draws — so a
204
+ * customer showing the simulator inside their own product has no way to send them without this.
205
+ */
206
+ async pressButton(session, button) {
207
+ const res = await this.request('POST', '/api/session/button', { session, button });
208
+ if (res.status !== 200)
209
+ throw await this.errorFor(res);
210
+ }
166
211
  /**
167
212
  * The language and theme the app renders in, changed live.
168
213
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palgroup/simstream",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Start and drive remote iOS simulator sessions.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",