@limrun/ui 0.16.0 → 0.17.0-rc.2
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 +64 -0
- package/dist/GLTFLoader-Cami_vza.mjs +1679 -0
- package/dist/GLTFLoader-DeCLxW_q.js +1 -0
- package/dist/components/duo-button-hinge.d.ts +16 -0
- package/dist/components/duo-controls.d.ts +21 -0
- package/dist/components/duo-flat-frame.d.ts +7 -0
- package/dist/components/duo-flat-geometry.d.ts +52 -0
- package/dist/components/duo-fold-motion.d.ts +27 -0
- package/dist/components/duo-fold-renderer.d.ts +19 -0
- package/dist/components/duo-fold-timing.d.ts +1 -0
- package/dist/components/duo-frame.d.ts +16 -0
- package/dist/components/duo-hardware.d.ts +20 -0
- package/dist/components/duo-loading.d.ts +8 -0
- package/dist/components/duo-model.d.ts +19 -0
- package/dist/components/duo-screen-handoff.d.ts +4 -0
- package/dist/components/duo-view.d.ts +9 -0
- package/dist/components/remote-control.d.ts +5 -1
- package/dist/core/duo.d.ts +63 -0
- package/dist/duo-fold-renderer-BXejNHcY.mjs +257 -0
- package/dist/duo-fold-renderer-DdltAnF7.js +53 -0
- package/dist/duo-frame-Cmw4p2uN.mjs +26767 -0
- package/dist/duo-frame-iMtrvx_a.js +4059 -0
- package/dist/duo-view-BAh-w2Kz.js +1 -0
- package/dist/duo-view-D9Ae00rj.mjs +512 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.js +2 -2
- package/dist/lite.cjs +1 -1
- package/dist/lite.js +1 -1
- package/dist/remote-control-B2jZpf3c.js +1 -0
- package/dist/remote-control-DiddxS8l.mjs +2883 -0
- package/package.json +8 -2
- package/dist/demo.d.ts +0 -1
- package/dist/remote-control-BRgbD7yo.mjs +0 -2516
- package/dist/remote-control-VISrP1zI.js +0 -1
- package/index.html +0 -199
- package/src/assets/Apple_logo_white.svg +0 -4
- package/src/assets/android_boot.gif +0 -0
- package/src/assets/android_boot.webp +0 -0
- package/src/assets/iphone16pro_black.webp +0 -0
- package/src/assets/iphone16pro_black_bg.webp +0 -0
- package/src/assets/iphone16pro_black_landscape.webp +0 -0
- package/src/assets/iphone16pro_black_landscape_bg.webp +0 -0
- package/src/assets/pixel9_black.webp +0 -0
- package/src/assets/pixel9_black_landscape.webp +0 -0
- package/src/assets/pixel_tablet_landscape.webp +0 -0
- package/src/assets/pixel_tablet_portrait.webp +0 -0
- package/src/components/device-install/index.ts +0 -1
- package/src/components/inspect-overlay.css +0 -223
- package/src/components/inspect-overlay.tsx +0 -437
- package/src/components/remote-control-framed.tsx +0 -14
- package/src/components/remote-control.css +0 -131
- package/src/components/remote-control.test.ts +0 -34
- package/src/components/remote-control.tsx +0 -3853
- package/src/core/ax-fetcher.test.ts +0 -418
- package/src/core/ax-fetcher.ts +0 -387
- package/src/core/ax-tree.test.ts +0 -491
- package/src/core/ax-tree.ts +0 -416
- package/src/core/camera.test.ts +0 -155
- package/src/core/camera.ts +0 -133
- package/src/core/constants.ts +0 -344
- package/src/core/webrtc-messages.ts +0 -148
- package/src/demo.tsx +0 -269
- package/src/frame-assets.ts +0 -22
- package/src/hooks/index.ts +0 -1
- package/src/index.ts +0 -29
- package/src/lite.test.ts +0 -30
- package/src/lite.ts +0 -30
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -26
- package/tsconfig.node.json +0 -26
- package/vite.config.ts +0 -35
- package/vitest.config.ts +0 -24
package/src/demo.tsx
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { useState, useRef } from 'react';
|
|
2
|
-
import { createRoot } from 'react-dom/client';
|
|
3
|
-
import { RemoteControl } from './components/remote-control-framed';
|
|
4
|
-
import type { RemoteControlHandle } from './components/remote-control';
|
|
5
|
-
import { AxSnapshot } from './core/ax-tree';
|
|
6
|
-
|
|
7
|
-
type InspectChoice = 'off' | 'hover-only' | 'select';
|
|
8
|
-
|
|
9
|
-
// Pre-fill from query string so the developer testing the demo can deeplink
|
|
10
|
-
// `?url=...&token=...&inspect=select&autoconnect=1`. Nothing is persisted.
|
|
11
|
-
const initialParams = new URLSearchParams(window.location.search);
|
|
12
|
-
const initialUrl = initialParams.get('url') || 'ws://localhost:8833/signaling';
|
|
13
|
-
const initialToken = initialParams.get('token') || 'token';
|
|
14
|
-
const initialPlatformParam = initialParams.get('platform');
|
|
15
|
-
const initialPlatform: 'ios' | 'android' = initialPlatformParam === 'android' ? 'android' : 'ios';
|
|
16
|
-
const initialInspect = (initialParams.get('inspect') as InspectChoice | null) ?? 'off';
|
|
17
|
-
const initialAutoconnect =
|
|
18
|
-
initialParams.get('autoconnect') === '1' && initialParams.has('url') && initialParams.has('token');
|
|
19
|
-
|
|
20
|
-
function Demo() {
|
|
21
|
-
const [url, setUrl] = useState(initialUrl);
|
|
22
|
-
const [token, setToken] = useState(initialToken);
|
|
23
|
-
const [platform, setPlatform] = useState<'ios' | 'android'>(initialPlatform);
|
|
24
|
-
const [isConnected, setIsConnected] = useState(initialAutoconnect);
|
|
25
|
-
const [key, setKey] = useState(0);
|
|
26
|
-
const [showDebugInfo, setShowDebugInfo] = useState(false);
|
|
27
|
-
const [inspectChoice, setInspectChoice] = useState<InspectChoice>(initialInspect);
|
|
28
|
-
const [latestSnapshot, setLatestSnapshot] = useState<AxSnapshot | null>(null);
|
|
29
|
-
const [latestSelection, setLatestSelection] = useState<string | null>(null);
|
|
30
|
-
|
|
31
|
-
const remoteControlRef = useRef<RemoteControlHandle>(null);
|
|
32
|
-
|
|
33
|
-
const inspectModeProp: boolean | 'hover-only' | undefined =
|
|
34
|
-
inspectChoice === 'off' ? undefined
|
|
35
|
-
: inspectChoice === 'hover-only' ? 'hover-only'
|
|
36
|
-
: true;
|
|
37
|
-
|
|
38
|
-
const handleConnect = () => {
|
|
39
|
-
if (url) {
|
|
40
|
-
setIsConnected(true);
|
|
41
|
-
// Force remount by changing key
|
|
42
|
-
setKey((prev) => prev + 1);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const handleDisconnect = () => {
|
|
47
|
-
setIsConnected(false);
|
|
48
|
-
setKey((prev) => prev + 1);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const handleScreenshot = async () => {
|
|
52
|
-
if (remoteControlRef.current) {
|
|
53
|
-
try {
|
|
54
|
-
const screenshot = await remoteControlRef.current.screenshot();
|
|
55
|
-
// Open screenshot in new window
|
|
56
|
-
const win = window.open();
|
|
57
|
-
if (win) {
|
|
58
|
-
win.document.write(`<img src="${screenshot.dataUri}" style="max-width: 100%;" />`);
|
|
59
|
-
}
|
|
60
|
-
} catch (error) {
|
|
61
|
-
console.error('Screenshot failed:', error);
|
|
62
|
-
alert('Screenshot failed: ' + (error as Error).message);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<>
|
|
69
|
-
<div className="header">
|
|
70
|
-
<h1>📱 RemoteControl Component Demo</h1>
|
|
71
|
-
<p>Test the iOS device frame and remote control features</p>
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<div className="demo-container">
|
|
75
|
-
<div className="info-box">
|
|
76
|
-
<h4>ℹ️ How to Use:</h4>
|
|
77
|
-
<p>
|
|
78
|
-
Enter your WebSocket URL and authentication token below, select iOS or Android platform, then
|
|
79
|
-
click Connect to see the remote control in action. The iOS platform will display a realistic
|
|
80
|
-
iPhone frame around the stream.
|
|
81
|
-
</p>
|
|
82
|
-
<p style={{ marginTop: '10px', fontWeight: 600 }}>
|
|
83
|
-
✨ iOS Feature: Touches can start from the bottom bezel area (below the screen, near the home
|
|
84
|
-
indicator) to enable authentic iOS swipe-up gestures for going home or switching apps!
|
|
85
|
-
</p>
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
<div className="controls">
|
|
89
|
-
<div className="control-group">
|
|
90
|
-
<label htmlFor="url">WebSocket URL</label>
|
|
91
|
-
<input
|
|
92
|
-
id="url"
|
|
93
|
-
type="text"
|
|
94
|
-
value={url}
|
|
95
|
-
onChange={(e) => setUrl(e.target.value)}
|
|
96
|
-
placeholder="wss://your-instance.limrun.com/control"
|
|
97
|
-
disabled={isConnected}
|
|
98
|
-
/>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<div className="control-group">
|
|
102
|
-
<label htmlFor="token">Authentication Token</label>
|
|
103
|
-
<input
|
|
104
|
-
id="token"
|
|
105
|
-
type="password"
|
|
106
|
-
value={token}
|
|
107
|
-
onChange={(e) => setToken(e.target.value)}
|
|
108
|
-
placeholder="Enter your token"
|
|
109
|
-
disabled={isConnected}
|
|
110
|
-
/>
|
|
111
|
-
</div>
|
|
112
|
-
|
|
113
|
-
<div className="control-group">
|
|
114
|
-
<label htmlFor="platform">Platform</label>
|
|
115
|
-
<select
|
|
116
|
-
id="platform"
|
|
117
|
-
value={platform}
|
|
118
|
-
onChange={(e) => setPlatform(e.target.value as 'ios' | 'android')}
|
|
119
|
-
disabled={isConnected}
|
|
120
|
-
>
|
|
121
|
-
<option value="ios">iOS (with frame)</option>
|
|
122
|
-
<option value="android">Android (no frame)</option>
|
|
123
|
-
</select>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<div className="control-group">
|
|
127
|
-
<label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
|
|
128
|
-
<input
|
|
129
|
-
type="checkbox"
|
|
130
|
-
checked={showDebugInfo}
|
|
131
|
-
onChange={(e) => setShowDebugInfo(e.target.checked)}
|
|
132
|
-
style={{ cursor: 'pointer' }}
|
|
133
|
-
/>
|
|
134
|
-
Show iOS Extended Touch Area Info
|
|
135
|
-
</label>
|
|
136
|
-
</div>
|
|
137
|
-
|
|
138
|
-
<div className="control-group">
|
|
139
|
-
<label htmlFor="inspect-mode">Inspect Mode</label>
|
|
140
|
-
<select
|
|
141
|
-
id="inspect-mode"
|
|
142
|
-
value={inspectChoice}
|
|
143
|
-
onChange={(e) => setInspectChoice(e.target.value as InspectChoice)}
|
|
144
|
-
>
|
|
145
|
-
<option value="off">Off</option>
|
|
146
|
-
<option value="hover-only">Hover-only (input still works)</option>
|
|
147
|
-
<option value="select">Select (click to pin, ESC to clear)</option>
|
|
148
|
-
</select>
|
|
149
|
-
</div>
|
|
150
|
-
|
|
151
|
-
<div className="button-group">
|
|
152
|
-
{!isConnected ?
|
|
153
|
-
<button className="primary" onClick={handleConnect} disabled={!url}>
|
|
154
|
-
Connect
|
|
155
|
-
</button>
|
|
156
|
-
: <>
|
|
157
|
-
<button className="secondary" onClick={handleDisconnect}>
|
|
158
|
-
Disconnect
|
|
159
|
-
</button>
|
|
160
|
-
<button className="primary" onClick={handleScreenshot}>
|
|
161
|
-
Take Screenshot
|
|
162
|
-
</button>
|
|
163
|
-
</>
|
|
164
|
-
}
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
|
|
168
|
-
{showDebugInfo && platform === 'ios' && (
|
|
169
|
-
<div
|
|
170
|
-
style={{
|
|
171
|
-
background: '#e0f2fe',
|
|
172
|
-
border: '2px solid #0284c7',
|
|
173
|
-
borderRadius: '8px',
|
|
174
|
-
padding: '15px',
|
|
175
|
-
marginBottom: '20px',
|
|
176
|
-
}}
|
|
177
|
-
>
|
|
178
|
-
<h4 style={{ color: '#0c4a6e', marginBottom: '8px', fontSize: '0.95rem' }}>
|
|
179
|
-
🔧 iOS Extended Touch Area
|
|
180
|
-
</h4>
|
|
181
|
-
<p style={{ color: '#075985', fontSize: '0.9rem', lineHeight: '1.5', margin: 0 }}>
|
|
182
|
-
The iOS frame includes a <strong>60-pixel extended touch area</strong> below the visible screen.
|
|
183
|
-
This area (where the home indicator is located) can receive touch events and sends coordinates
|
|
184
|
-
beyond the screen bounds (y > screenHeight), allowing iOS to properly detect gestures that
|
|
185
|
-
start from outside the screen - just like on a real iPhone. Try starting a swipe gesture from
|
|
186
|
-
the home indicator area!
|
|
187
|
-
</p>
|
|
188
|
-
</div>
|
|
189
|
-
)}
|
|
190
|
-
|
|
191
|
-
{isConnected ?
|
|
192
|
-
<>
|
|
193
|
-
<div className="device-preview">
|
|
194
|
-
<div className="preview-item">
|
|
195
|
-
<h3>{platform === 'ios' ? '📱 iOS with Frame' : '🤖 Android (No Frame)'}</h3>
|
|
196
|
-
<div className="device-wrapper">
|
|
197
|
-
<RemoteControl
|
|
198
|
-
key={key}
|
|
199
|
-
ref={remoteControlRef}
|
|
200
|
-
url={url}
|
|
201
|
-
token={token}
|
|
202
|
-
inspectMode={inspectModeProp}
|
|
203
|
-
onAxSnapshotChange={setLatestSnapshot}
|
|
204
|
-
onInspectSelectionChange={(sel) =>
|
|
205
|
-
setLatestSelection(
|
|
206
|
-
sel ?
|
|
207
|
-
`${sel.element.role || sel.element.type} · ${sel.element.label || '(no label)'}`
|
|
208
|
-
: null,
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
/>
|
|
212
|
-
</div>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
|
|
216
|
-
{inspectChoice !== 'off' && (
|
|
217
|
-
<div
|
|
218
|
-
style={{
|
|
219
|
-
marginTop: '20px',
|
|
220
|
-
background: '#0f172a',
|
|
221
|
-
color: '#e2e8f0',
|
|
222
|
-
border: '1px solid #1e293b',
|
|
223
|
-
borderRadius: '8px',
|
|
224
|
-
padding: '12px 14px',
|
|
225
|
-
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
226
|
-
fontSize: '12px',
|
|
227
|
-
}}
|
|
228
|
-
>
|
|
229
|
-
<div
|
|
230
|
-
style={{
|
|
231
|
-
fontWeight: 600,
|
|
232
|
-
marginBottom: '6px',
|
|
233
|
-
display: 'flex',
|
|
234
|
-
gap: '12px',
|
|
235
|
-
flexWrap: 'wrap',
|
|
236
|
-
}}
|
|
237
|
-
>
|
|
238
|
-
<span>Inspect debug (demo-only)</span>
|
|
239
|
-
<span style={{ color: '#94a3b8', fontWeight: 400 }}>
|
|
240
|
-
elements: {latestSnapshot?.elements.length ?? 0} · screen:{' '}
|
|
241
|
-
{latestSnapshot ? `${latestSnapshot.screen.width}×${latestSnapshot.screen.height}` : '—'}{' '}
|
|
242
|
-
· platform: {latestSnapshot?.platform ?? '—'} · selection: {latestSelection ?? '(none)'}
|
|
243
|
-
</span>
|
|
244
|
-
</div>
|
|
245
|
-
</div>
|
|
246
|
-
)}
|
|
247
|
-
</>
|
|
248
|
-
: <div
|
|
249
|
-
style={{
|
|
250
|
-
textAlign: 'center',
|
|
251
|
-
padding: '60px 20px',
|
|
252
|
-
color: '#9ca3af',
|
|
253
|
-
fontSize: '1.1rem',
|
|
254
|
-
}}
|
|
255
|
-
>
|
|
256
|
-
Enter your connection details above and click Connect to start
|
|
257
|
-
</div>
|
|
258
|
-
}
|
|
259
|
-
</div>
|
|
260
|
-
</>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Mount the demo app
|
|
265
|
-
const container = document.getElementById('root');
|
|
266
|
-
if (container) {
|
|
267
|
-
const root = createRoot(container);
|
|
268
|
-
root.render(<Demo />);
|
|
269
|
-
}
|
package/src/frame-assets.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// Limrun's bundled device frames and boot logos. Imported only by the default
|
|
2
|
-
// entry so `@limrun/ui/lite` ships without ~600 KB of inlined artwork.
|
|
3
|
-
import type { RemoteControlAssets } from './components/remote-control';
|
|
4
|
-
import iphoneFrame from './assets/iphone16pro_black_bg.webp';
|
|
5
|
-
import iphoneFrameLandscape from './assets/iphone16pro_black_landscape_bg.webp';
|
|
6
|
-
import pixelFrame from './assets/pixel9_black.webp';
|
|
7
|
-
import pixelFrameLandscape from './assets/pixel9_black_landscape.webp';
|
|
8
|
-
import pixelTabletFrame from './assets/pixel_tablet_portrait.webp';
|
|
9
|
-
import pixelTabletFrameLandscape from './assets/pixel_tablet_landscape.webp';
|
|
10
|
-
import appleLogo from './assets/Apple_logo_white.svg';
|
|
11
|
-
import androidBootLogo from './assets/android_boot.webp';
|
|
12
|
-
|
|
13
|
-
export const defaultRemoteControlAssets: RemoteControlAssets = {
|
|
14
|
-
ios: { frame: iphoneFrame, frameLandscape: iphoneFrameLandscape, loadingLogo: appleLogo },
|
|
15
|
-
android: {
|
|
16
|
-
frame: pixelFrame,
|
|
17
|
-
frameLandscape: pixelFrameLandscape,
|
|
18
|
-
tabletFrame: pixelTabletFrame,
|
|
19
|
-
tabletFrameLandscape: pixelTabletFrameLandscape,
|
|
20
|
-
loadingLogo: androidBootLogo,
|
|
21
|
-
},
|
|
22
|
-
};
|
package/src/hooks/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export { RemoteControl } from './components/remote-control-framed';
|
|
2
|
-
export { defaultRemoteControlAssets } from './frame-assets';
|
|
3
|
-
export type {
|
|
4
|
-
RemoteControlProps,
|
|
5
|
-
RemoteControlHandle,
|
|
6
|
-
RemoteControlAssets,
|
|
7
|
-
RemoteControlPlatformAssets,
|
|
8
|
-
RemoteControlConnectionState,
|
|
9
|
-
MicrophoneState,
|
|
10
|
-
CameraStreamStats,
|
|
11
|
-
} from './components/remote-control';
|
|
12
|
-
export type { CameraCaptureInfo, CameraFacingMode, CameraRequest, CameraResult } from './core/camera';
|
|
13
|
-
|
|
14
|
-
// Accessibility / inspect-mode types and helpers. Exported so customers can
|
|
15
|
-
// build their own side panels, search UIs, or agent-driven inspectors on top
|
|
16
|
-
// of the snapshots delivered via `onAxSnapshotChange`.
|
|
17
|
-
export type { AxSnapshot, AxElement, AxRect, AxSelectors, AxPlatform } from './core/ax-tree';
|
|
18
|
-
export type { AndroidElementTreeOptions, AxStatus } from './core/ax-fetcher';
|
|
19
|
-
export {
|
|
20
|
-
axElementAtPoint,
|
|
21
|
-
axElementSelectorExpression,
|
|
22
|
-
axElementSummary,
|
|
23
|
-
axElementsEqual,
|
|
24
|
-
axSnapshotsEqual,
|
|
25
|
-
clampAxFrameForScreen,
|
|
26
|
-
normalizeAndroidTree,
|
|
27
|
-
normalizeIosTree,
|
|
28
|
-
AX_UNAVAILABLE_ERROR,
|
|
29
|
-
} from './core/ax-tree';
|
package/src/lite.test.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest';
|
|
2
|
-
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
|
|
5
|
-
// Guards the reason the lite entry exists: an embed that imports it must not
|
|
6
|
-
// pull the bundled device artwork. Runs against dist, so build first.
|
|
7
|
-
const dist = join(__dirname, '..', 'dist');
|
|
8
|
-
const describeDist = existsSync(join(dist, 'lite.js')) ? describe : describe.skip;
|
|
9
|
-
|
|
10
|
-
describeDist('@limrun/ui/lite bundle', () => {
|
|
11
|
-
const chunksOf = (entry: string): string[] => {
|
|
12
|
-
const src = readFileSync(join(dist, entry), 'utf8');
|
|
13
|
-
const chunks = [...src.matchAll(/from "\.\/([^"]+)"/g)].map((m) => m[1]);
|
|
14
|
-
return [src, ...chunks.map((c) => readFileSync(join(dist, c), 'utf8'))];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
test('lite entry and its chunks carry no inlined images', () => {
|
|
18
|
-
for (const code of chunksOf('lite.js')) {
|
|
19
|
-
expect(code).not.toMatch(/data:image\//);
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('default entry still bundles the device frames (positive control)', () => {
|
|
24
|
-
expect(chunksOf('index.js').some((code) => /data:image\/webp/.test(code))).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test('one stylesheet keeps its historical name', () => {
|
|
28
|
-
expect(readdirSync(dist).filter((f) => f.endsWith('.css'))).toEqual(['index.css']);
|
|
29
|
-
});
|
|
30
|
-
});
|
package/src/lite.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Frameless entry: identical API, but no bundled device artwork. Pass `assets`
|
|
2
|
-
// to add frames or boot logos.
|
|
3
|
-
export { RemoteControl } from './components/remote-control';
|
|
4
|
-
export type {
|
|
5
|
-
RemoteControlProps,
|
|
6
|
-
RemoteControlHandle,
|
|
7
|
-
RemoteControlAssets,
|
|
8
|
-
RemoteControlPlatformAssets,
|
|
9
|
-
RemoteControlConnectionState,
|
|
10
|
-
MicrophoneState,
|
|
11
|
-
CameraStreamStats,
|
|
12
|
-
} from './components/remote-control';
|
|
13
|
-
export type { CameraCaptureInfo, CameraFacingMode, CameraRequest, CameraResult } from './core/camera';
|
|
14
|
-
|
|
15
|
-
// Accessibility / inspect-mode types and helpers. Exported so customers can
|
|
16
|
-
// build their own side panels, search UIs, or agent-driven inspectors on top
|
|
17
|
-
// of the snapshots delivered via `onAxSnapshotChange`.
|
|
18
|
-
export type { AxSnapshot, AxElement, AxRect, AxSelectors, AxPlatform } from './core/ax-tree';
|
|
19
|
-
export type { AndroidElementTreeOptions, AxStatus } from './core/ax-fetcher';
|
|
20
|
-
export {
|
|
21
|
-
axElementAtPoint,
|
|
22
|
-
axElementSelectorExpression,
|
|
23
|
-
axElementSummary,
|
|
24
|
-
axElementsEqual,
|
|
25
|
-
axSnapshotsEqual,
|
|
26
|
-
clampAxFrameForScreen,
|
|
27
|
-
normalizeAndroidTree,
|
|
28
|
-
normalizeIosTree,
|
|
29
|
-
AX_UNAVAILABLE_ERROR,
|
|
30
|
-
} from './core/ax-tree';
|
package/src/vite-env.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
package/tsconfig.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"moduleResolution": "bundler",
|
|
9
|
-
"allowImportingTsExtensions": false,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"noEmit": false,
|
|
13
|
-
"emitDeclarationOnly": true,
|
|
14
|
-
"declaration": true,
|
|
15
|
-
"declarationDir": "dist",
|
|
16
|
-
"jsx": "react-jsx",
|
|
17
|
-
"strict": true,
|
|
18
|
-
"noUnusedLocals": true,
|
|
19
|
-
"noUnusedParameters": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"outDir": "dist"
|
|
22
|
-
},
|
|
23
|
-
"include": ["src"],
|
|
24
|
-
"exclude": ["**/*.test.ts", "**/*.test.tsx", "node_modules", "dist"],
|
|
25
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
26
|
-
}
|
package/tsconfig.node.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
5
|
-
"target": "ES2022",
|
|
6
|
-
"lib": ["ES2023"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"moduleDetection": "force",
|
|
15
|
-
"noEmit": false,
|
|
16
|
-
"emitDeclarationOnly": true,
|
|
17
|
-
|
|
18
|
-
/* Linting */
|
|
19
|
-
"strict": true,
|
|
20
|
-
"noUnusedLocals": true,
|
|
21
|
-
"noUnusedParameters": true,
|
|
22
|
-
"noFallthroughCasesInSwitch": true,
|
|
23
|
-
"noUncheckedSideEffectImports": true
|
|
24
|
-
},
|
|
25
|
-
"include": ["vite.config.ts"]
|
|
26
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import react from '@vitejs/plugin-react-swc';
|
|
3
|
-
import { resolve } from 'path';
|
|
4
|
-
import dts from 'vite-plugin-dts';
|
|
5
|
-
import { libInjectCss } from 'vite-plugin-lib-inject-css';
|
|
6
|
-
|
|
7
|
-
// https://vite.dev/config/
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
plugins: [react(), libInjectCss(), dts({ include: ['src'] })],
|
|
10
|
-
build: {
|
|
11
|
-
lib: {
|
|
12
|
-
entry: {
|
|
13
|
-
index: resolve(__dirname, 'src/index.ts'),
|
|
14
|
-
lite: resolve(__dirname, 'src/lite.ts'),
|
|
15
|
-
},
|
|
16
|
-
name: 'LimrunUI',
|
|
17
|
-
formats: ['es', 'cjs'],
|
|
18
|
-
fileName: (format, entryName) => `${entryName}.${format === 'es' ? 'js' : 'cjs'}`,
|
|
19
|
-
},
|
|
20
|
-
rollupOptions: {
|
|
21
|
-
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
|
22
|
-
output: {
|
|
23
|
-
// Both entries share one stylesheet; keep its historical name so
|
|
24
|
-
// consumers that reference dist/index.css directly keep working.
|
|
25
|
-
assetFileNames: (info) =>
|
|
26
|
-
info.names?.some((n) => n.endsWith('.css')) ? 'index.css' : '[name][extname]',
|
|
27
|
-
globals: {
|
|
28
|
-
react: 'React',
|
|
29
|
-
'react-dom': 'ReactDOM',
|
|
30
|
-
'react/jsx-runtime': 'jsxRuntime',
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
});
|
package/vitest.config.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
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 pieces:
|
|
16
|
-
// `core/ax-tree.ts`, `core/ax-fetcher.ts` and the URL helper exported from
|
|
17
|
-
// `components/remote-control.tsx`.
|
|
18
|
-
export default defineConfig({
|
|
19
|
-
test: {
|
|
20
|
-
environment: 'jsdom',
|
|
21
|
-
include: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
|
|
22
|
-
globals: false,
|
|
23
|
-
},
|
|
24
|
-
});
|