@limrun/ui 0.9.0-rc.1 → 0.9.0-rc.11

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.
Files changed (46) hide show
  1. package/dist/components/inspect-overlay.d.ts +33 -0
  2. package/dist/components/remote-control.d.ts +86 -0
  3. package/dist/core/ax-fetcher.d.ts +49 -0
  4. package/dist/core/ax-tree.d.ts +99 -0
  5. package/dist/core/device-install/apple/client.d.ts +1 -0
  6. package/dist/core/device-install/apple/provisioning.d.ts +42 -31
  7. package/dist/core/device-install/apple/relay.d.ts +5 -9
  8. package/dist/core/device-install/storage/browser-storage.d.ts +19 -0
  9. package/dist/core/device-install/types.d.ts +2 -2
  10. package/dist/device-install/index.cjs +1 -9
  11. package/dist/device-install/index.js +76 -210
  12. package/dist/device-install/react.cjs +1 -1
  13. package/dist/device-install/react.js +1 -1
  14. package/dist/device-install-dialog-CjH25hnN.js +2 -0
  15. package/dist/device-install-dialog-W5Xv9kWL.mjs +443 -0
  16. package/dist/device-install-dialog.css +1 -1
  17. package/dist/hooks/use-device-install.d.ts +21 -3
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.css +1 -1
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.js +1485 -778
  22. package/dist/use-device-install-Y1u6vIBB.js +31 -0
  23. package/dist/use-device-install-sDVvby1V.mjs +13627 -0
  24. package/package.json +7 -3
  25. package/src/components/device-install/device-install-dialog.css +82 -1
  26. package/src/components/device-install/device-install-dialog.tsx +319 -187
  27. package/src/components/inspect-overlay.css +223 -0
  28. package/src/components/inspect-overlay.tsx +437 -0
  29. package/src/components/remote-control.tsx +547 -9
  30. package/src/core/ax-fetcher.test.ts +418 -0
  31. package/src/core/ax-fetcher.ts +377 -0
  32. package/src/core/ax-tree.test.ts +491 -0
  33. package/src/core/ax-tree.ts +416 -0
  34. package/src/core/device-install/apple/client.ts +92 -4
  35. package/src/core/device-install/apple/provisioning.ts +67 -24
  36. package/src/core/device-install/apple/relay.ts +121 -205
  37. package/src/core/device-install/storage/browser-storage.ts +26 -1
  38. package/src/core/device-install/types.ts +2 -2
  39. package/src/demo.tsx +93 -10
  40. package/src/hooks/use-device-install.ts +766 -67
  41. package/src/index.ts +19 -1
  42. package/vitest.config.ts +23 -0
  43. package/dist/device-install-dialog-CTwVViYY.js +0 -2
  44. package/dist/device-install-dialog-zzKJu7SM.mjs +0 -328
  45. package/dist/use-device-install-CgrOKKyi.mjs +0 -13042
  46. package/dist/use-device-install-DDKRf6IL.js +0 -23
package/src/index.ts CHANGED
@@ -1,4 +1,22 @@
1
1
  export { RemoteControl } from './components/remote-control';
2
2
  export type { RemoteControlHandle } from './components/remote-control';
3
+
4
+ // Accessibility / inspect-mode types and helpers. Exported so customers can
5
+ // build their own side panels, search UIs, or agent-driven inspectors on top
6
+ // of the snapshots delivered via `onAxSnapshotChange`.
7
+ export type { AxSnapshot, AxElement, AxRect, AxSelectors, AxPlatform } from './core/ax-tree';
8
+ export type { AxStatus } from './core/ax-fetcher';
9
+ export {
10
+ axElementAtPoint,
11
+ axElementSelectorExpression,
12
+ axElementSummary,
13
+ axElementsEqual,
14
+ axSnapshotsEqual,
15
+ clampAxFrameForScreen,
16
+ normalizeAndroidTree,
17
+ normalizeIosTree,
18
+ AX_UNAVAILABLE_ERROR,
19
+ } from './core/ax-tree';
20
+
3
21
  export { DeviceInstallDialog, DeviceInstallRelay } from './components/device-install';
