serve-sim 0.1.7 → 0.1.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/README.md +1 -1
- package/bin/serve-sim-bin +0 -0
- package/dist/middleware.js +7 -8
- package/dist/serve-sim.js +16 -17
- package/package.json +4 -1
- package/src/middleware.ts +36 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serve-sim",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Evan Bacon",
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"bin": {
|
|
21
21
|
"serve-sim": "dist/serve-sim.js"
|
|
22
22
|
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
23
26
|
"files": [
|
|
24
27
|
"dist/serve-sim.js",
|
|
25
28
|
"dist/middleware.js",
|
package/src/middleware.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { join } from "path";
|
|
|
7
7
|
declare const __PREVIEW_HTML_B64__: string;
|
|
8
8
|
const STATE_DIR = join(tmpdir(), "serve-sim");
|
|
9
9
|
|
|
10
|
-
interface ServeSimState {
|
|
10
|
+
export interface ServeSimState {
|
|
11
11
|
pid: number;
|
|
12
12
|
port: number;
|
|
13
13
|
device: string;
|
|
@@ -125,6 +125,27 @@ function readServeSimStates(): ServeSimState[] {
|
|
|
125
125
|
return states;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
export function selectServeSimState(
|
|
129
|
+
states: ServeSimState[],
|
|
130
|
+
device?: string | null,
|
|
131
|
+
): ServeSimState | null {
|
|
132
|
+
if (device) {
|
|
133
|
+
return states.find((state) => state.device === device) ?? null;
|
|
134
|
+
}
|
|
135
|
+
return states[0] ?? null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function queryDevice(rawUrl: string): string | null {
|
|
139
|
+
const qIndex = rawUrl.indexOf("?");
|
|
140
|
+
if (qIndex === -1) return null;
|
|
141
|
+
return new URLSearchParams(rawUrl.slice(qIndex + 1)).get("device");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function endpoint(base: string, path: string, device: string): string {
|
|
145
|
+
const value = `${base}${path}`;
|
|
146
|
+
return `${value}?device=${encodeURIComponent(device)}`;
|
|
147
|
+
}
|
|
148
|
+
|
|
128
149
|
let _html: string | null = null;
|
|
129
150
|
function loadHtml(): string {
|
|
130
151
|
if (!_html) {
|
|
@@ -136,6 +157,8 @@ function loadHtml(): string {
|
|
|
136
157
|
export interface SimMiddlewareOptions {
|
|
137
158
|
/** Base path to serve the preview at. Default: "/.sim" */
|
|
138
159
|
basePath?: string;
|
|
160
|
+
/** Pin this preview server to a specific simulator UDID. */
|
|
161
|
+
device?: string;
|
|
139
162
|
}
|
|
140
163
|
|
|
141
164
|
/**
|
|
@@ -153,11 +176,12 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
|
153
176
|
const rawUrl: string = req.url ?? "";
|
|
154
177
|
const qIndex = rawUrl.indexOf("?");
|
|
155
178
|
const url = qIndex === -1 ? rawUrl : rawUrl.slice(0, qIndex);
|
|
179
|
+
const selectedDevice = queryDevice(rawUrl) ?? options?.device ?? null;
|
|
156
180
|
|
|
157
181
|
// Serve the preview page
|
|
158
182
|
if (url === base || url === base + "/") {
|
|
159
183
|
const states = readServeSimStates();
|
|
160
|
-
const state = states
|
|
184
|
+
const state = selectServeSimState(states, selectedDevice);
|
|
161
185
|
let html = loadHtml();
|
|
162
186
|
|
|
163
187
|
if (state) {
|
|
@@ -166,7 +190,8 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
|
166
190
|
// and connects to the WS directly (WS has no CORS).
|
|
167
191
|
const config = JSON.stringify({
|
|
168
192
|
...state,
|
|
169
|
-
logsEndpoint: base
|
|
193
|
+
logsEndpoint: endpoint(base, "/logs", state.device),
|
|
194
|
+
appStateEndpoint: endpoint(base, "/appstate", state.device),
|
|
170
195
|
});
|
|
171
196
|
const configScript = `<script>window.__SIM_PREVIEW__=${config}</script>`;
|
|
172
197
|
html = html.replace("<!--__SIM_PREVIEW_CONFIG__-->", configScript);
|
|
@@ -183,11 +208,12 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
|
183
208
|
// JSON API: serve-sim state
|
|
184
209
|
if (url === base + "/api") {
|
|
185
210
|
const states = readServeSimStates();
|
|
211
|
+
const state = selectServeSimState(states, selectedDevice);
|
|
186
212
|
res.writeHead(200, {
|
|
187
213
|
"Content-Type": "application/json",
|
|
188
214
|
"Cache-Control": "no-store",
|
|
189
215
|
});
|
|
190
|
-
res.end(JSON.stringify(
|
|
216
|
+
res.end(JSON.stringify(state || null));
|
|
191
217
|
return;
|
|
192
218
|
}
|
|
193
219
|
|
|
@@ -224,12 +250,13 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
|
224
250
|
// SSE: simctl log stream
|
|
225
251
|
if (url === base + "/logs") {
|
|
226
252
|
const states = readServeSimStates();
|
|
227
|
-
|
|
253
|
+
const state = selectServeSimState(states, selectedDevice);
|
|
254
|
+
if (!state) {
|
|
228
255
|
res.writeHead(404);
|
|
229
256
|
res.end("No serve-sim device");
|
|
230
257
|
return;
|
|
231
258
|
}
|
|
232
|
-
const udid =
|
|
259
|
+
const udid = state.device;
|
|
233
260
|
res.writeHead(200, {
|
|
234
261
|
"Content-Type": "text/event-stream",
|
|
235
262
|
"Cache-Control": "no-cache",
|
|
@@ -266,12 +293,13 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
|
|
|
266
293
|
// stays narrow and the client can listen without rate-limit concerns.
|
|
267
294
|
if (url === base + "/appstate") {
|
|
268
295
|
const states = readServeSimStates();
|
|
269
|
-
|
|
296
|
+
const state = selectServeSimState(states, selectedDevice);
|
|
297
|
+
if (!state) {
|
|
270
298
|
res.writeHead(404);
|
|
271
299
|
res.end("No serve-sim device");
|
|
272
300
|
return;
|
|
273
301
|
}
|
|
274
|
-
const udid =
|
|
302
|
+
const udid = state.device;
|
|
275
303
|
res.writeHead(200, {
|
|
276
304
|
"Content-Type": "text/event-stream",
|
|
277
305
|
"Cache-Control": "no-cache",
|