@absolutejs/absolute 0.20.0-beta.65 → 0.20.0-beta.67
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +768 -544
- package/dist/build.js.map +10 -8
- package/dist/cli/index.js +148 -5
- package/dist/dev/serverBootstrap.js +544 -6
- package/dist/index.js +905 -619
- package/dist/index.js.map +14 -11
- package/dist/mobile/index.js +5430 -5
- package/dist/mobile/index.js.map +11 -8
- package/dist/mobile/mobilePreviewClient.ts +246 -0
- package/dist/mobile/remoteMacAgentEntry.js +241 -180
- package/dist/mobile/shellAuth.js +16 -0
- package/dist/mobile/shellBootstrap.js +5427 -117
- package/dist/mobile/shellExpoAuth.js +16 -0
- package/dist/mobile/shellExpoDevices.js +16 -0
- package/dist/mobile/shellExpoSync.js +16 -0
- package/dist/mobile/shellSync.js +16 -0
- package/dist/mobile/shellUpdate.js +16 -0
- package/dist/mobile/uiPrimitives.js +16 -0
- package/dist/src/build/chainInlineSourcemaps.d.ts +2 -0
- package/dist/src/build/vueCompileCache.d.ts +43 -0
- package/dist/src/cli/config/server.d.ts +1 -1
- package/dist/src/dev/bootLifecycle.d.ts +11 -0
- package/dist/src/dev/earlyListener.d.ts +41 -0
- package/dist/src/mobile/capacitorBundle.d.ts +8 -1
- package/dist/src/mobile/config.d.ts +6 -0
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/mobileInspect.d.ts +14 -0
- package/dist/src/mobile/mobilePreview.d.ts +1 -1
- package/dist/src/mobile/shellBootstrap.d.ts +2 -0
- package/dist/src/mobile/shellObservability.d.ts +11 -0
- package/dist/src/mobile/transport.d.ts +6 -0
- package/dist/src/plugins/imageOptimizer.d.ts +1 -1
- package/dist/src/utils/startupTimings.d.ts +4 -0
- package/dist/types/build.d.ts +12 -0
- package/dist/types/globals.d.ts +15 -0
- package/package.json +9 -7
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { installDeviceAdapter } from '@absolutejs/devices';
|
|
2
|
+
import {
|
|
3
|
+
createAbsoluteHttpTransport,
|
|
4
|
+
installAbsoluteHttpTransport
|
|
5
|
+
} from '@absolutejs/http';
|
|
6
|
+
import {
|
|
7
|
+
createTestDeviceAdapter,
|
|
8
|
+
type TestDeviceController
|
|
9
|
+
} from '@absolutejs/devices/testing';
|
|
10
|
+
|
|
11
|
+
type PreviewMessage =
|
|
12
|
+
| { type: 'absolute-preview:back' }
|
|
13
|
+
| { type: 'absolute-preview:deep-link'; url: string }
|
|
14
|
+
| { type: 'absolute-preview:keyboard'; heightPx: number; visible: boolean }
|
|
15
|
+
| {
|
|
16
|
+
type: 'absolute-preview:lifecycle';
|
|
17
|
+
state: 'active' | 'background' | 'inactive';
|
|
18
|
+
}
|
|
19
|
+
| {
|
|
20
|
+
type: 'absolute-preview:network';
|
|
21
|
+
connected: boolean;
|
|
22
|
+
connectionType: 'cellular' | 'none' | 'unknown' | 'wifi';
|
|
23
|
+
}
|
|
24
|
+
| {
|
|
25
|
+
type: 'absolute-preview:permission';
|
|
26
|
+
capability: 'camera' | 'location' | 'notifications';
|
|
27
|
+
state: 'blocked' | 'denied' | 'granted' | 'prompt';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
31
|
+
typeof value === 'object' && value !== null;
|
|
32
|
+
|
|
33
|
+
const isPreviewMessage = (value: unknown): value is PreviewMessage => {
|
|
34
|
+
if (!isRecord(value) || typeof value.type !== 'string') return false;
|
|
35
|
+
if (value.type === 'absolute-preview:back') return true;
|
|
36
|
+
if (value.type === 'absolute-preview:deep-link')
|
|
37
|
+
return typeof value.url === 'string';
|
|
38
|
+
if (value.type === 'absolute-preview:keyboard')
|
|
39
|
+
return (
|
|
40
|
+
typeof value.heightPx === 'number' &&
|
|
41
|
+
Number.isFinite(value.heightPx) &&
|
|
42
|
+
typeof value.visible === 'boolean'
|
|
43
|
+
);
|
|
44
|
+
if (value.type === 'absolute-preview:lifecycle')
|
|
45
|
+
return ['active', 'background', 'inactive'].includes(
|
|
46
|
+
String(value.state)
|
|
47
|
+
);
|
|
48
|
+
if (value.type === 'absolute-preview:network')
|
|
49
|
+
return (
|
|
50
|
+
typeof value.connected === 'boolean' &&
|
|
51
|
+
['cellular', 'none', 'unknown', 'wifi'].includes(
|
|
52
|
+
String(value.connectionType)
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
if (value.type === 'absolute-preview:permission')
|
|
56
|
+
return (
|
|
57
|
+
['camera', 'location', 'notifications'].includes(
|
|
58
|
+
String(value.capability)
|
|
59
|
+
) &&
|
|
60
|
+
['blocked', 'denied', 'granted', 'prompt'].includes(
|
|
61
|
+
String(value.state)
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return false;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const previewPlatform = () =>
|
|
69
|
+
new URLSearchParams(location.search).get('__absolute_preview_platform') ===
|
|
70
|
+
'android'
|
|
71
|
+
? 'android'
|
|
72
|
+
: 'ios';
|
|
73
|
+
|
|
74
|
+
const PREVIEW_STATE_KEY = Symbol.for('@absolutejs/mobile-preview/state');
|
|
75
|
+
type AbsoluteMobilePreviewState = { connected: boolean };
|
|
76
|
+
const isAbsoluteMobilePreviewState = (
|
|
77
|
+
value: unknown
|
|
78
|
+
): value is AbsoluteMobilePreviewState =>
|
|
79
|
+
isRecord(value) && typeof value.connected === 'boolean';
|
|
80
|
+
const getPreviewState = () => {
|
|
81
|
+
const existing = Reflect.get(globalThis, PREVIEW_STATE_KEY);
|
|
82
|
+
if (isAbsoluteMobilePreviewState(existing)) return existing;
|
|
83
|
+
const created: AbsoluteMobilePreviewState = { connected: true };
|
|
84
|
+
Reflect.set(globalThis, PREVIEW_STATE_KEY, created);
|
|
85
|
+
|
|
86
|
+
return created;
|
|
87
|
+
};
|
|
88
|
+
const previewState = getPreviewState();
|
|
89
|
+
const browserFetch = globalThis.fetch;
|
|
90
|
+
const nativeFetch = browserFetch.bind(globalThis);
|
|
91
|
+
const isPreviewInfrastructureRequest = (url: URL) =>
|
|
92
|
+
url.origin === location.origin &&
|
|
93
|
+
(url.pathname.startsWith('/__absolute/') ||
|
|
94
|
+
url.pathname.startsWith('/@src/') ||
|
|
95
|
+
url.pathname === '/hmr-status');
|
|
96
|
+
|
|
97
|
+
const previewPreconnect = (
|
|
98
|
+
...args: Parameters<typeof globalThis.fetch.preconnect>
|
|
99
|
+
) => {
|
|
100
|
+
const preconnect = Reflect.get(browserFetch, 'preconnect');
|
|
101
|
+
if (typeof preconnect === 'function')
|
|
102
|
+
Reflect.apply(preconnect, browserFetch, args);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const previewFetch: typeof globalThis.fetch = Object.assign(
|
|
106
|
+
(
|
|
107
|
+
input: Parameters<typeof globalThis.fetch>[0],
|
|
108
|
+
init?: Parameters<typeof globalThis.fetch>[1]
|
|
109
|
+
) => {
|
|
110
|
+
const requestUrl = new URL(
|
|
111
|
+
input instanceof Request ? input.url : String(input),
|
|
112
|
+
location.href
|
|
113
|
+
);
|
|
114
|
+
if (
|
|
115
|
+
!previewState.connected &&
|
|
116
|
+
!isPreviewInfrastructureRequest(requestUrl)
|
|
117
|
+
) {
|
|
118
|
+
return Promise.reject(
|
|
119
|
+
new TypeError(
|
|
120
|
+
'AbsoluteJS mobile preview is offline. Restore connectivity from the preview controls.'
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return nativeFetch(input, init);
|
|
126
|
+
},
|
|
127
|
+
{ preconnect: previewPreconnect }
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const installPreviewFetch = () => {
|
|
131
|
+
globalThis.fetch = previewFetch;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
let removePreviewHttpTransport: (() => void) | undefined;
|
|
135
|
+
const installPreviewHttpTransport = () => {
|
|
136
|
+
removePreviewHttpTransport?.();
|
|
137
|
+
removePreviewHttpTransport = installAbsoluteHttpTransport(
|
|
138
|
+
createAbsoluteHttpTransport({
|
|
139
|
+
fetch: previewFetch,
|
|
140
|
+
origin: location.origin,
|
|
141
|
+
runtime: 'web'
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
installPreviewFetch();
|
|
147
|
+
|
|
148
|
+
const postState = (
|
|
149
|
+
type: 'event' | 'ready',
|
|
150
|
+
detail: Record<string, unknown> = {}
|
|
151
|
+
) => {
|
|
152
|
+
if (window.parent === window) return;
|
|
153
|
+
window.parent.postMessage(
|
|
154
|
+
{
|
|
155
|
+
...detail,
|
|
156
|
+
platform: previewPlatform(),
|
|
157
|
+
type: `absolute-preview:${type}`
|
|
158
|
+
},
|
|
159
|
+
location.origin
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const reportReady = () => {
|
|
164
|
+
const durationMs = Math.max(0, Math.round(performance.now()));
|
|
165
|
+
void nativeFetch('/__absolute/mobile-preview-telemetry', {
|
|
166
|
+
body: JSON.stringify({ durationMs, platform: previewPlatform() }),
|
|
167
|
+
headers: { 'content-type': 'application/json' },
|
|
168
|
+
keepalive: true,
|
|
169
|
+
method: 'POST'
|
|
170
|
+
}).catch(() => undefined);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const emitPermission = (
|
|
174
|
+
controller: TestDeviceController,
|
|
175
|
+
message: Extract<PreviewMessage, { type: 'absolute-preview:permission' }>
|
|
176
|
+
) => {
|
|
177
|
+
const status = {
|
|
178
|
+
canRequest: message.state === 'prompt',
|
|
179
|
+
state: message.state
|
|
180
|
+
} as const;
|
|
181
|
+
if (message.capability === 'camera')
|
|
182
|
+
controller.cameraPermission.setStatus(status);
|
|
183
|
+
else if (message.capability === 'location')
|
|
184
|
+
controller.locationPermission.setStatus(status);
|
|
185
|
+
else controller.notificationPermission.setStatus(status);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const handlePreviewMessage = (
|
|
189
|
+
controller: TestDeviceController,
|
|
190
|
+
message: PreviewMessage
|
|
191
|
+
) => {
|
|
192
|
+
if (message.type === 'absolute-preview:back') {
|
|
193
|
+
controller.emitBack({ canGoBack: history.length > 1 });
|
|
194
|
+
} else if (message.type === 'absolute-preview:deep-link') {
|
|
195
|
+
controller.emitLink(message.url);
|
|
196
|
+
} else if (message.type === 'absolute-preview:keyboard') {
|
|
197
|
+
controller.emitKeyboard({
|
|
198
|
+
heightPx: Math.max(0, Math.round(message.heightPx)),
|
|
199
|
+
visible: message.visible
|
|
200
|
+
});
|
|
201
|
+
} else if (message.type === 'absolute-preview:lifecycle') {
|
|
202
|
+
controller.emitLifecycle(message.state);
|
|
203
|
+
} else if (message.type === 'absolute-preview:network') {
|
|
204
|
+
previewState.connected = message.connected;
|
|
205
|
+
// Some framework runtimes replace window.fetch while bootstrapping.
|
|
206
|
+
// Reassert the raw-fetch simulation whenever connectivity changes;
|
|
207
|
+
// @absolutejs/http remains pinned to this provider independently.
|
|
208
|
+
installPreviewFetch();
|
|
209
|
+
installPreviewHttpTransport();
|
|
210
|
+
controller.emitNetwork({
|
|
211
|
+
connected: message.connected,
|
|
212
|
+
connectionType: message.connectionType
|
|
213
|
+
});
|
|
214
|
+
} else emitPermission(controller, message);
|
|
215
|
+
postState('event', { event: message.type });
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export const installAbsoluteMobilePreview = () => {
|
|
219
|
+
if (Reflect.has(globalThis, '__ABS_MOBILE_PREVIEW__')) return;
|
|
220
|
+
const platform = previewPlatform();
|
|
221
|
+
const controller = createTestDeviceAdapter({
|
|
222
|
+
lifecycle: 'active',
|
|
223
|
+
network: { connected: true, connectionType: 'wifi' },
|
|
224
|
+
platform: {
|
|
225
|
+
formFactor: 'phone',
|
|
226
|
+
isNative: true,
|
|
227
|
+
os: platform,
|
|
228
|
+
runtime: 'capacitor',
|
|
229
|
+
safeAreaInsets:
|
|
230
|
+
platform === 'ios'
|
|
231
|
+
? { bottom: 34, left: 0, right: 0, top: 59 }
|
|
232
|
+
: { bottom: 24, left: 0, right: 0, top: 24 }
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
installDeviceAdapter(controller.adapter);
|
|
236
|
+
installPreviewHttpTransport();
|
|
237
|
+
Reflect.set(globalThis, '__ABS_MOBILE_PREVIEW__', controller);
|
|
238
|
+
addEventListener('message', (event: MessageEvent<unknown>) => {
|
|
239
|
+
if (event.origin !== location.origin || event.source !== window.parent)
|
|
240
|
+
return;
|
|
241
|
+
if (!isPreviewMessage(event.data)) return;
|
|
242
|
+
handlePreviewMessage(controller, event.data);
|
|
243
|
+
});
|
|
244
|
+
postState('ready');
|
|
245
|
+
reportReady();
|
|
246
|
+
};
|