4
- export { useDeviceInstall } from './hooks/use-device-install';
22
+ export { useDeviceInstall } from './hooks/use-device-install';
@@ -0,0 +1,23 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ // Vitest config for @limrun/ui unit tests.
4
+ //
5
+ // We use jsdom as the default environment because the runtime code uses
6
+ // browser globals (window.setTimeout, window.requestAnimationFrame, etc.).
7
+ // Pure modules can opt back into the node env per-file via:
8
+ //
9
+ // // @vitest-environment node
10
+ //
11
+ // at the top of the test file.
12
+ //
13
+ // The actual <RemoteControl> component is intentionally NOT under unit
14
+ // test here — its WebRTC plumbing is integration-tested via the demo +
15
+ // staging instance. These tests cover the smaller, pure-logic modules:
16
+ // `core/ax-tree.ts` and `core/ax-fetcher.ts`.
17
+ export default defineConfig({
18
+ test: {
19
+ environment: 'jsdom',
20
+ include: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
21
+ globals: false,
22
+ },
23
+ });
@@ -1,2 +0,0 @@
1
- "use strict";require('./device-install-dialog.css');const e=require("react/jsx-runtime"),o=require("react"),f=require("./use-device-install-DDKRf6IL.js");function g(s){var r,t,a="";if(typeof s=="string"||typeof s=="number")a+=s;else if(typeof s=="object")if(Array.isArray(s)){var c=s.length;for(r=0;r<c;r++)s[r]&&(t=g(s[r]))&&(a&&(a+=" "),a+=t)}else for(t in s)s[t]&&(a&&(a+=" "),a+=t);return a}function v(){for(var s,r,t=0,a="",c=arguments.length;t<c;t++)(s=arguments[t])&&(r=g(s))&&(a&&(a+=" "),a+=r);return a}const N=[{id:"build",title:"Start a device build",description:"Upload signing assets if needed, then follow the live build logs until the device build succeeds."},{id:"usb",title:"Access USB procedures",description:"Allow WebUSB access to the connected iPhone from a Chromium browser on a secure origin."},{id:"pair",title:"Pair with this browser",description:"Pair once and store the pair record locally so future installs can reuse it."},{id:"install",title:"Start installation",description:"Relay the last successful device build to the paired iPhone."}];function w({disabled:s,...r}){const[t,a]=o.useState(!1),[c,x]=o.useState(""),[u,_]=o.useState(""),[h,j]=o.useState(""),m=o.useId(),i=f.useDeviceInstall(r),b=(n,d)=>{i.setSigningFiles({[n]:d.currentTarget.files?.[0]})};return e.jsxs("div",{className:"lr-device-install",children:[e.jsx("button",{type:"button",className:"lr-device-install__trigger",disabled:s||!r.apiUrl,onClick:()=>a(!0),children:"Install to iPhone"}),t&&e.jsx("div",{className:"lr-device-install__backdrop",role:"presentation",children:e.jsxs("section",{"aria-labelledby":m,"aria-modal":"true",className:"lr-device-install__dialog",role:"dialog",children:[e.jsxs("header",{className:"lr-device-install__header",children:[e.jsxs("div",{children:[e.jsx("h2",{id:m,children:"Install to a real iPhone"}),e.jsx("p",{children:"Follow each step to build, authorize USB, pair, and install from this browser."})]}),e.jsx("button",{type:"button",className:"lr-device-install__icon-button",onClick:()=>a(!1),children:"Close"})]}),i.error&&e.jsx("div",{className:"lr-device-install__error",children:i.error}),e.jsx("div",{className:"lr-device-install__steps",children:N.map((n,d)=>e.jsxs(S,{index:d+1,step:n,active:i.currentStep===n.id,status:i.stepStatuses[n.id],children:[n.id==="build"&&e.jsxs("div",{className:"lr-device-install__step-body",children:[e.jsxs("div",{className:"lr-device-install__grid",children:[e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Apple ID"}),e.jsx("input",{type:"email",autoComplete:"username",placeholder:"name@example.com",value:c,onChange:l=>x(l.currentTarget.value)})]}),e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Apple ID password"}),e.jsx("input",{type:"password",autoComplete:"current-password",placeholder:"Password stays in this browser",value:u,onChange:l=>_(l.currentTarget.value)})]}),e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Generated .p12 password"}),e.jsx("input",{type:"password",placeholder:"Used when exporting Apple certificate",onChange:l=>i.setSigningFiles({certificatePassword:l.currentTarget.value})})]})]}),e.jsxs("div",{className:"lr-device-install__actions",children:[e.jsx("button",{type:"button",className:"lr-device-install__secondary",disabled:s||!r.apiUrl||!c||!u||i.busyAction==="build",onClick:()=>void i.startAppleIDLogin({accountName:c,password:u}),children:i.appleSigningStatus==="authenticating"?"Signing in...":"Sign in with Apple ID"}),e.jsxs("span",{className:"lr-device-install__hint",children:["Apple password is used only by browser-side SRP. Status: ",i.appleSigningStatus]})]}),i.appleSigningStatus==="two-factor-required"&&e.jsxs("div",{className:"lr-device-install__grid",children:[e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Two-factor code"}),e.jsx("input",{type:"text",inputMode:"numeric",autoComplete:"one-time-code",value:h,onChange:l=>j(l.currentTarget.value)})]}),e.jsx("button",{type:"button",className:"lr-device-install__secondary",disabled:!h||i.busyAction==="build",onClick:()=>void i.submitAppleTwoFactorCode(h),children:"Submit Apple ID code"})]}),i.appleTeams.length>0&&e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Apple Developer team"}),e.jsx("select",{value:i.selectedAppleTeamID??"",onChange:l=>i.setSelectedAppleTeamID(l.currentTarget.value||void 0),children:i.appleTeams.map((l,y)=>{const p=l.teamId??(l.providerId===void 0?void 0:String(l.providerId))??l.publicProviderId??"";return e.jsxs("option",{value:p,children:[l.name??"Apple Developer Team"," ",p?`(${p})`:""]},`${p}-${y}`)})})]}),e.jsxs("div",{className:"lr-device-install__grid",children:[e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Certificate (.p12)"}),e.jsx("input",{type:"file",accept:".p12,application/x-pkcs12",onChange:l=>b("certificateFile",l)})]}),e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Provisioning profile"}),e.jsx("input",{type:"file",accept:".mobileprovision",onChange:l=>b("provisioningProfileFile",l)})]}),e.jsxs("label",{className:"lr-device-install__field",children:[e.jsx("span",{children:"Uploaded .p12 password"}),e.jsx("input",{type:"password",placeholder:"Export password",onChange:l=>i.setSigningFiles({certificatePassword:l.currentTarget.value})})]})]}),e.jsx("button",{type:"button",className:"lr-device-install__primary",disabled:s||!i.canBuild,onClick:()=>void i.startDeviceBuild(),children:i.busyAction==="build"?"Starting build...":"Start device build"}),e.jsxs("details",{className:"lr-device-install__build-logs",open:i.buildLogPanelOpen,onToggle:l=>i.setBuildLogPanelOpen(l.currentTarget.open),children:[e.jsxs("summary",{children:["Build logs (",i.buildStatus,")"]}),e.jsx("pre",{children:i.buildLogs.length>0?i.buildLogs.filter(l=>l.type!=="meta").map(l=>l.data).join(`
2
- `):"Build logs will appear here while the device build is running."})]})]}),n.id==="usb"&&e.jsxs("div",{className:"lr-device-install__step-body",children:[e.jsx("p",{children:"WebUSB works in Chromium browsers on secure origins. Connect the iPhone over USB and approve the browser permission prompt."}),e.jsx("button",{type:"button",className:"lr-device-install__primary",disabled:s||!i.canRequestUSBAccess,onClick:()=>void i.requestUSBAccess(),children:i.busyAction==="usb"?"Selecting iPhone...":"Allow USB access"}),i.device&&e.jsx("div",{className:"lr-device-install__device",children:`${i.device.productName??"iPhone"} ${i.device.serialNumber??""}`.trim()})]}),n.id==="pair"&&e.jsxs("div",{className:"lr-device-install__step-body",children:[i.pairConfirmationRequired&&e.jsxs("p",{children:["Unlock the iPhone and tap ",e.jsx("strong",{children:"Trust"})," in the system dialog, then confirm the pair record."]}),e.jsx("button",{type:"button",className:"lr-device-install__primary",disabled:s||!i.canPairBrowser,onClick:()=>void i.pairBrowser(),children:i.busyAction==="pair"?"Pairing...":i.pairConfirmationRequired?"Confirm pair record":"Pair browser"}),e.jsx("p",{children:i.hasPairRecord?"Pair record is stored locally. Installation is available.":"Pair this browser once before installing."})]}),n.id==="install"&&e.jsxs("div",{className:"lr-device-install__step-body",children:[e.jsx("button",{type:"button",className:"lr-device-install__primary",disabled:s||!i.canInstall,onClick:()=>void i.startInstallation(),children:i.busyAction==="install"?"Installing...":"Install last build"}),e.jsx("button",{type:"button",className:"lr-device-install__secondary",onClick:i.stopRelay,children:"Stop relay"})]})]},n.id))}),e.jsxs("footer",{className:"lr-device-install__logs",children:[e.jsx("h3",{children:"Progress"}),e.jsx("ol",{children:i.logs.map((n,d)=>e.jsx("li",{children:n},`${d}-${n.slice(0,24)}`))})]})]})})]})}function S({index:s,step:r,active:t,status:a,children:c}){return e.jsxs("article",{className:v("lr-device-install__step",t&&"lr-device-install__step--active"),children:[e.jsxs("div",{className:"lr-device-install__step-header",children:[e.jsx("div",{className:"lr-device-install__step-number",children:s}),e.jsxs("div",{children:[e.jsx("h3",{children:r.title}),e.jsx("p",{children:r.description})]}),e.jsx("span",{className:v("lr-device-install__status",`lr-device-install__status--${a}`),children:a})]}),c]})}exports.DeviceInstallDialog=w;exports.clsx=v;
@@ -1,328 +0,0 @@
1
- import { jsxs as l, jsx as i } from "react/jsx-runtime";
2
- import { useState as u, useId as S } from "react";
3
- import { u as C } from "./use-device-install-CgrOKKyi.mjs";
4
- import './device-install-dialog.css';function _(r) {
5
- var t, s, n = "";
6
- if (typeof r == "string" || typeof r == "number") n += r;
7
- else if (typeof r == "object") if (Array.isArray(r)) {
8
- var d = r.length;
9
- for (t = 0; t < d; t++) r[t] && (s = _(r[t])) && (n && (n += " "), n += s);
10
- } else for (s in r) r[s] && (n && (n += " "), n += s);
11
- return n;
12
- }
13
- function g() {
14
- for (var r, t, s = 0, n = "", d = arguments.length; s < d; s++) (r = arguments[s]) && (t = _(r)) && (n && (n += " "), n += t);
15
- return n;
16
- }
17
- const A = [
18
- {
19
- id: "build",
20
- title: "Start a device build",
21
- description: "Upload signing assets if needed, then follow the live build logs until the device build succeeds."
22
- },
23
- {
24
- id: "usb",
25
- title: "Access USB procedures",
26
- description: "Allow WebUSB access to the connected iPhone from a Chromium browser on a secure origin."
27
- },
28
- {
29
- id: "pair",
30
- title: "Pair with this browser",
31
- description: "Pair once and store the pair record locally so future installs can reuse it."
32
- },
33
- {
34
- id: "install",
35
- title: "Start installation",
36
- description: "Relay the last successful device build to the paired iPhone."
37
- }
38
- ];
39
- function D({
40
- disabled: r,
41
- ...t
42
- }) {
43
- const [s, n] = u(!1), [d, f] = u(""), [h, y] = u(""), [v, N] = u(""), m = S(), e = C(t), b = (c, o) => {
44
- e.setSigningFiles({
45
- [c]: o.currentTarget.files?.[0]
46
- });
47
- };
48
- return /* @__PURE__ */ l("div", { className: "lr-device-install", children: [
49
- /* @__PURE__ */ i(
50
- "button",
51
- {
52
- type: "button",
53
- className: "lr-device-install__trigger",
54
- disabled: r || !t.apiUrl,
55
- onClick: () => n(!0),
56
- children: "Install to iPhone"
57
- }
58
- ),
59
- s && /* @__PURE__ */ i("div", { className: "lr-device-install__backdrop", role: "presentation", children: /* @__PURE__ */ l(
60
- "section",
61
- {
62
- "aria-labelledby": m,
63
- "aria-modal": "true",
64
- className: "lr-device-install__dialog",
65
- role: "dialog",
66
- children: [
67
- /* @__PURE__ */ l("header", { className: "lr-device-install__header", children: [
68
- /* @__PURE__ */ l("div", { children: [
69
- /* @__PURE__ */ i("h2", { id: m, children: "Install to a real iPhone" }),
70
- /* @__PURE__ */ i("p", { children: "Follow each step to build, authorize USB, pair, and install from this browser." })
71
- ] }),
72
- /* @__PURE__ */ i("button", { type: "button", className: "lr-device-install__icon-button", onClick: () => n(!1), children: "Close" })
73
- ] }),
74
- e.error && /* @__PURE__ */ i("div", { className: "lr-device-install__error", children: e.error }),
75
- /* @__PURE__ */ i("div", { className: "lr-device-install__steps", children: A.map((c, o) => /* @__PURE__ */ l(
76
- P,
77
- {
78
- index: o + 1,
79
- step: c,
80
- active: e.currentStep === c.id,
81
- status: e.stepStatuses[c.id],
82
- children: [
83
- c.id === "build" && /* @__PURE__ */ l("div", { className: "lr-device-install__step-body", children: [
84
- /* @__PURE__ */ l("div", { className: "lr-device-install__grid", children: [
85
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
86
- /* @__PURE__ */ i("span", { children: "Apple ID" }),
87
- /* @__PURE__ */ i(
88
- "input",
89
- {
90
- type: "email",
91
- autoComplete: "username",
92
- placeholder: "name@example.com",
93
- value: d,
94
- onChange: (a) => f(a.currentTarget.value)
95
- }
96
- )
97
- ] }),
98
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
99
- /* @__PURE__ */ i("span", { children: "Apple ID password" }),
100
- /* @__PURE__ */ i(
101
- "input",
102
- {
103
- type: "password",
104
- autoComplete: "current-password",
105
- placeholder: "Password stays in this browser",
106
- value: h,
107
- onChange: (a) => y(a.currentTarget.value)
108
- }
109
- )
110
- ] }),
111
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
112
- /* @__PURE__ */ i("span", { children: "Generated .p12 password" }),
113
- /* @__PURE__ */ i(
114
- "input",
115
- {
116
- type: "password",
117
- placeholder: "Used when exporting Apple certificate",
118
- onChange: (a) => e.setSigningFiles({ certificatePassword: a.currentTarget.value })
119
- }
120
- )
121
- ] })
122
- ] }),
123
- /* @__PURE__ */ l("div", { className: "lr-device-install__actions", children: [
124
- /* @__PURE__ */ i(
125
- "button",
126
- {
127
- type: "button",
128
- className: "lr-device-install__secondary",
129
- disabled: r || !t.apiUrl || !d || !h || e.busyAction === "build",
130
- onClick: () => void e.startAppleIDLogin({
131
- accountName: d,
132
- password: h
133
- }),
134
- children: e.appleSigningStatus === "authenticating" ? "Signing in..." : "Sign in with Apple ID"
135
- }
136
- ),
137
- /* @__PURE__ */ l("span", { className: "lr-device-install__hint", children: [
138
- "Apple password is used only by browser-side SRP. Status: ",
139
- e.appleSigningStatus
140
- ] })
141
- ] }),
142
- e.appleSigningStatus === "two-factor-required" && /* @__PURE__ */ l("div", { className: "lr-device-install__grid", children: [
143
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
144
- /* @__PURE__ */ i("span", { children: "Two-factor code" }),
145
- /* @__PURE__ */ i(
146
- "input",
147
- {
148
- type: "text",
149
- inputMode: "numeric",
150
- autoComplete: "one-time-code",
151
- value: v,
152
- onChange: (a) => N(a.currentTarget.value)
153
- }
154
- )
155
- ] }),
156
- /* @__PURE__ */ i(
157
- "button",
158
- {
159
- type: "button",
160
- className: "lr-device-install__secondary",
161
- disabled: !v || e.busyAction === "build",
162
- onClick: () => void e.submitAppleTwoFactorCode(v),
163
- children: "Submit Apple ID code"
164
- }
165
- )
166
- ] }),
167
- e.appleTeams.length > 0 && /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
168
- /* @__PURE__ */ i("span", { children: "Apple Developer team" }),
169
- /* @__PURE__ */ i(
170
- "select",
171
- {
172
- value: e.selectedAppleTeamID ?? "",
173
- onChange: (a) => e.setSelectedAppleTeamID(a.currentTarget.value || void 0),
174
- children: e.appleTeams.map((a, w) => {
175
- const p = a.teamId ?? (a.providerId === void 0 ? void 0 : String(a.providerId)) ?? a.publicProviderId ?? "";
176
- return /* @__PURE__ */ l("option", { value: p, children: [
177
- a.name ?? "Apple Developer Team",
178
- " ",
179
- p ? `(${p})` : ""
180
- ] }, `${p}-${w}`);
181
- })
182
- }
183
- )
184
- ] }),
185
- /* @__PURE__ */ l("div", { className: "lr-device-install__grid", children: [
186
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
187
- /* @__PURE__ */ i("span", { children: "Certificate (.p12)" }),
188
- /* @__PURE__ */ i(
189
- "input",
190
- {
191
- type: "file",
192
- accept: ".p12,application/x-pkcs12",
193
- onChange: (a) => b("certificateFile", a)
194
- }
195
- )
196
- ] }),
197
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
198
- /* @__PURE__ */ i("span", { children: "Provisioning profile" }),
199
- /* @__PURE__ */ i(
200
- "input",
201
- {
202
- type: "file",
203
- accept: ".mobileprovision",
204
- onChange: (a) => b("provisioningProfileFile", a)
205
- }
206
- )
207
- ] }),
208
- /* @__PURE__ */ l("label", { className: "lr-device-install__field", children: [
209
- /* @__PURE__ */ i("span", { children: "Uploaded .p12 password" }),
210
- /* @__PURE__ */ i(
211
- "input",
212
- {
213
- type: "password",
214
- placeholder: "Export password",
215
- onChange: (a) => e.setSigningFiles({ certificatePassword: a.currentTarget.value })
216
- }
217
- )
218
- ] })
219
- ] }),
220
- /* @__PURE__ */ i(
221
- "button",
222
- {
223
- type: "button",
224
- className: "lr-device-install__primary",
225
- disabled: r || !e.canBuild,
226
- onClick: () => void e.startDeviceBuild(),
227
- children: e.busyAction === "build" ? "Starting build..." : "Start device build"
228
- }
229
- ),
230
- /* @__PURE__ */ l(
231
- "details",
232
- {
233
- className: "lr-device-install__build-logs",
234
- open: e.buildLogPanelOpen,
235
- onToggle: (a) => e.setBuildLogPanelOpen(a.currentTarget.open),
236
- children: [
237
- /* @__PURE__ */ l("summary", { children: [
238
- "Build logs (",
239
- e.buildStatus,
240
- ")"
241
- ] }),
242
- /* @__PURE__ */ i("pre", { children: e.buildLogs.length > 0 ? e.buildLogs.filter((a) => a.type !== "meta").map((a) => a.data).join(`
243
- `) : "Build logs will appear here while the device build is running." })
244
- ]
245
- }
246
- )
247
- ] }),
248
- c.id === "usb" && /* @__PURE__ */ l("div", { className: "lr-device-install__step-body", children: [
249
- /* @__PURE__ */ i("p", { children: "WebUSB works in Chromium browsers on secure origins. Connect the iPhone over USB and approve the browser permission prompt." }),
250
- /* @__PURE__ */ i(
251
- "button",
252
- {
253
- type: "button",
254
- className: "lr-device-install__primary",
255
- disabled: r || !e.canRequestUSBAccess,
256
- onClick: () => void e.requestUSBAccess(),
257
- children: e.busyAction === "usb" ? "Selecting iPhone..." : "Allow USB access"
258
- }
259
- ),
260
- e.device && /* @__PURE__ */ i("div", { className: "lr-device-install__device", children: `${e.device.productName ?? "iPhone"} ${e.device.serialNumber ?? ""}`.trim() })
261
- ] }),
262
- c.id === "pair" && /* @__PURE__ */ l("div", { className: "lr-device-install__step-body", children: [
263
- e.pairConfirmationRequired && /* @__PURE__ */ l("p", { children: [
264
- "Unlock the iPhone and tap ",
265
- /* @__PURE__ */ i("strong", { children: "Trust" }),
266
- " in the system dialog, then confirm the pair record."
267
- ] }),
268
- /* @__PURE__ */ i(
269
- "button",
270
- {
271
- type: "button",
272
- className: "lr-device-install__primary",
273
- disabled: r || !e.canPairBrowser,
274
- onClick: () => void e.pairBrowser(),
275
- children: e.busyAction === "pair" ? "Pairing..." : e.pairConfirmationRequired ? "Confirm pair record" : "Pair browser"
276
- }
277
- ),
278
- /* @__PURE__ */ i("p", { children: e.hasPairRecord ? "Pair record is stored locally. Installation is available." : "Pair this browser once before installing." })
279
- ] }),
280
- c.id === "install" && /* @__PURE__ */ l("div", { className: "lr-device-install__step-body", children: [
281
- /* @__PURE__ */ i(
282
- "button",
283
- {
284
- type: "button",
285
- className: "lr-device-install__primary",
286
- disabled: r || !e.canInstall,
287
- onClick: () => void e.startInstallation(),
288
- children: e.busyAction === "install" ? "Installing..." : "Install last build"
289
- }
290
- ),
291
- /* @__PURE__ */ i("button", { type: "button", className: "lr-device-install__secondary", onClick: e.stopRelay, children: "Stop relay" })
292
- ] })
293
- ]
294
- },
295
- c.id
296
- )) }),
297
- /* @__PURE__ */ l("footer", { className: "lr-device-install__logs", children: [
298
- /* @__PURE__ */ i("h3", { children: "Progress" }),
299
- /* @__PURE__ */ i("ol", { children: e.logs.map((c, o) => /* @__PURE__ */ i("li", { children: c }, `${o}-${c.slice(0, 24)}`)) })
300
- ] })
301
- ]
302
- }
303
- ) })
304
- ] });
305
- }
306
- function P({
307
- index: r,
308
- step: t,
309
- active: s,
310
- status: n,
311
- children: d
312
- }) {
313
- return /* @__PURE__ */ l("article", { className: g("lr-device-install__step", s && "lr-device-install__step--active"), children: [
314
- /* @__PURE__ */ l("div", { className: "lr-device-install__step-header", children: [
315
- /* @__PURE__ */ i("div", { className: "lr-device-install__step-number", children: r }),
316
- /* @__PURE__ */ l("div", { children: [
317
- /* @__PURE__ */ i("h3", { children: t.title }),
318
- /* @__PURE__ */ i("p", { children: t.description })
319
- ] }),
320
- /* @__PURE__ */ i("span", { className: g("lr-device-install__status", `lr-device-install__status--${n}`), children: n })
321
- ] }),
322
- d
323
- ] });
324
- }
325
- export {
326
- D,
327
- g as c
328
- };