@ng-native/platform 0.2.0 → 0.4.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/README.md +2 -2
- package/dist/adapter.d.ts +37 -3
- package/dist/adapter.js +179 -32
- package/dist/adapter.js.map +1 -1
- package/dist/http.d.ts +8 -5
- package/dist/http.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -41,8 +41,8 @@ AppRegistry.registerRunnable('main', ({ rootTag }) => {
|
|
|
41
41
|
|
|
42
42
|
- `.` - `mount()`, `NativeRendererFactory`, `PLATFORM_NATIVE_ID`, `isPlatformNative()`.
|
|
43
43
|
- `./http` - `provideNativeHttpClient()`, an `HttpClient` backend over React Native's
|
|
44
|
-
`XMLHttpRequest` (Angular's default `fetch` backend cannot read
|
|
45
|
-
|
|
44
|
+
`XMLHttpRequest` (Angular's default `fetch` backend cannot read the body of React Native's own
|
|
45
|
+
`fetch` response). Use it in place of `provideHttpClient()`.
|
|
46
46
|
|
|
47
47
|
## Docs
|
|
48
48
|
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Where the engine meets Angular, which the engine itself never imports: Renderer2 over the
|
|
3
3
|
* engine, plus bootstrap.
|
|
4
4
|
*
|
|
5
5
|
* Bootstrap leans on private `ɵ` exports of `@angular/core`, which can change in any major.
|
|
6
6
|
* `bootstrap.test.ts` asserts each one still exists, so an upgrade fails there rather than on a
|
|
7
7
|
* device.
|
|
8
8
|
*/
|
|
9
|
-
import { ApplicationRef, Renderer2, RendererFactory2, type ComponentRef, type EnvironmentProviders, type Provider, type Type } from '@angular/core';
|
|
9
|
+
import { ApplicationRef, Renderer2, RendererFactory2, type Binding, type ComponentRef, type EnvironmentProviders, type Provider, type Type } from '@angular/core';
|
|
10
10
|
import { Engine, type EngineOptions, type FabricUIManager } from '@ng-native/fabric';
|
|
11
11
|
/**
|
|
12
12
|
* The slice of Angular's component definition `createRenderer` receives that says which element
|
|
@@ -16,6 +16,7 @@ import { Engine, type EngineOptions, type FabricUIManager } from '@ng-native/fab
|
|
|
16
16
|
interface ComponentDefLike {
|
|
17
17
|
id?: string;
|
|
18
18
|
type?: unknown;
|
|
19
|
+
encapsulation?: number;
|
|
19
20
|
tView?: {
|
|
20
21
|
directiveRegistry?: readonly {
|
|
21
22
|
selectors?: readonly (readonly unknown[])[];
|
|
@@ -28,6 +29,10 @@ export declare class NativeRendererFactory implements RendererFactory2 {
|
|
|
28
29
|
private readonly renderer;
|
|
29
30
|
/** One renderer per component type, because each carries its own stylesheet. */
|
|
30
31
|
private readonly byComponent;
|
|
32
|
+
/** The global sheet each `ViewEncapsulation.None` component registered, which a hot swap replaces. */
|
|
33
|
+
private readonly globalById;
|
|
34
|
+
/** The scoped sheet each emulated or Shadow DOM component has, which a hot swap replaces. */
|
|
35
|
+
private readonly scopedById;
|
|
31
36
|
readonly engine: Engine;
|
|
32
37
|
constructor(engine: Engine);
|
|
33
38
|
/**
|
|
@@ -36,6 +41,20 @@ export declare class NativeRendererFactory implements RendererFactory2 {
|
|
|
36
41
|
* its elements match its rules and nobody else's.
|
|
37
42
|
*/
|
|
38
43
|
createRenderer(host: unknown, type: ComponentDefLike | null): Renderer2;
|
|
44
|
+
/**
|
|
45
|
+
* The sheet a component's elements are matched against, or null.
|
|
46
|
+
*
|
|
47
|
+
* `ViewEncapsulation.None`: a browser adds the component's CSS to the document as written, so
|
|
48
|
+
* its rules reach any element, its host by class among them, and `:host` matches nothing. Its
|
|
49
|
+
* sheet is a global one, registered when the component first renders, and it has none of its
|
|
50
|
+
* own. Shadow DOM stays scoped, as a shadow root scopes it.
|
|
51
|
+
*/
|
|
52
|
+
private scopedSheetOf;
|
|
53
|
+
/**
|
|
54
|
+
* Tell the engine when a hot swap gave a component another scoped sheet, or none, so the
|
|
55
|
+
* `@keyframes` the old one defined go with it. Nothing changes without a hot swap.
|
|
56
|
+
*/
|
|
57
|
+
private swapScoped;
|
|
39
58
|
/**
|
|
40
59
|
* Angular's HMR calls this before it recreates a hot-swapped component's views. The renderer
|
|
41
60
|
* cached for that component is bound to the sheet it had, so an edited stylesheet would never
|
|
@@ -78,8 +97,18 @@ export declare class NativeRendererFactory implements RendererFactory2 {
|
|
|
78
97
|
*/
|
|
79
98
|
readonly commitSoon: () => void;
|
|
80
99
|
private rendering;
|
|
100
|
+
/** How many commits there had been before the first one of this turn, while one is unsettled. */
|
|
101
|
+
private unseenSince;
|
|
102
|
+
/**
|
|
103
|
+
* Commit what the rest of this turn changes before a frame is drawn, rather than a frame later.
|
|
104
|
+
*
|
|
105
|
+
* Angular's `animate.enter` adds its class from a queue that runs after the render pass, so the
|
|
106
|
+
* element has been committed once without it. Committed again in the same turn, the class is on
|
|
107
|
+
* the view's first frame, and the engine starts the view there instead of easing to it.
|
|
108
|
+
*/
|
|
109
|
+
private settleUnseen;
|
|
81
110
|
begin(): void;
|
|
82
|
-
/** The single
|
|
111
|
+
/** The single commit point: at most one commit per change-detection pass. */
|
|
83
112
|
end(): void;
|
|
84
113
|
}
|
|
85
114
|
export interface MountResult {
|
|
@@ -96,5 +125,10 @@ export declare function mount(rootTag: number, component: Type<unknown>, fabric:
|
|
|
96
125
|
* set one afterwards. What `render()` in `@ng-native/testing` passes a component's inputs as.
|
|
97
126
|
*/
|
|
98
127
|
inputs?: Record<string, unknown>;
|
|
128
|
+
/**
|
|
129
|
+
* Bindings for the root component, as `createComponent` takes them: `outputBinding()` for a
|
|
130
|
+
* listener a template would bind. What `render()` passes its `on` as.
|
|
131
|
+
*/
|
|
132
|
+
bindings?: Binding[];
|
|
99
133
|
}): MountResult;
|
|
100
134
|
export {};
|
package/dist/adapter.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Where the engine meets Angular, which the engine itself never imports: Renderer2 over the
|
|
3
3
|
* engine, plus bootstrap.
|
|
4
4
|
*
|
|
5
5
|
* Bootstrap leans on private `ɵ` exports of `@angular/core`, which can change in any major.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { APP_BOOTSTRAP_LISTENER, ApplicationInitStatus, ApplicationRef, DOCUMENT, ErrorHandler, Renderer2, RendererFactory2, createComponent, createEnvironmentInjector, PLATFORM_ID, ɵcreateOrReusePlatformInjector as createOrReusePlatformInjector, ɵINJECTOR_SCOPE as INJECTOR_SCOPE, ɵprovideZonelessChangeDetectionInternal as provideZonelessChangeDetectionInternal, } from '@angular/core';
|
|
10
10
|
import { installDateParse } from "./date-parse.js";
|
|
11
11
|
import { PLATFORM_NATIVE_ID } from "./platform-id.js";
|
|
12
|
-
import { Engine, HostEngine, installDeferTriggers, markComponentHost, nativePlatform, onFontsRegistered, reportUnboundFormsInput, styleSheetOf, } from '@ng-native/fabric';
|
|
12
|
+
import { Engine, firstFamily, HostEngine, installDeferTriggers, markComponentHost, nativePlatform, onFontsRegistered, onFontsSettled, reportUnboundFormsInput, styleSheetOf, } from '@ng-native/fabric';
|
|
13
13
|
import { calmLoadingBanner } from "./dev-loading-view.js";
|
|
14
14
|
/**
|
|
15
15
|
* Angular `(touchEnd)` -> Fabric `topTouchEnd`.
|
|
@@ -38,6 +38,18 @@ const styleKey = (name) => name.includes('-') ? name.replace(/-([a-z])/g, (_, c)
|
|
|
38
38
|
* of one design disagreeing at the only layer that can tell.
|
|
39
39
|
*/
|
|
40
40
|
const styleValue = (value) => typeof value === 'string' && (PX.test(value) || NUMBER.test(value)) ? parseFloat(value) : value;
|
|
41
|
+
/**
|
|
42
|
+
* A `font-family` is a stack, quoted or not, where native takes one family by name: the first,
|
|
43
|
+
* unquoted, as a stylesheet rule commits it. Left as written, `'Inter-Bold'` names no font.
|
|
44
|
+
*/
|
|
45
|
+
const declaredValue = (key, value) => key === 'fontFamily' && typeof value === 'string'
|
|
46
|
+
? (firstFamily(value) ?? value)
|
|
47
|
+
: styleValue(value);
|
|
48
|
+
/**
|
|
49
|
+
* A bound custom property's name, as it was written. Angular 22 compiles `[style.--tint]` to
|
|
50
|
+
* `--%NS%tint`, for a DOM renderer to fill with a namespace; there is none here.
|
|
51
|
+
*/
|
|
52
|
+
const customPropertyName = (style) => style.replace(/%NS%/g, '');
|
|
41
53
|
/**
|
|
42
54
|
* `flex: 1; margin-top: 4px` -> `{ flex: 1, marginTop: 4 }`.
|
|
43
55
|
*
|
|
@@ -46,15 +58,9 @@ const styleValue = (value) => typeof value === 'string' && (PX.test(value) || NU
|
|
|
46
58
|
* *static* `style="..."` is not a binding at all, so it comes through `setAttribute` whole.
|
|
47
59
|
*
|
|
48
60
|
* Splitting on `;` and `:` rather than parsing properly, because the values that reach here are
|
|
49
|
-
* lengths, numbers, keywords and
|
|
50
|
-
* character would be cut in the wrong place
|
|
51
|
-
* one thing worse than not supporting them would be appearing to.
|
|
61
|
+
* lengths, numbers, keywords, colours and font families. A `url()` or a family name containing
|
|
62
|
+
* either character would be cut in the wrong place.
|
|
52
63
|
*/
|
|
53
|
-
/**
|
|
54
|
-
* A bound custom property's name, as it was written. Angular 22 compiles `[style.--tint]` to
|
|
55
|
-
* `--%NS%tint`, for a DOM renderer to fill with a namespace; there is none here.
|
|
56
|
-
*/
|
|
57
|
-
const customPropertyName = (style) => style.replace(/%NS%/g, '');
|
|
58
64
|
function parseStyleAttribute(css) {
|
|
59
65
|
const out = {};
|
|
60
66
|
for (const declaration of css.split(';')) {
|
|
@@ -67,7 +73,7 @@ function parseStyleAttribute(css) {
|
|
|
67
73
|
if (name.startsWith('--'))
|
|
68
74
|
out[name] = value;
|
|
69
75
|
else if (name)
|
|
70
|
-
out[styleKey(name)] =
|
|
76
|
+
out[styleKey(name)] = declaredValue(styleKey(name), value);
|
|
71
77
|
}
|
|
72
78
|
return out;
|
|
73
79
|
}
|
|
@@ -150,7 +156,10 @@ class NativeRenderer {
|
|
|
150
156
|
return;
|
|
151
157
|
}
|
|
152
158
|
const key = styleKey(style);
|
|
153
|
-
|
|
159
|
+
// A `var()` is for the cascade to settle, with the tokens in scope, not a value of the style.
|
|
160
|
+
if (this.engine.setBoundStyle(el, key, value))
|
|
161
|
+
return this.dropStyle(el, key);
|
|
162
|
+
const next = declaredValue(key, value);
|
|
154
163
|
const current = el.props['style'];
|
|
155
164
|
if (current && current === el.ownStyle) {
|
|
156
165
|
if (current[key] === next)
|
|
@@ -168,15 +177,21 @@ class NativeRenderer {
|
|
|
168
177
|
this.engine.setCustomProperty(el, customPropertyName(style), null);
|
|
169
178
|
return;
|
|
170
179
|
}
|
|
180
|
+
const key = styleKey(style);
|
|
181
|
+
this.engine.setBoundStyle(el, key, null);
|
|
182
|
+
this.dropStyle(el, key);
|
|
183
|
+
}
|
|
184
|
+
/** Takes `key` out of an element's inline style, if it is there. */
|
|
185
|
+
dropStyle(el, key) {
|
|
171
186
|
const current = el.props['style'];
|
|
172
|
-
if (!current || !(
|
|
187
|
+
if (!current || !(key in current))
|
|
173
188
|
return;
|
|
174
189
|
if (current === el.ownStyle) {
|
|
175
|
-
delete current[
|
|
190
|
+
delete current[key];
|
|
176
191
|
this.engine.styleChanged(el);
|
|
177
192
|
return;
|
|
178
193
|
}
|
|
179
|
-
const { [
|
|
194
|
+
const { [key]: _removed, ...rest } = current;
|
|
180
195
|
el.ownStyle = rest;
|
|
181
196
|
this.engine.setProp(el, 'style', rest);
|
|
182
197
|
}
|
|
@@ -192,12 +207,18 @@ class NativeRenderer {
|
|
|
192
207
|
return this.engine.setEventListener(target, topLevelType(eventName), callback);
|
|
193
208
|
}
|
|
194
209
|
}
|
|
210
|
+
/** `ViewEncapsulation.None`'s value in a component definition. */
|
|
211
|
+
const NONE = 2;
|
|
195
212
|
/** The attribute names in a projection selector such as `[listHeader]` or `text[slot=a]`. */
|
|
196
213
|
const PROJECTED_ATTRIBUTE = /\[([^\]=~|^$*\s]+)/g;
|
|
197
214
|
export class NativeRendererFactory {
|
|
198
215
|
renderer;
|
|
199
216
|
/** One renderer per component type, because each carries its own stylesheet. */
|
|
200
217
|
byComponent = new Map();
|
|
218
|
+
/** The global sheet each `ViewEncapsulation.None` component registered, which a hot swap replaces. */
|
|
219
|
+
globalById = new Map();
|
|
220
|
+
/** The scoped sheet each emulated or Shadow DOM component has, which a hot swap replaces. */
|
|
221
|
+
scopedById = new Map();
|
|
201
222
|
engine;
|
|
202
223
|
constructor(engine) {
|
|
203
224
|
this.engine = engine;
|
|
@@ -209,7 +230,7 @@ export class NativeRendererFactory {
|
|
|
209
230
|
* its elements match its rules and nobody else's.
|
|
210
231
|
*/
|
|
211
232
|
createRenderer(host, type) {
|
|
212
|
-
const sheet =
|
|
233
|
+
const sheet = this.scopedSheetOf(type);
|
|
213
234
|
// `host` is the element this component is mounted on, and Angular created it with the
|
|
214
235
|
// *parent's* renderer, so it carries the parent's sheet. Tagging it here is the only moment
|
|
215
236
|
// the two are both in hand, and it is what makes `:host` reachable at all.
|
|
@@ -217,7 +238,7 @@ export class NativeRendererFactory {
|
|
|
217
238
|
// It is also the one sure sign that an element hosts a component, whatever the selector
|
|
218
239
|
// that put it there, which is what tells an `<x-card>` from a typo.
|
|
219
240
|
if (host && typeof host === 'object') {
|
|
220
|
-
host
|
|
241
|
+
this.engine.setHostSheet(host, sheet);
|
|
221
242
|
markComponentHost(host);
|
|
222
243
|
}
|
|
223
244
|
if (type)
|
|
@@ -232,6 +253,47 @@ export class NativeRendererFactory {
|
|
|
232
253
|
}
|
|
233
254
|
return renderer;
|
|
234
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* The sheet a component's elements are matched against, or null.
|
|
258
|
+
*
|
|
259
|
+
* `ViewEncapsulation.None`: a browser adds the component's CSS to the document as written, so
|
|
260
|
+
* its rules reach any element, its host by class among them, and `:host` matches nothing. Its
|
|
261
|
+
* sheet is a global one, registered when the component first renders, and it has none of its
|
|
262
|
+
* own. Shadow DOM stays scoped, as a shadow root scopes it.
|
|
263
|
+
*/
|
|
264
|
+
scopedSheetOf(type) {
|
|
265
|
+
const sheet = styleSheetOf(type?.type);
|
|
266
|
+
const id = type?.id ?? '';
|
|
267
|
+
this.swapScoped(id, type?.encapsulation === NONE ? null : sheet);
|
|
268
|
+
const registered = this.globalById.get(id);
|
|
269
|
+
if (!sheet || type?.encapsulation !== NONE) {
|
|
270
|
+
// A hot swap that left the component no rules, or made it scoped: its old sheet goes, and a
|
|
271
|
+
// scoped one takes its `@keyframes` over now, before anything plays them.
|
|
272
|
+
if (registered) {
|
|
273
|
+
this.engine.removeGlobalSheet(registered);
|
|
274
|
+
if (sheet)
|
|
275
|
+
this.engine.sheetReplaced(registered, sheet);
|
|
276
|
+
}
|
|
277
|
+
this.globalById.delete(id);
|
|
278
|
+
return sheet;
|
|
279
|
+
}
|
|
280
|
+
this.engine.addGlobalSheet(sheet, registered);
|
|
281
|
+
this.globalById.set(id, sheet);
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Tell the engine when a hot swap gave a component another scoped sheet, or none, so the
|
|
286
|
+
* `@keyframes` the old one defined go with it. Nothing changes without a hot swap.
|
|
287
|
+
*/
|
|
288
|
+
swapScoped(id, sheet) {
|
|
289
|
+
const previous = this.scopedById.get(id);
|
|
290
|
+
if (previous && previous !== sheet)
|
|
291
|
+
this.engine.sheetReplaced(previous, sheet);
|
|
292
|
+
if (sheet)
|
|
293
|
+
this.scopedById.set(id, sheet);
|
|
294
|
+
else
|
|
295
|
+
this.scopedById.delete(id);
|
|
296
|
+
}
|
|
235
297
|
/**
|
|
236
298
|
* Angular's HMR calls this before it recreates a hot-swapped component's views. The renderer
|
|
237
299
|
* cached for that component is bound to the sheet it had, so an edited stylesheet would never
|
|
@@ -330,14 +392,39 @@ export class NativeRendererFactory {
|
|
|
330
392
|
this.schedule();
|
|
331
393
|
};
|
|
332
394
|
rendering = false;
|
|
395
|
+
/** How many commits there had been before the first one of this turn, while one is unsettled. */
|
|
396
|
+
unseenSince = null;
|
|
397
|
+
/**
|
|
398
|
+
* Commit what the rest of this turn changes before a frame is drawn, rather than a frame later.
|
|
399
|
+
*
|
|
400
|
+
* Angular's `animate.enter` adds its class from a queue that runs after the render pass, so the
|
|
401
|
+
* element has been committed once without it. Committed again in the same turn, the class is on
|
|
402
|
+
* the view's first frame, and the engine starts the view there instead of easing to it.
|
|
403
|
+
*/
|
|
404
|
+
settleUnseen(before) {
|
|
405
|
+
if (this.unseenSince !== null)
|
|
406
|
+
return;
|
|
407
|
+
this.unseenSince = before;
|
|
408
|
+
queueMicrotask(() => {
|
|
409
|
+
const since = this.unseenSince;
|
|
410
|
+
this.unseenSince = null;
|
|
411
|
+
if (!this.engine.pending)
|
|
412
|
+
return;
|
|
413
|
+
this.engine.commitUnseen(since);
|
|
414
|
+
if (this.engine.animating)
|
|
415
|
+
this.schedule();
|
|
416
|
+
});
|
|
417
|
+
}
|
|
333
418
|
begin() {
|
|
334
419
|
this.rendering = true;
|
|
335
420
|
this.renderStarted = globalThis.performance?.now?.() ?? Date.now();
|
|
336
421
|
}
|
|
337
|
-
/** The single
|
|
422
|
+
/** The single commit point: at most one commit per change-detection pass. */
|
|
338
423
|
end() {
|
|
339
424
|
this.rendering = false;
|
|
340
|
-
this.engine.
|
|
425
|
+
const before = this.engine.stats.commits;
|
|
426
|
+
if (this.engine.commit())
|
|
427
|
+
this.settleUnseen(before);
|
|
341
428
|
// A commit is what starts a transition, because it is where the cascade is recomputed.
|
|
342
429
|
if (this.engine.animating)
|
|
343
430
|
this.schedule();
|
|
@@ -348,11 +435,6 @@ export class NativeRendererFactory {
|
|
|
348
435
|
stats.worstRenderMs = elapsed;
|
|
349
436
|
}
|
|
350
437
|
}
|
|
351
|
-
/**
|
|
352
|
-
* `ɵINJECTOR_SCOPE` and `DOCUMENT` are both load-bearing: without the first Angular
|
|
353
|
-
* cannot resolve `ChangeDetectionSchedulerImpl` (NG0201), without the second
|
|
354
|
-
* `getStyleHost` throws NG0210.
|
|
355
|
-
*/
|
|
356
438
|
/**
|
|
357
439
|
* Angular decides whether `animate.enter` and `animate.leave` do anything when `@angular/core` is
|
|
358
440
|
* first evaluated, by reading a global that a Metro polyfill has to have set by then. Nothing
|
|
@@ -369,7 +451,26 @@ function warnIfAnimationsAreOff() {
|
|
|
369
451
|
'metro.config.js with `withAngularNative` from `@ng-native/metro/config.cjs`, which ' +
|
|
370
452
|
'adds the polyfill that sets it. Animated styles and CSS transitions work either way.');
|
|
371
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* The reload the HMR block falls back to when a change is more than a template.
|
|
456
|
+
*
|
|
457
|
+
* Each compiled component module can patch its own live class when only the template moved. For
|
|
458
|
+
* anything else - a new method, a changed selector, different imports - there is no metadata to
|
|
459
|
+
* replace, so it calls `globalThis.__angularNativeReload` instead. React Native's own Fast Refresh
|
|
460
|
+
* cannot cover for it: that is React-specific, and it accepts the update and reports success, so
|
|
461
|
+
* Metro never falls back on its own.
|
|
462
|
+
*
|
|
463
|
+
* This is installed here because `mount` is the one call every app makes. It used to be a line in
|
|
464
|
+
* an example app's entry file, which meant every other app logged "hmr reload", called an empty
|
|
465
|
+
* function, and carried on running the code from before the edit - with a second copy of every
|
|
466
|
+
* class in the changed file now loaded, which Angular reports as `NG0912`. An edit that ships and
|
|
467
|
+
* does nothing is a bad enough failure; one that also makes the next few screenshots lie about
|
|
468
|
+
* what the app is running is worse.
|
|
469
|
+
*
|
|
470
|
+
* An app that sets its own is left alone: it will have a better reason string than this one.
|
|
471
|
+
*/
|
|
372
472
|
function installReloadHook() {
|
|
473
|
+
reloadMetroThroughExpo();
|
|
373
474
|
const scope = globalThis;
|
|
374
475
|
if (scope.__angularNativeReload)
|
|
375
476
|
return;
|
|
@@ -399,6 +500,37 @@ function installReloadHook() {
|
|
|
399
500
|
devSettings?.reload('angular-native: more than a template changed');
|
|
400
501
|
};
|
|
401
502
|
}
|
|
503
|
+
/**
|
|
504
|
+
* Metro's own reload, for an edit nothing accepted: a route file, a service, or a component the
|
|
505
|
+
* hook above has already asked to reload. Metro calls React Native's Fast Refresh runtime, which
|
|
506
|
+
* calls `DevSettings.reload()`, and in Expo Go that brings the app back without Expo's native
|
|
507
|
+
* modules (`Cannot find native module 'ExpoFontLoader'`) until Expo Go is relaunched. Expo's
|
|
508
|
+
* reload works in Expo Go and a development build alike, so in an Expo app Metro's goes through
|
|
509
|
+
* it too.
|
|
510
|
+
*/
|
|
511
|
+
const THROUGH_EXPO = Symbol.for('ng-native.reloadThroughExpo');
|
|
512
|
+
function reloadMetroThroughExpo() {
|
|
513
|
+
const scope = globalThis;
|
|
514
|
+
const refresh = scope[`${scope.__METRO_GLOBAL_PREFIX__ ?? ''}__ReactRefresh`];
|
|
515
|
+
const reactNative = refresh?.performFullRefresh;
|
|
516
|
+
if (!refresh || !reactNative || reactNative[THROUGH_EXPO])
|
|
517
|
+
return;
|
|
518
|
+
try {
|
|
519
|
+
const { reloadAppAsync } = require('expo');
|
|
520
|
+
if (!reloadAppAsync)
|
|
521
|
+
return;
|
|
522
|
+
// A reload Expo could not do is still a reload the edit needs: React Native's, then.
|
|
523
|
+
const throughExpo = (reason) => void reloadAppAsync(reason).catch((error) => {
|
|
524
|
+
console.error("[angular-native] Expo's reload failed; reloading through React Native.", error);
|
|
525
|
+
reactNative.call(refresh, reason);
|
|
526
|
+
});
|
|
527
|
+
throughExpo[THROUGH_EXPO] = true;
|
|
528
|
+
refresh.performFullRefresh = throughExpo;
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
// Not an Expo app: React Native's own reload re-fetches the bundle there.
|
|
532
|
+
}
|
|
533
|
+
}
|
|
402
534
|
/** Dev only, and required rather than imported: React Native ships Flow, which Node cannot parse. */
|
|
403
535
|
function calmDevBanner() {
|
|
404
536
|
try {
|
|
@@ -427,6 +559,8 @@ function nativeAnimated() {
|
|
|
427
559
|
return null;
|
|
428
560
|
}
|
|
429
561
|
}
|
|
562
|
+
/** The root component's host until its `:host` says otherwise. See `Engine.setDefaultStyle`. */
|
|
563
|
+
const ROOT_HOST_STYLE = { height: '100%' };
|
|
430
564
|
/**
|
|
431
565
|
* Run the app's initializers, `provideAppInitializer` and `APP_INITIALIZER`, before the root
|
|
432
566
|
* component exists, as `bootstrapApplication` does. `createEnvironmentInjector` runs only
|
|
@@ -454,7 +588,7 @@ export function mount(rootTag, component, fabric, options = {}) {
|
|
|
454
588
|
calmDevBanner();
|
|
455
589
|
}
|
|
456
590
|
installDeferTriggers();
|
|
457
|
-
const { providers: extraProviders = [], inputs = {}, ...engineOptions } = options;
|
|
591
|
+
const { providers: extraProviders = [], inputs = {}, bindings, ...engineOptions } = options;
|
|
458
592
|
// The factory needs the engine and the engine needs the factory's dirty hook, so the hook is
|
|
459
593
|
// handed over once both exist rather than through the constructor.
|
|
460
594
|
const engine = new Engine(fabric, rootTag, {
|
|
@@ -474,6 +608,9 @@ export function mount(rootTag, component, fabric, options = {}) {
|
|
|
474
608
|
// null parent they simply do not exist: the router fails with NG0201 the moment it logs.
|
|
475
609
|
const platformInjector = createOrReusePlatformInjector();
|
|
476
610
|
const injector = createEnvironmentInjector([
|
|
611
|
+
// `INJECTOR_SCOPE` and `DOCUMENT` are both load-bearing: without the first Angular cannot
|
|
612
|
+
// resolve `ChangeDetectionSchedulerImpl` (NG0201), without the second `getStyleHost` throws
|
|
613
|
+
// NG0210.
|
|
477
614
|
{ provide: INJECTOR_SCOPE, useValue: 'root' },
|
|
478
615
|
provideZonelessChangeDetectionInternal(),
|
|
479
616
|
{ provide: RendererFactory2, useValue: factory },
|
|
@@ -500,16 +637,24 @@ export function mount(rootTag, component, fabric, options = {}) {
|
|
|
500
637
|
engine.setOnError((error) => injector.get(ErrorHandler).handleError(error));
|
|
501
638
|
}
|
|
502
639
|
runInitializers(injector);
|
|
503
|
-
const componentRef = createComponent(component, {
|
|
504
|
-
environmentInjector: injector,
|
|
505
|
-
// The engine root doubles as the host node.
|
|
506
|
-
hostElement: engine.root,
|
|
507
|
-
});
|
|
508
640
|
// What `@ng-native/tailwind`'s `ios:` and `android:` variants match beneath. On the root so
|
|
509
641
|
// they work with nothing to set up; an app that had to add it itself, and did not, got platform
|
|
510
|
-
// variants that silently matched nothing.
|
|
511
|
-
// root with a static `class` sets the whole list as it is created.
|
|
642
|
+
// variants that silently matched nothing.
|
|
512
643
|
engine.addClass(engine.root, `platform-${nativePlatform()}`);
|
|
644
|
+
// No `hostElement`, so Angular creates the host from the selector as it does any other
|
|
645
|
+
// component's, and it goes under the engine root as a view of its own. The engine root is the
|
|
646
|
+
// surface and is never committed: as the host it took the component's `:host` rules and sent
|
|
647
|
+
// them nowhere, so a root component's background and padding were dropped without a word.
|
|
648
|
+
const componentRef = createComponent(component, {
|
|
649
|
+
environmentInjector: injector,
|
|
650
|
+
...(bindings && { bindings }),
|
|
651
|
+
});
|
|
652
|
+
const host = componentRef.location.nativeElement;
|
|
653
|
+
// The full height of the surface, as the web's mount point is given, so a template's `flex: 1`
|
|
654
|
+
// still fills the screen. A height rather than `flex: 1`, which a `:host` height would lose to.
|
|
655
|
+
// The app's own `:host` overrides it.
|
|
656
|
+
engine.setDefaultStyle(host, ROOT_HOST_STYLE);
|
|
657
|
+
engine.appendChild(engine.root, host);
|
|
513
658
|
for (const [name, value] of Object.entries(inputs))
|
|
514
659
|
componentRef.setInput(name, value);
|
|
515
660
|
const applicationRef = injector.get(ApplicationRef);
|
|
@@ -528,8 +673,10 @@ export function mount(rootTag, component, fabric, options = {}) {
|
|
|
528
673
|
// Text laid out before its face registered is laid out again when it does: `loadFonts` is not
|
|
529
674
|
// awaited before `mount` behind a splash screen.
|
|
530
675
|
const stopFonts = onFontsRegistered((families) => engine.fontsRegistered(families));
|
|
676
|
+
const stopSettled = onFontsSettled((families) => engine.fontsSettled(families));
|
|
531
677
|
componentRef.onDestroy(() => {
|
|
532
678
|
stopFonts();
|
|
679
|
+
stopSettled();
|
|
533
680
|
applicationRef.detachView(componentRef.hostView);
|
|
534
681
|
const at = applicationRef.components.indexOf(componentRef);
|
|
535
682
|
if (at !== -1)
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The only Angular-aware file: the engine below it never imports Angular. Renderer2 over the\n * engine, plus bootstrap.\n *\n * Bootstrap leans on private `ɵ` exports of `@angular/core`, which can change in any major.\n * `bootstrap.test.ts` asserts each one still exists, so an upgrade fails there rather than on a\n * device.\n */\nimport {\n APP_BOOTSTRAP_LISTENER,\n ApplicationInitStatus,\n ApplicationRef,\n DOCUMENT,\n ErrorHandler,\n Renderer2,\n RendererFactory2,\n createComponent,\n createEnvironmentInjector,\n PLATFORM_ID,\n type ComponentRef,\n type EnvironmentInjector,\n type EnvironmentProviders,\n type Provider,\n type RendererStyleFlags2,\n type Type,\n ɵcreateOrReusePlatformInjector as createOrReusePlatformInjector,\n ɵINJECTOR_SCOPE as INJECTOR_SCOPE,\n ɵprovideZonelessChangeDetectionInternal as provideZonelessChangeDetectionInternal,\n} from '@angular/core';\nimport { installDateParse } from './date-parse.ts';\nimport { PLATFORM_NATIVE_ID } from './platform-id.ts';\nimport {\n Engine,\n HostEngine,\n installDeferTriggers,\n markComponentHost,\n nativePlatform,\n onFontsRegistered,\n reportUnboundFormsInput,\n styleSheetOf,\n type EngineNode,\n type EngineOptions,\n type FabricUIManager,\n type NativeAnimated,\n type StyleSheet,\n} from '@ng-native/fabric';\nimport { calmLoadingBanner, type LoadingBanner } from './dev-loading-view.ts';\n\n/**\n * Angular `(touchEnd)` -> Fabric `topTouchEnd`.\n *\n * There is no alias for `press`: `onPress` is not a native event, RN synthesises it in JS from\n * the touch responder system. `Pressable` in `components.ts` does the same, and because Angular\n * resolves a directive output before an element event, `(press)` on a `<pressable>` binds to\n * that output rather than reaching the renderer at all.\n */\nfunction topLevelType(eventName: string): string {\n return 'top' + eventName.charAt(0).toUpperCase() + eventName.slice(1);\n}\n\n/**\n * What Angular's compiler emits for a style binding is aimed at the DOM: `[style.font-size]`\n * arrives dash-cased, and `[style.width.px]` arrives as the string `'10px'`. Fabric reads\n * camelCase keys and plain numbers, and drops both forms without a word.\n */\nconst PX = /^-?\\d*\\.?\\d+px$/;\nconst NUMBER = /^-?\\d*\\.?\\d+$/;\nconst styleKey = (name: string): string =>\n name.includes('-') ? name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()) : name;\n/**\n * A bare number arrives as a string too, and Yoga wants a number.\n *\n * Angular parses `[style]=\"'flex: 1'\"` itself and calls `setStyle('flex', '1')`, so the same\n * declaration written as an object gave `1` and written as a string gave `'1'` - the two spellings\n * of one design disagreeing at the only layer that can tell.\n */\nconst styleValue = (value: unknown): unknown =>\n typeof value === 'string' && (PX.test(value) || NUMBER.test(value)) ? parseFloat(value) : value;\n\n/**\n * `flex: 1; margin-top: 4px` -> `{ flex: 1, marginTop: 4 }`.\n *\n * Only the static-attribute path needs this. Angular compiles `[style]` and `[style.x]` into\n * styling instructions that parse the string themselves and arrive one declaration at a time; a\n * *static* `style=\"...\"` is not a binding at all, so it comes through `setAttribute` whole.\n *\n * Splitting on `;` and `:` rather than parsing properly, because the values that reach here are\n * lengths, numbers, keywords and colours. A `url()` or a quoted font stack containing either\n * character would be cut in the wrong place - neither is expressible on this platform, and the\n * one thing worse than not supporting them would be appearing to.\n */\n/**\n * A bound custom property's name, as it was written. Angular 22 compiles `[style.--tint]` to\n * `--%NS%tint`, for a DOM renderer to fill with a namespace; there is none here.\n */\nconst customPropertyName = (style: string): string => style.replace(/%NS%/g, '');\n\nfunction parseStyleAttribute(css: string): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const declaration of css.split(';')) {\n const at = declaration.indexOf(':');\n if (at === -1) continue;\n const name = declaration.slice(0, at).trim();\n const value = declaration.slice(at + 1).trim();\n // A custom property keeps its name, which is case-sensitive, and its text for the engine.\n if (name.startsWith('--')) out[name] = value;\n else if (name) out[styleKey(name)] = styleValue(value);\n }\n return out;\n}\n\nclass NativeRenderer implements Renderer2 {\n readonly data: { [key: string]: unknown } = Object.create(null);\n destroyNode: (node: EngineNode) => void;\n\n private readonly engine: Engine;\n /** The creating component's compiled CSS. Elements this renderer makes are matched against it. */\n private readonly sheet: StyleSheet | null;\n\n constructor(engine: Engine, sheet: StyleSheet | null = null) {\n this.engine = engine;\n this.sheet = sheet;\n this.destroyNode = (node) => this.engine.destroyNode(node);\n }\n\n destroy(): void {}\n\n createElement(name: string): EngineNode {\n return this.engine.createElement(name, this.sheet);\n }\n\n createComment(): EngineNode {\n return this.engine.createAnchor();\n }\n\n createText(value: string): EngineNode {\n return this.engine.createText(value);\n }\n\n appendChild(parent: EngineNode, newChild: EngineNode): void {\n this.engine.appendChild(parent, newChild);\n }\n\n insertBefore(parent: EngineNode, newChild: EngineNode, refChild: EngineNode | null): void {\n if (!parent) return;\n this.engine.insertBefore(parent, newChild, refChild);\n }\n\n removeChild(parent: EngineNode | null, oldChild: EngineNode): void {\n this.engine.removeChild(parent, oldChild);\n }\n\n selectRootElement(selectorOrNode: string | EngineNode): EngineNode {\n if (typeof selectorOrNode !== 'string') return selectorOrNode;\n return this.engine.root;\n }\n\n parentNode(node: EngineNode): EngineNode | null {\n return this.engine.parentNode(node);\n }\n\n nextSibling(node: EngineNode): EngineNode | null {\n return this.engine.nextSibling(node);\n }\n\n setAttribute(el: EngineNode, name: string, value: string): void {\n // `class` drives selector matching, not a native prop: nothing on the native side reads it.\n if (name === 'class') {\n this.engine.setClasses(el, value);\n return;\n }\n /*\n * A *static* `style=\"flex: 1\"` is not a binding, so it never becomes a styling instruction -\n * it arrives here as one attribute holding the whole declaration list. Handing that string on\n * as the `style` prop meant Fabric received a string where it merges objects, which it drops\n * without a word: every static style in the codebase, and in this project's own doc comments,\n * was doing nothing at all.\n */\n if (name === 'style') {\n for (const [key, next] of Object.entries(parseStyleAttribute(value))) {\n this.setStyle(el, key, next);\n }\n return;\n }\n this.engine.setProp(el, name, value);\n }\n\n removeAttribute(el: EngineNode, name: string): void {\n this.engine.setProp(el, name, null);\n }\n\n addClass(el: EngineNode, name: string): void {\n this.engine.addClass(el, name);\n }\n\n removeClass(el: EngineNode, name: string): void {\n this.engine.removeClass(el, name);\n }\n\n setStyle(el: EngineNode, style: string, value: unknown, _flags?: RendererStyleFlags2): void {\n if (style.startsWith('--')) {\n this.engine.setCustomProperty(el, customPropertyName(style), value);\n return;\n }\n const key = styleKey(style);\n const next = styleValue(value);\n const current = el.props['style'] as Record<string, unknown> | undefined;\n if (current && current === el.ownStyle) {\n if (current[key] === next) return;\n current[key] = next;\n this.engine.styleChanged(el);\n return;\n }\n const owned = { ...(current ?? {}), [key]: next };\n el.ownStyle = owned;\n this.engine.setProp(el, 'style', owned);\n }\n\n removeStyle(el: EngineNode, style: string, _flags?: RendererStyleFlags2): void {\n if (style.startsWith('--')) {\n this.engine.setCustomProperty(el, customPropertyName(style), null);\n return;\n }\n const current = el.props['style'] as Record<string, unknown> | undefined;\n if (!current || !(styleKey(style) in current)) return;\n if (current === el.ownStyle) {\n delete current[styleKey(style)];\n this.engine.styleChanged(el);\n return;\n }\n const { [styleKey(style)]: _removed, ...rest } = current;\n el.ownStyle = rest;\n this.engine.setProp(el, 'style', rest);\n }\n\n setProperty(el: EngineNode, name: string, value: unknown): void {\n if (this.engine.dev) reportUnboundFormsInput(this.engine, el, name);\n this.engine.setProp(el, name, value);\n }\n\n setValue(node: EngineNode, value: string): void {\n this.engine.setText(node, value);\n }\n\n listen(\n target: EngineNode,\n eventName: string,\n callback: (event: unknown) => boolean | void,\n ): () => void {\n return this.engine.setEventListener(target, topLevelType(eventName), callback);\n }\n}\n\n/**\n * The slice of Angular's component definition `createRenderer` receives that says which element\n * names a template can legitimately contain. Private shape, read only to keep the engine's typo\n * check quiet, so a missing piece means \"nothing to declare\" rather than an error.\n */\ninterface ComponentDefLike {\n id?: string;\n type?: unknown;\n tView?: {\n directiveRegistry?:\n readonly { selectors?: readonly (readonly unknown[])[]; inputs?: object }[] | null;\n } | null;\n ngContentSelectors?: readonly string[];\n}\n\n/** The attribute names in a projection selector such as `[listHeader]` or `text[slot=a]`. */\nconst PROJECTED_ATTRIBUTE = /\\[([^\\]=~|^$*\\s]+)/g;\n\nexport class NativeRendererFactory implements RendererFactory2 {\n private readonly renderer: NativeRenderer;\n /** One renderer per component type, because each carries its own stylesheet. */\n private readonly byComponent = new Map<string, NativeRenderer>();\n readonly engine: Engine;\n\n constructor(engine: Engine) {\n this.engine = engine;\n this.renderer = new NativeRenderer(engine);\n }\n\n /**\n * Angular hands us the component definition here, which is how emulated encapsulation gets\n * scoped: the renderer a component uses is bound to that component's compiled stylesheet, so\n * its elements match its rules and nobody else's.\n */\n createRenderer(host: unknown, type: ComponentDefLike | null): Renderer2 {\n const sheet = styleSheetOf(type?.type);\n\n // `host` is the element this component is mounted on, and Angular created it with the\n // *parent's* renderer, so it carries the parent's sheet. Tagging it here is the only moment\n // the two are both in hand, and it is what makes `:host` reachable at all.\n //\n // It is also the one sure sign that an element hosts a component, whatever the selector\n // that put it there, which is what tells an `<x-card>` from a typo.\n if (host && typeof host === 'object') {\n (host as EngineNode).hostSheet = sheet;\n markComponentHost(host as EngineNode);\n }\n if (type) this.declareElements(type);\n\n if (!sheet) return this.renderer;\n\n const key = type?.id ?? '';\n let renderer = this.byComponent.get(key);\n if (!renderer) {\n renderer = new NativeRenderer(this.engine, sheet);\n this.byComponent.set(key, renderer);\n }\n return renderer;\n }\n\n /**\n * Angular's HMR calls this before it recreates a hot-swapped component's views. The renderer\n * cached for that component is bound to the sheet it had, so an edited stylesheet would never\n * reach the recreated views without letting it go.\n */\n componentReplaced(id: string): void {\n this.byComponent.delete(id);\n }\n\n /** Component definitions whose templates have been looked through already. */\n private readonly declared = new WeakSet<object>();\n\n /**\n * Tell the engine every element name this component's template may select by tag.\n *\n * Angular builds a component's template view, with its directive registry resolved from the\n * component's `imports`, before it asks for the renderer, so the registry is in hand here and\n * before the template that uses those names runs. This is what keeps a directive that owns an\n * element without hosting a component, such as Angular's `router-outlet`, from reading as a\n * typo; a component host is marked directly instead, above.\n */\n private declareElements(def: ComponentDefLike): void {\n // Only once the template view exists. The root component asks for a renderer twice, first\n // without a host and before its template view is built, and marking it seen then would\n // skip the call that has the registry.\n const registry = def.tView?.directiveRegistry;\n if (!registry || this.declared.has(def)) return;\n this.declared.add(def);\n for (const directive of registry) {\n for (const selector of directive.selectors ?? []) {\n const tag = selector[0];\n if (typeof tag === 'string' && tag) this.engine.declareElement(tag);\n }\n }\n this.declareAttributes(def, registry);\n }\n\n /**\n * Tell the engine the attribute names that are Angular's rather than a native view's: what a\n * directive selects on or takes as an input, which Angular also writes to the node as a static\n * attribute, and what the component's `<ng-content select>` projects by.\n */\n private declareAttributes(\n def: ComponentDefLike,\n registry: NonNullable<NonNullable<ComponentDefLike['tView']>['directiveRegistry']>,\n ): void {\n for (const directive of registry) {\n for (const selector of directive.selectors ?? []) {\n for (const name of selector.filter((part, at) => at % 2 === 1)) {\n if (typeof name === 'string') this.engine.declareAttribute(name);\n }\n }\n for (const input of Object.keys(directive.inputs ?? {})) this.engine.declareAttribute(input);\n }\n for (const selector of def.ngContentSelectors ?? []) {\n for (const [, name] of selector.matchAll(PROJECTED_ATTRIBUTE)) {\n this.engine.declareAttribute(name!);\n }\n }\n }\n\n private renderStarted = 0;\n private frame = 0;\n\n /**\n * Drive CSS transitions.\n *\n * A transition is not a binding: nothing in Angular changes while one runs, so change detection\n * would never fire again and the animation would stop on its first frame. This pumps the engine\n * directly for as long as one has frames left, and commits each one.\n */\n private readonly pump = (): void => {\n this.frame = 0;\n this.engine.advanceAnimations();\n // Also the commit for anything changed outside change detection. Angular's `animate.enter`\n // and `animate.leave` add their classes from an animation queue that runs after the render\n // pass, so without a frame behind it the class would sit on the node and never reach native.\n this.engine.commit();\n // `pending` as well as `transitioning`: a transition's end listener runs after the commit\n // that finished it, and removing a leaving element is exactly what it tends to do.\n if (this.engine.animating || this.engine.pending) this.schedule();\n };\n\n private schedule(): void {\n if (this.frame) return;\n // `requestAnimationFrame` is a global in React Native. The fallback is for Node, where the\n // suite drives `advanceTransitions` itself and this never runs.\n const request =\n globalThis.requestAnimationFrame ??\n ((callback: FrameRequestCallback) => setTimeout(() => callback(Date.now()), 16));\n this.frame = request(this.pump) as unknown as number;\n }\n\n /**\n * A change that lands outside a render pass has no commit coming. The engine reports the moment\n * the tree goes dirty, and this arranges a frame for it, which is how the classes Angular's\n * animation queue adds after a pass reach native at all.\n */\n readonly commitSoon = (): void => {\n if (!this.rendering) this.schedule();\n };\n\n private rendering = false;\n\n begin(): void {\n this.rendering = true;\n this.renderStarted = globalThis.performance?.now?.() ?? Date.now();\n }\n\n /** The single flush point: at most one commit per change-detection pass. */\n end(): void {\n this.rendering = false;\n this.engine.commit();\n\n // A commit is what starts a transition, because it is where the cascade is recomputed.\n if (this.engine.animating) this.schedule();\n\n // Excludes the mount, which is not representative of a steady-state frame.\n const elapsed = (globalThis.performance?.now?.() ?? Date.now()) - this.renderStarted;\n const stats = this.engine.stats;\n if (stats.commits > 1 && elapsed > stats.worstRenderMs) stats.worstRenderMs = elapsed;\n }\n}\n\nexport interface MountResult {\n componentRef: ComponentRef<unknown>;\n applicationRef: ApplicationRef;\n factory: NativeRendererFactory;\n engine: Engine;\n}\n\n/**\n * `ɵINJECTOR_SCOPE` and `DOCUMENT` are both load-bearing: without the first Angular\n * cannot resolve `ChangeDetectionSchedulerImpl` (NG0201), without the second\n * `getStyleHost` throws NG0210.\n */\n/**\n * Angular decides whether `animate.enter` and `animate.leave` do anything when `@angular/core` is\n * first evaluated, by reading a global that a Metro polyfill has to have set by then. Nothing\n * later can change the answer, so the most that can be done is to notice and say so. Checked here\n * because booting is the one moment every app passes through.\n */\nfunction warnIfAnimationsAreOff(): void {\n const document = (globalThis as { document?: { documentElement?: { getAnimations?: unknown } } })\n .document;\n if (typeof document?.documentElement?.getAnimations === 'function') return;\n console.error(\n '[angular-native] `animate.enter` and `animate.leave` will do nothing: Angular reads ' +\n 'whether to support them when it is first imported, before anything here runs. Build ' +\n 'metro.config.js with `withAngularNative` from `@ng-native/metro/config.cjs`, which ' +\n 'adds the polyfill that sets it. Animated styles and CSS transitions work either way.',\n );\n}\n\n/**\n * The reload the HMR block falls back to when a change is more than a template.\n *\n * Each compiled component module can patch its own live class when only the template moved. For\n * anything else - a new method, a changed selector, different imports - there is no metadata to\n * replace, so it calls `globalThis.__angularNativeReload` instead. React Native's own Fast Refresh\n * cannot cover for it: that is React-specific, and it accepts the update and reports success, so\n * Metro never falls back on its own.\n *\n * This is installed here because `mount` is the one call every app makes. It used to be a line in\n * an example app's entry file, which meant every other app logged \"hmr reload\", called an empty\n * function, and carried on running the code from before the edit - with a second copy of every\n * class in the changed file now loaded, which Angular reports as `NG0912`. An edit that ships and\n * does nothing is a bad enough failure; one that also makes the next few screenshots lie about\n * what the app is running is worse.\n *\n * An app that sets its own is left alone: it will have a better reason string than this one.\n */\ndeclare const __DEV__: boolean | undefined;\n\nfunction installReloadHook(): void {\n const scope = globalThis as { __angularNativeReload?: () => void };\n if (scope.__angularNativeReload) return;\n scope.__angularNativeReload = () => {\n /*\n * Expo's reload first, React Native's only as a fallback.\n *\n * `DevSettings.reload()` under Expo Go re-runs the bundle the app downloaded when it launched\n * rather than fetching the current one, so the app comes back holding the code from before\n * the edit - forever one generation behind, however long you wait. That is worse than not\n * reloading, because it looks like it worked.\n *\n * Required rather than imported, both of them: React Native ships Flow, which Node cannot\n * parse, and this file has to stay importable by the test suite. Expo is genuinely optional.\n */\n try {\n const expo = require('expo') as { reloadAppAsync?: (reason?: string) => Promise<void> };\n if (expo.reloadAppAsync) {\n void expo.reloadAppAsync('angular-native: more than a template changed');\n return;\n }\n } catch {\n // Not an Expo app. React Native's own reload does re-fetch outside Expo Go.\n }\n const devSettings = (\n require('react-native') as { DevSettings?: { reload(reason?: string): void } }\n ).DevSettings;\n devSettings?.reload('angular-native: more than a template changed');\n };\n}\n\n/** Dev only, and required rather than imported: React Native ships Flow, which Node cannot parse. */\nfunction calmDevBanner(): void {\n try {\n const { default: banner } = require('react-native/Libraries/Utilities/DevLoadingView') as {\n default?: LoadingBanner;\n };\n if (banner) calmLoadingBanner(banner);\n } catch {\n // No React Native under us: a test, or the web.\n }\n}\n\n/**\n * React Native's `NativeAnimatedHelper`, for the engine to move sticky headers by a scroll on the\n * native side. Required rather than imported for the same reason as the banner, and null where\n * there is no native animated module to talk to: a test, or the web.\n */\nfunction nativeAnimated(): NativeAnimated | null {\n try {\n const { default: helper } =\n require('react-native/src/private/animated/NativeAnimatedHelper') as {\n default?: NativeAnimated & { assertNativeAnimatedModule(): void };\n };\n if (!helper) return null;\n helper.assertNativeAnimatedModule();\n return helper;\n } catch {\n return null;\n }\n}\n\n/**\n * Run the app's initializers, `provideAppInitializer` and `APP_INITIALIZER`, before the root\n * component exists, as `bootstrapApplication` does. `createEnvironmentInjector` runs only\n * environment initializers, so without this an app initializer silently never ran.\n *\n * Through Angular's own `ApplicationInitStatus`, so its `done` and `donePromise` stay true to what\n * happened for anything that waits on them. `runInitializers` is what Angular's bootstrap calls;\n * it is missing from the public types, which is why it is reached through a cast.\n *\n * An initializer that returns a promise is started, not awaited: `mount` is synchronous and the\n * first frame does not wait. One that fails reaches the `ErrorHandler` rather than vanishing.\n */\nfunction runInitializers(injector: EnvironmentInjector): void {\n const status = injector.get(ApplicationInitStatus);\n (status as unknown as { runInitializers(): void }).runInitializers();\n status.donePromise.catch((error: unknown) => injector.get(ErrorHandler).handleError(error));\n}\n\nexport function mount(\n rootTag: number,\n component: Type<unknown>,\n fabric: FabricUIManager,\n options: EngineOptions & {\n providers?: (Provider | EnvironmentProviders)[];\n /**\n * Root component inputs, set before its first change detection. That is the only moment a\n * `required` input can be given, and `mount` runs that first pass itself, so a caller cannot\n * set one afterwards. What `render()` in `@ng-native/testing` passes a component's inputs as.\n */\n inputs?: Record<string, unknown>;\n } = {},\n): MountResult {\n // The bare identifier, behind `typeof` so Node does not throw: Metro inlines `__DEV__` and folds\n // this branch away in a release build, and a property read through `globalThis` it cannot, which\n // left the reload hook and its `require('expo')` in every release bundle.\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n warnIfAnimationsAreOff();\n installReloadHook();\n calmDevBanner();\n }\n installDeferTriggers();\n const { providers: extraProviders = [], inputs = {}, ...engineOptions } = options;\n // The factory needs the engine and the engine needs the factory's dirty hook, so the hook is\n // handed over once both exist rather than through the constructor.\n const engine = new Engine(fabric, rootTag, {\n ...engineOptions,\n nativeAnimated:\n engineOptions.nativeAnimated === undefined ? nativeAnimated() : engineOptions.nativeAnimated,\n });\n installDateParse(engine.dev);\n const factory = new NativeRendererFactory(engine);\n engine.setOnDirty(factory.commitSoon);\n // `getElementById` is what `TransferState` calls, and `TransferState` is what `resource()`\n // reaches for the moment one is created. Without it every resource in an app throws\n // `doc.getElementById is not a function` before its loader has run - which is a long way from\n // anything a stylesheet does, and is why the stub is not as thin as it looks.\n const documentStub = { head: undefined, body: undefined, getElementById: () => null };\n\n // Parent the app injector to the platform injector, exactly as `internalCreateApplication`\n // does. Some Angular services are `providedIn: 'platform'` - `Console` among them - and with a\n // null parent they simply do not exist: the router fails with NG0201 the moment it logs.\n const platformInjector = createOrReusePlatformInjector();\n\n const injector = createEnvironmentInjector(\n [\n { provide: INJECTOR_SCOPE, useValue: 'root' },\n provideZonelessChangeDetectionInternal(),\n { provide: RendererFactory2, useValue: factory },\n // Exposed so a component can read commit stats, or reach a node for a native command.\n { provide: Engine, useValue: engine },\n // The contract the shared packages inject. `Engine` is still provided under its own token\n // for the three worklet components that need Fabric's own handles. See `fabric/host.ts`.\n { provide: HostEngine, useExisting: Engine },\n { provide: DOCUMENT, useValue: documentStub },\n // 'native', not Angular's default 'unknown': see `platform-id.ts`.\n { provide: PLATFORM_ID, useValue: PLATFORM_NATIVE_ID },\n { provide: ErrorHandler, useClass: ErrorHandler },\n ...extraProviders,\n ],\n // The platform injector is an EnvironmentInjector in practice; the factory's return type is\n // just declared more loosely.\n platformInjector as EnvironmentInjector,\n );\n\n // Errors the engine catches in its native event dispatch, which is outside every Angular\n // listener wrapper: responder handlers, engine-level listeners, a commit a focus change starts.\n // Looked up when one happens rather than now, as Angular's own handler is, so an app's\n // `ErrorHandler` that injects something not yet constructible is not forced at boot. A caller\n // that passed its own `onError` keeps it.\n if (!engineOptions.onError) {\n engine.setOnError((error) => injector.get(ErrorHandler).handleError(error));\n }\n\n runInitializers(injector);\n\n const componentRef = createComponent(component, {\n environmentInjector: injector,\n // The engine root doubles as the host node.\n hostElement: engine.root as unknown as Element,\n });\n\n // What `@ng-native/tailwind`'s `ios:` and `android:` variants match beneath. On the root so\n // they work with nothing to set up; an app that had to add it itself, and did not, got platform\n // variants that silently matched nothing. After the component rather than before, because a\n // root with a static `class` sets the whole list as it is created.\n engine.addClass(engine.root, `platform-${nativePlatform()}`);\n\n for (const [name, value] of Object.entries(inputs)) componentRef.setInput(name, value);\n\n const applicationRef = injector.get(ApplicationRef);\n\n // `ApplicationRef.bootstrap()` does all of this; `createComponent` does not, and we\n // deliberately do not use `bootstrap()` because it wants a DOM selector. Order and\n // bookkeeping both matter, so this mirrors `_loadComponent` step for step.\n applicationRef.componentTypes.push(component);\n applicationRef.attachView(componentRef.hostView);\n // Before the listeners, so the root component's template has run and any outlet in it has\n // registered itself by the time the router's initial navigation activates a route.\n applicationRef.tick();\n // Load-bearing, not bookkeeping: the router's bootstrap listener returns early unless the\n // ref it is handed is `ApplicationRef.components[0]`, so with an empty array the initial\n // navigation never runs and a routed app renders nothing but its outlet's host.\n applicationRef.components.push(componentRef);\n // Text laid out before its face registered is laid out again when it does: `loadFonts` is not\n // awaited before `mount` behind a splash screen.\n const stopFonts = onFontsRegistered((families) => engine.fontsRegistered(families));\n componentRef.onDestroy(() => {\n stopFonts();\n applicationRef.detachView(componentRef.hostView);\n const at = applicationRef.components.indexOf(componentRef);\n if (at !== -1) applicationRef.components.splice(at, 1);\n });\n\n for (const listener of injector.get(APP_BOOTSTRAP_LISTENER, [])) {\n listener(componentRef);\n }\n\n return { componentRef, applicationRef, factory, engine };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where the engine meets Angular, which the engine itself never imports: Renderer2 over the\n * engine, plus bootstrap.\n *\n * Bootstrap leans on private `ɵ` exports of `@angular/core`, which can change in any major.\n * `bootstrap.test.ts` asserts each one still exists, so an upgrade fails there rather than on a\n * device.\n */\nimport {\n APP_BOOTSTRAP_LISTENER,\n ApplicationInitStatus,\n ApplicationRef,\n DOCUMENT,\n ErrorHandler,\n Renderer2,\n RendererFactory2,\n createComponent,\n createEnvironmentInjector,\n PLATFORM_ID,\n type Binding,\n type ComponentRef,\n type EnvironmentInjector,\n type EnvironmentProviders,\n type Provider,\n type RendererStyleFlags2,\n type Type,\n ɵcreateOrReusePlatformInjector as createOrReusePlatformInjector,\n ɵINJECTOR_SCOPE as INJECTOR_SCOPE,\n ɵprovideZonelessChangeDetectionInternal as provideZonelessChangeDetectionInternal,\n} from '@angular/core';\nimport { installDateParse } from './date-parse.ts';\nimport { PLATFORM_NATIVE_ID } from './platform-id.ts';\nimport {\n Engine,\n firstFamily,\n HostEngine,\n installDeferTriggers,\n markComponentHost,\n nativePlatform,\n onFontsRegistered,\n onFontsSettled,\n reportUnboundFormsInput,\n styleSheetOf,\n type EngineNode,\n type EngineOptions,\n type FabricUIManager,\n type NativeAnimated,\n type StyleSheet,\n} from '@ng-native/fabric';\nimport { calmLoadingBanner, type LoadingBanner } from './dev-loading-view.ts';\n\n/**\n * Angular `(touchEnd)` -> Fabric `topTouchEnd`.\n *\n * There is no alias for `press`: `onPress` is not a native event, RN synthesises it in JS from\n * the touch responder system. `Pressable` in `components.ts` does the same, and because Angular\n * resolves a directive output before an element event, `(press)` on a `<pressable>` binds to\n * that output rather than reaching the renderer at all.\n */\nfunction topLevelType(eventName: string): string {\n return 'top' + eventName.charAt(0).toUpperCase() + eventName.slice(1);\n}\n\n/**\n * What Angular's compiler emits for a style binding is aimed at the DOM: `[style.font-size]`\n * arrives dash-cased, and `[style.width.px]` arrives as the string `'10px'`. Fabric reads\n * camelCase keys and plain numbers, and drops both forms without a word.\n */\nconst PX = /^-?\\d*\\.?\\d+px$/;\nconst NUMBER = /^-?\\d*\\.?\\d+$/;\nconst styleKey = (name: string): string =>\n name.includes('-') ? name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()) : name;\n/**\n * A bare number arrives as a string too, and Yoga wants a number.\n *\n * Angular parses `[style]=\"'flex: 1'\"` itself and calls `setStyle('flex', '1')`, so the same\n * declaration written as an object gave `1` and written as a string gave `'1'` - the two spellings\n * of one design disagreeing at the only layer that can tell.\n */\nconst styleValue = (value: unknown): unknown =>\n typeof value === 'string' && (PX.test(value) || NUMBER.test(value)) ? parseFloat(value) : value;\n/**\n * A `font-family` is a stack, quoted or not, where native takes one family by name: the first,\n * unquoted, as a stylesheet rule commits it. Left as written, `'Inter-Bold'` names no font.\n */\nconst declaredValue = (key: string, value: unknown): unknown =>\n key === 'fontFamily' && typeof value === 'string'\n ? (firstFamily(value) ?? value)\n : styleValue(value);\n\n/**\n * A bound custom property's name, as it was written. Angular 22 compiles `[style.--tint]` to\n * `--%NS%tint`, for a DOM renderer to fill with a namespace; there is none here.\n */\nconst customPropertyName = (style: string): string => style.replace(/%NS%/g, '');\n\n/**\n * `flex: 1; margin-top: 4px` -> `{ flex: 1, marginTop: 4 }`.\n *\n * Only the static-attribute path needs this. Angular compiles `[style]` and `[style.x]` into\n * styling instructions that parse the string themselves and arrive one declaration at a time; a\n * *static* `style=\"...\"` is not a binding at all, so it comes through `setAttribute` whole.\n *\n * Splitting on `;` and `:` rather than parsing properly, because the values that reach here are\n * lengths, numbers, keywords, colours and font families. A `url()` or a family name containing\n * either character would be cut in the wrong place.\n */\nfunction parseStyleAttribute(css: string): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const declaration of css.split(';')) {\n const at = declaration.indexOf(':');\n if (at === -1) continue;\n const name = declaration.slice(0, at).trim();\n const value = declaration.slice(at + 1).trim();\n // A custom property keeps its name, which is case-sensitive, and its text for the engine.\n if (name.startsWith('--')) out[name] = value;\n else if (name) out[styleKey(name)] = declaredValue(styleKey(name), value);\n }\n return out;\n}\n\nclass NativeRenderer implements Renderer2 {\n readonly data: { [key: string]: unknown } = Object.create(null);\n destroyNode: (node: EngineNode) => void;\n\n private readonly engine: Engine;\n /** The creating component's compiled CSS. Elements this renderer makes are matched against it. */\n private readonly sheet: StyleSheet | null;\n\n constructor(engine: Engine, sheet: StyleSheet | null = null) {\n this.engine = engine;\n this.sheet = sheet;\n this.destroyNode = (node) => this.engine.destroyNode(node);\n }\n\n destroy(): void {}\n\n createElement(name: string): EngineNode {\n return this.engine.createElement(name, this.sheet);\n }\n\n createComment(): EngineNode {\n return this.engine.createAnchor();\n }\n\n createText(value: string): EngineNode {\n return this.engine.createText(value);\n }\n\n appendChild(parent: EngineNode, newChild: EngineNode): void {\n this.engine.appendChild(parent, newChild);\n }\n\n insertBefore(parent: EngineNode, newChild: EngineNode, refChild: EngineNode | null): void {\n if (!parent) return;\n this.engine.insertBefore(parent, newChild, refChild);\n }\n\n removeChild(parent: EngineNode | null, oldChild: EngineNode): void {\n this.engine.removeChild(parent, oldChild);\n }\n\n selectRootElement(selectorOrNode: string | EngineNode): EngineNode {\n if (typeof selectorOrNode !== 'string') return selectorOrNode;\n return this.engine.root;\n }\n\n parentNode(node: EngineNode): EngineNode | null {\n return this.engine.parentNode(node);\n }\n\n nextSibling(node: EngineNode): EngineNode | null {\n return this.engine.nextSibling(node);\n }\n\n setAttribute(el: EngineNode, name: string, value: string): void {\n // `class` drives selector matching, not a native prop: nothing on the native side reads it.\n if (name === 'class') {\n this.engine.setClasses(el, value);\n return;\n }\n /*\n * A *static* `style=\"flex: 1\"` is not a binding, so it never becomes a styling instruction -\n * it arrives here as one attribute holding the whole declaration list. Handing that string on\n * as the `style` prop meant Fabric received a string where it merges objects, which it drops\n * without a word: every static style in the codebase, and in this project's own doc comments,\n * was doing nothing at all.\n */\n if (name === 'style') {\n for (const [key, next] of Object.entries(parseStyleAttribute(value))) {\n this.setStyle(el, key, next);\n }\n return;\n }\n this.engine.setProp(el, name, value);\n }\n\n removeAttribute(el: EngineNode, name: string): void {\n this.engine.setProp(el, name, null);\n }\n\n addClass(el: EngineNode, name: string): void {\n this.engine.addClass(el, name);\n }\n\n removeClass(el: EngineNode, name: string): void {\n this.engine.removeClass(el, name);\n }\n\n setStyle(el: EngineNode, style: string, value: unknown, _flags?: RendererStyleFlags2): void {\n if (style.startsWith('--')) {\n this.engine.setCustomProperty(el, customPropertyName(style), value);\n return;\n }\n const key = styleKey(style);\n // A `var()` is for the cascade to settle, with the tokens in scope, not a value of the style.\n if (this.engine.setBoundStyle(el, key, value)) return this.dropStyle(el, key);\n const next = declaredValue(key, value);\n const current = el.props['style'] as Record<string, unknown> | undefined;\n if (current && current === el.ownStyle) {\n if (current[key] === next) return;\n current[key] = next;\n this.engine.styleChanged(el);\n return;\n }\n const owned = { ...(current ?? {}), [key]: next };\n el.ownStyle = owned;\n this.engine.setProp(el, 'style', owned);\n }\n\n removeStyle(el: EngineNode, style: string, _flags?: RendererStyleFlags2): void {\n if (style.startsWith('--')) {\n this.engine.setCustomProperty(el, customPropertyName(style), null);\n return;\n }\n const key = styleKey(style);\n this.engine.setBoundStyle(el, key, null);\n this.dropStyle(el, key);\n }\n\n /** Takes `key` out of an element's inline style, if it is there. */\n private dropStyle(el: EngineNode, key: string): void {\n const current = el.props['style'] as Record<string, unknown> | undefined;\n if (!current || !(key in current)) return;\n if (current === el.ownStyle) {\n delete current[key];\n this.engine.styleChanged(el);\n return;\n }\n const { [key]: _removed, ...rest } = current;\n el.ownStyle = rest;\n this.engine.setProp(el, 'style', rest);\n }\n\n setProperty(el: EngineNode, name: string, value: unknown): void {\n if (this.engine.dev) reportUnboundFormsInput(this.engine, el, name);\n this.engine.setProp(el, name, value);\n }\n\n setValue(node: EngineNode, value: string): void {\n this.engine.setText(node, value);\n }\n\n listen(\n target: EngineNode,\n eventName: string,\n callback: (event: unknown) => boolean | void,\n ): () => void {\n return this.engine.setEventListener(target, topLevelType(eventName), callback);\n }\n}\n\n/**\n * The slice of Angular's component definition `createRenderer` receives that says which element\n * names a template can legitimately contain. Private shape, read only to keep the engine's typo\n * check quiet, so a missing piece means \"nothing to declare\" rather than an error.\n */\ninterface ComponentDefLike {\n id?: string;\n type?: unknown;\n encapsulation?: number;\n tView?: {\n directiveRegistry?:\n readonly { selectors?: readonly (readonly unknown[])[]; inputs?: object }[] | null;\n } | null;\n ngContentSelectors?: readonly string[];\n}\n\n/** `ViewEncapsulation.None`'s value in a component definition. */\nconst NONE = 2;\n\n/** The attribute names in a projection selector such as `[listHeader]` or `text[slot=a]`. */\nconst PROJECTED_ATTRIBUTE = /\\[([^\\]=~|^$*\\s]+)/g;\n\nexport class NativeRendererFactory implements RendererFactory2 {\n private readonly renderer: NativeRenderer;\n /** One renderer per component type, because each carries its own stylesheet. */\n private readonly byComponent = new Map<string, NativeRenderer>();\n /** The global sheet each `ViewEncapsulation.None` component registered, which a hot swap replaces. */\n private readonly globalById = new Map<string, StyleSheet>();\n /** The scoped sheet each emulated or Shadow DOM component has, which a hot swap replaces. */\n private readonly scopedById = new Map<string, StyleSheet>();\n readonly engine: Engine;\n\n constructor(engine: Engine) {\n this.engine = engine;\n this.renderer = new NativeRenderer(engine);\n }\n\n /**\n * Angular hands us the component definition here, which is how emulated encapsulation gets\n * scoped: the renderer a component uses is bound to that component's compiled stylesheet, so\n * its elements match its rules and nobody else's.\n */\n createRenderer(host: unknown, type: ComponentDefLike | null): Renderer2 {\n const sheet = this.scopedSheetOf(type);\n\n // `host` is the element this component is mounted on, and Angular created it with the\n // *parent's* renderer, so it carries the parent's sheet. Tagging it here is the only moment\n // the two are both in hand, and it is what makes `:host` reachable at all.\n //\n // It is also the one sure sign that an element hosts a component, whatever the selector\n // that put it there, which is what tells an `<x-card>` from a typo.\n if (host && typeof host === 'object') {\n this.engine.setHostSheet(host as EngineNode, sheet);\n markComponentHost(host as EngineNode);\n }\n if (type) this.declareElements(type);\n\n if (!sheet) return this.renderer;\n\n const key = type?.id ?? '';\n let renderer = this.byComponent.get(key);\n if (!renderer) {\n renderer = new NativeRenderer(this.engine, sheet);\n this.byComponent.set(key, renderer);\n }\n return renderer;\n }\n\n /**\n * The sheet a component's elements are matched against, or null.\n *\n * `ViewEncapsulation.None`: a browser adds the component's CSS to the document as written, so\n * its rules reach any element, its host by class among them, and `:host` matches nothing. Its\n * sheet is a global one, registered when the component first renders, and it has none of its\n * own. Shadow DOM stays scoped, as a shadow root scopes it.\n */\n private scopedSheetOf(type: ComponentDefLike | null): StyleSheet | null {\n const sheet = styleSheetOf(type?.type);\n const id = type?.id ?? '';\n this.swapScoped(id, type?.encapsulation === NONE ? null : sheet);\n const registered = this.globalById.get(id);\n if (!sheet || type?.encapsulation !== NONE) {\n // A hot swap that left the component no rules, or made it scoped: its old sheet goes, and a\n // scoped one takes its `@keyframes` over now, before anything plays them.\n if (registered) {\n this.engine.removeGlobalSheet(registered);\n if (sheet) this.engine.sheetReplaced(registered, sheet);\n }\n this.globalById.delete(id);\n return sheet;\n }\n this.engine.addGlobalSheet(sheet, registered);\n this.globalById.set(id, sheet);\n return null;\n }\n\n /**\n * Tell the engine when a hot swap gave a component another scoped sheet, or none, so the\n * `@keyframes` the old one defined go with it. Nothing changes without a hot swap.\n */\n private swapScoped(id: string, sheet: StyleSheet | null): void {\n const previous = this.scopedById.get(id);\n if (previous && previous !== sheet) this.engine.sheetReplaced(previous, sheet);\n if (sheet) this.scopedById.set(id, sheet);\n else this.scopedById.delete(id);\n }\n\n /**\n * Angular's HMR calls this before it recreates a hot-swapped component's views. The renderer\n * cached for that component is bound to the sheet it had, so an edited stylesheet would never\n * reach the recreated views without letting it go.\n */\n componentReplaced(id: string): void {\n this.byComponent.delete(id);\n }\n\n /** Component definitions whose templates have been looked through already. */\n private readonly declared = new WeakSet<object>();\n\n /**\n * Tell the engine every element name this component's template may select by tag.\n *\n * Angular builds a component's template view, with its directive registry resolved from the\n * component's `imports`, before it asks for the renderer, so the registry is in hand here and\n * before the template that uses those names runs. This is what keeps a directive that owns an\n * element without hosting a component, such as Angular's `router-outlet`, from reading as a\n * typo; a component host is marked directly instead, above.\n */\n private declareElements(def: ComponentDefLike): void {\n // Only once the template view exists. The root component asks for a renderer twice, first\n // without a host and before its template view is built, and marking it seen then would\n // skip the call that has the registry.\n const registry = def.tView?.directiveRegistry;\n if (!registry || this.declared.has(def)) return;\n this.declared.add(def);\n for (const directive of registry) {\n for (const selector of directive.selectors ?? []) {\n const tag = selector[0];\n if (typeof tag === 'string' && tag) this.engine.declareElement(tag);\n }\n }\n this.declareAttributes(def, registry);\n }\n\n /**\n * Tell the engine the attribute names that are Angular's rather than a native view's: what a\n * directive selects on or takes as an input, which Angular also writes to the node as a static\n * attribute, and what the component's `<ng-content select>` projects by.\n */\n private declareAttributes(\n def: ComponentDefLike,\n registry: NonNullable<NonNullable<ComponentDefLike['tView']>['directiveRegistry']>,\n ): void {\n for (const directive of registry) {\n for (const selector of directive.selectors ?? []) {\n for (const name of selector.filter((part, at) => at % 2 === 1)) {\n if (typeof name === 'string') this.engine.declareAttribute(name);\n }\n }\n for (const input of Object.keys(directive.inputs ?? {})) this.engine.declareAttribute(input);\n }\n for (const selector of def.ngContentSelectors ?? []) {\n for (const [, name] of selector.matchAll(PROJECTED_ATTRIBUTE)) {\n this.engine.declareAttribute(name!);\n }\n }\n }\n\n private renderStarted = 0;\n private frame = 0;\n\n /**\n * Drive CSS transitions.\n *\n * A transition is not a binding: nothing in Angular changes while one runs, so change detection\n * would never fire again and the animation would stop on its first frame. This pumps the engine\n * directly for as long as one has frames left, and commits each one.\n */\n private readonly pump = (): void => {\n this.frame = 0;\n this.engine.advanceAnimations();\n // Also the commit for anything changed outside change detection. Angular's `animate.enter`\n // and `animate.leave` add their classes from an animation queue that runs after the render\n // pass, so without a frame behind it the class would sit on the node and never reach native.\n this.engine.commit();\n // `pending` as well as `transitioning`: a transition's end listener runs after the commit\n // that finished it, and removing a leaving element is exactly what it tends to do.\n if (this.engine.animating || this.engine.pending) this.schedule();\n };\n\n private schedule(): void {\n if (this.frame) return;\n // `requestAnimationFrame` is a global in React Native. The fallback is for Node, where the\n // suite drives `advanceTransitions` itself and this never runs.\n const request =\n globalThis.requestAnimationFrame ??\n ((callback: FrameRequestCallback) => setTimeout(() => callback(Date.now()), 16));\n this.frame = request(this.pump) as unknown as number;\n }\n\n /**\n * A change that lands outside a render pass has no commit coming. The engine reports the moment\n * the tree goes dirty, and this arranges a frame for it, which is how the classes Angular's\n * animation queue adds after a pass reach native at all.\n */\n readonly commitSoon = (): void => {\n if (!this.rendering) this.schedule();\n };\n\n private rendering = false;\n /** How many commits there had been before the first one of this turn, while one is unsettled. */\n private unseenSince: number | null = null;\n\n /**\n * Commit what the rest of this turn changes before a frame is drawn, rather than a frame later.\n *\n * Angular's `animate.enter` adds its class from a queue that runs after the render pass, so the\n * element has been committed once without it. Committed again in the same turn, the class is on\n * the view's first frame, and the engine starts the view there instead of easing to it.\n */\n private settleUnseen(before: number): void {\n if (this.unseenSince !== null) return;\n this.unseenSince = before;\n queueMicrotask(() => {\n const since = this.unseenSince!;\n this.unseenSince = null;\n if (!this.engine.pending) return;\n this.engine.commitUnseen(since);\n if (this.engine.animating) this.schedule();\n });\n }\n\n begin(): void {\n this.rendering = true;\n this.renderStarted = globalThis.performance?.now?.() ?? Date.now();\n }\n\n /** The single commit point: at most one commit per change-detection pass. */\n end(): void {\n this.rendering = false;\n const before = this.engine.stats.commits;\n if (this.engine.commit()) this.settleUnseen(before);\n\n // A commit is what starts a transition, because it is where the cascade is recomputed.\n if (this.engine.animating) this.schedule();\n\n // Excludes the mount, which is not representative of a steady-state frame.\n const elapsed = (globalThis.performance?.now?.() ?? Date.now()) - this.renderStarted;\n const stats = this.engine.stats;\n if (stats.commits > 1 && elapsed > stats.worstRenderMs) stats.worstRenderMs = elapsed;\n }\n}\n\nexport interface MountResult {\n componentRef: ComponentRef<unknown>;\n applicationRef: ApplicationRef;\n factory: NativeRendererFactory;\n engine: Engine;\n}\n\n/**\n * Angular decides whether `animate.enter` and `animate.leave` do anything when `@angular/core` is\n * first evaluated, by reading a global that a Metro polyfill has to have set by then. Nothing\n * later can change the answer, so the most that can be done is to notice and say so. Checked here\n * because booting is the one moment every app passes through.\n */\nfunction warnIfAnimationsAreOff(): void {\n const document = (globalThis as { document?: { documentElement?: { getAnimations?: unknown } } })\n .document;\n if (typeof document?.documentElement?.getAnimations === 'function') return;\n console.error(\n '[angular-native] `animate.enter` and `animate.leave` will do nothing: Angular reads ' +\n 'whether to support them when it is first imported, before anything here runs. Build ' +\n 'metro.config.js with `withAngularNative` from `@ng-native/metro/config.cjs`, which ' +\n 'adds the polyfill that sets it. Animated styles and CSS transitions work either way.',\n );\n}\n\ndeclare const __DEV__: boolean | undefined;\n\n/**\n * The reload the HMR block falls back to when a change is more than a template.\n *\n * Each compiled component module can patch its own live class when only the template moved. For\n * anything else - a new method, a changed selector, different imports - there is no metadata to\n * replace, so it calls `globalThis.__angularNativeReload` instead. React Native's own Fast Refresh\n * cannot cover for it: that is React-specific, and it accepts the update and reports success, so\n * Metro never falls back on its own.\n *\n * This is installed here because `mount` is the one call every app makes. It used to be a line in\n * an example app's entry file, which meant every other app logged \"hmr reload\", called an empty\n * function, and carried on running the code from before the edit - with a second copy of every\n * class in the changed file now loaded, which Angular reports as `NG0912`. An edit that ships and\n * does nothing is a bad enough failure; one that also makes the next few screenshots lie about\n * what the app is running is worse.\n *\n * An app that sets its own is left alone: it will have a better reason string than this one.\n */\nfunction installReloadHook(): void {\n reloadMetroThroughExpo();\n const scope = globalThis as { __angularNativeReload?: () => void };\n if (scope.__angularNativeReload) return;\n scope.__angularNativeReload = () => {\n /*\n * Expo's reload first, React Native's only as a fallback.\n *\n * `DevSettings.reload()` under Expo Go re-runs the bundle the app downloaded when it launched\n * rather than fetching the current one, so the app comes back holding the code from before\n * the edit - forever one generation behind, however long you wait. That is worse than not\n * reloading, because it looks like it worked.\n *\n * Required rather than imported, both of them: React Native ships Flow, which Node cannot\n * parse, and this file has to stay importable by the test suite. Expo is genuinely optional.\n */\n try {\n const expo = require('expo') as { reloadAppAsync?: (reason?: string) => Promise<void> };\n if (expo.reloadAppAsync) {\n void expo.reloadAppAsync('angular-native: more than a template changed');\n return;\n }\n } catch {\n // Not an Expo app. React Native's own reload does re-fetch outside Expo Go.\n }\n const devSettings = (\n require('react-native') as { DevSettings?: { reload(reason?: string): void } }\n ).DevSettings;\n devSettings?.reload('angular-native: more than a template changed');\n };\n}\n\n/**\n * Metro's own reload, for an edit nothing accepted: a route file, a service, or a component the\n * hook above has already asked to reload. Metro calls React Native's Fast Refresh runtime, which\n * calls `DevSettings.reload()`, and in Expo Go that brings the app back without Expo's native\n * modules (`Cannot find native module 'ExpoFontLoader'`) until Expo Go is relaunched. Expo's\n * reload works in Expo Go and a development build alike, so in an Expo app Metro's goes through\n * it too.\n */\nconst THROUGH_EXPO = Symbol.for('ng-native.reloadThroughExpo');\n\nfunction reloadMetroThroughExpo(): void {\n const scope = globalThis as { __METRO_GLOBAL_PREFIX__?: string } & Record<string, unknown>;\n const refresh = scope[`${scope.__METRO_GLOBAL_PREFIX__ ?? ''}__ReactRefresh`] as\n { performFullRefresh?: ((reason: string) => void) & { [THROUGH_EXPO]?: true } } | undefined;\n const reactNative = refresh?.performFullRefresh;\n if (!refresh || !reactNative || reactNative[THROUGH_EXPO]) return;\n try {\n const { reloadAppAsync } = require('expo') as {\n reloadAppAsync?: (reason?: string) => Promise<void>;\n };\n if (!reloadAppAsync) return;\n // A reload Expo could not do is still a reload the edit needs: React Native's, then.\n const throughExpo = (reason: string) =>\n void reloadAppAsync(reason).catch((error: unknown) => {\n console.error(\n \"[angular-native] Expo's reload failed; reloading through React Native.\",\n error,\n );\n reactNative.call(refresh, reason);\n });\n throughExpo[THROUGH_EXPO] = true as const;\n refresh.performFullRefresh = throughExpo;\n } catch {\n // Not an Expo app: React Native's own reload re-fetches the bundle there.\n }\n}\n\n/** Dev only, and required rather than imported: React Native ships Flow, which Node cannot parse. */\nfunction calmDevBanner(): void {\n try {\n const { default: banner } = require('react-native/Libraries/Utilities/DevLoadingView') as {\n default?: LoadingBanner;\n };\n if (banner) calmLoadingBanner(banner);\n } catch {\n // No React Native under us: a test, or the web.\n }\n}\n\n/**\n * React Native's `NativeAnimatedHelper`, for the engine to move sticky headers by a scroll on the\n * native side. Required rather than imported for the same reason as the banner, and null where\n * there is no native animated module to talk to: a test, or the web.\n */\nfunction nativeAnimated(): NativeAnimated | null {\n try {\n const { default: helper } =\n require('react-native/src/private/animated/NativeAnimatedHelper') as {\n default?: NativeAnimated & { assertNativeAnimatedModule(): void };\n };\n if (!helper) return null;\n helper.assertNativeAnimatedModule();\n return helper;\n } catch {\n return null;\n }\n}\n\n/** The root component's host until its `:host` says otherwise. See `Engine.setDefaultStyle`. */\nconst ROOT_HOST_STYLE = { height: '100%' } as const;\n\n/**\n * Run the app's initializers, `provideAppInitializer` and `APP_INITIALIZER`, before the root\n * component exists, as `bootstrapApplication` does. `createEnvironmentInjector` runs only\n * environment initializers, so without this an app initializer silently never ran.\n *\n * Through Angular's own `ApplicationInitStatus`, so its `done` and `donePromise` stay true to what\n * happened for anything that waits on them. `runInitializers` is what Angular's bootstrap calls;\n * it is missing from the public types, which is why it is reached through a cast.\n *\n * An initializer that returns a promise is started, not awaited: `mount` is synchronous and the\n * first frame does not wait. One that fails reaches the `ErrorHandler` rather than vanishing.\n */\nfunction runInitializers(injector: EnvironmentInjector): void {\n const status = injector.get(ApplicationInitStatus);\n (status as unknown as { runInitializers(): void }).runInitializers();\n status.donePromise.catch((error: unknown) => injector.get(ErrorHandler).handleError(error));\n}\n\nexport function mount(\n rootTag: number,\n component: Type<unknown>,\n fabric: FabricUIManager,\n options: EngineOptions & {\n providers?: (Provider | EnvironmentProviders)[];\n /**\n * Root component inputs, set before its first change detection. That is the only moment a\n * `required` input can be given, and `mount` runs that first pass itself, so a caller cannot\n * set one afterwards. What `render()` in `@ng-native/testing` passes a component's inputs as.\n */\n inputs?: Record<string, unknown>;\n /**\n * Bindings for the root component, as `createComponent` takes them: `outputBinding()` for a\n * listener a template would bind. What `render()` passes its `on` as.\n */\n bindings?: Binding[];\n } = {},\n): MountResult {\n // The bare identifier, behind `typeof` so Node does not throw: Metro inlines `__DEV__` and folds\n // this branch away in a release build, and a property read through `globalThis` it cannot, which\n // left the reload hook and its `require('expo')` in every release bundle.\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n warnIfAnimationsAreOff();\n installReloadHook();\n calmDevBanner();\n }\n installDeferTriggers();\n const { providers: extraProviders = [], inputs = {}, bindings, ...engineOptions } = options;\n // The factory needs the engine and the engine needs the factory's dirty hook, so the hook is\n // handed over once both exist rather than through the constructor.\n const engine = new Engine(fabric, rootTag, {\n ...engineOptions,\n nativeAnimated:\n engineOptions.nativeAnimated === undefined ? nativeAnimated() : engineOptions.nativeAnimated,\n });\n installDateParse(engine.dev);\n const factory = new NativeRendererFactory(engine);\n engine.setOnDirty(factory.commitSoon);\n // `getElementById` is what `TransferState` calls, and `TransferState` is what `resource()`\n // reaches for the moment one is created. Without it every resource in an app throws\n // `doc.getElementById is not a function` before its loader has run - which is a long way from\n // anything a stylesheet does, and is why the stub is not as thin as it looks.\n const documentStub = { head: undefined, body: undefined, getElementById: () => null };\n\n // Parent the app injector to the platform injector, exactly as `internalCreateApplication`\n // does. Some Angular services are `providedIn: 'platform'` - `Console` among them - and with a\n // null parent they simply do not exist: the router fails with NG0201 the moment it logs.\n const platformInjector = createOrReusePlatformInjector();\n\n const injector = createEnvironmentInjector(\n [\n // `INJECTOR_SCOPE` and `DOCUMENT` are both load-bearing: without the first Angular cannot\n // resolve `ChangeDetectionSchedulerImpl` (NG0201), without the second `getStyleHost` throws\n // NG0210.\n { provide: INJECTOR_SCOPE, useValue: 'root' },\n provideZonelessChangeDetectionInternal(),\n { provide: RendererFactory2, useValue: factory },\n // Exposed so a component can read commit stats, or reach a node for a native command.\n { provide: Engine, useValue: engine },\n // The contract the shared packages inject. `Engine` is still provided under its own token\n // for the three worklet components that need Fabric's own handles. See `fabric/host.ts`.\n { provide: HostEngine, useExisting: Engine },\n { provide: DOCUMENT, useValue: documentStub },\n // 'native', not Angular's default 'unknown': see `platform-id.ts`.\n { provide: PLATFORM_ID, useValue: PLATFORM_NATIVE_ID },\n { provide: ErrorHandler, useClass: ErrorHandler },\n ...extraProviders,\n ],\n // The platform injector is an EnvironmentInjector in practice; the factory's return type is\n // just declared more loosely.\n platformInjector as EnvironmentInjector,\n );\n\n // Errors the engine catches in its native event dispatch, which is outside every Angular\n // listener wrapper: responder handlers, engine-level listeners, a commit a focus change starts.\n // Looked up when one happens rather than now, as Angular's own handler is, so an app's\n // `ErrorHandler` that injects something not yet constructible is not forced at boot. A caller\n // that passed its own `onError` keeps it.\n if (!engineOptions.onError) {\n engine.setOnError((error) => injector.get(ErrorHandler).handleError(error));\n }\n\n runInitializers(injector);\n\n // What `@ng-native/tailwind`'s `ios:` and `android:` variants match beneath. On the root so\n // they work with nothing to set up; an app that had to add it itself, and did not, got platform\n // variants that silently matched nothing.\n engine.addClass(engine.root, `platform-${nativePlatform()}`);\n\n // No `hostElement`, so Angular creates the host from the selector as it does any other\n // component's, and it goes under the engine root as a view of its own. The engine root is the\n // surface and is never committed: as the host it took the component's `:host` rules and sent\n // them nowhere, so a root component's background and padding were dropped without a word.\n const componentRef = createComponent(component, {\n environmentInjector: injector,\n ...(bindings && { bindings }),\n });\n const host = componentRef.location.nativeElement as EngineNode;\n // The full height of the surface, as the web's mount point is given, so a template's `flex: 1`\n // still fills the screen. A height rather than `flex: 1`, which a `:host` height would lose to.\n // The app's own `:host` overrides it.\n engine.setDefaultStyle(host, ROOT_HOST_STYLE);\n engine.appendChild(engine.root, host);\n\n for (const [name, value] of Object.entries(inputs)) componentRef.setInput(name, value);\n\n const applicationRef = injector.get(ApplicationRef);\n\n // `ApplicationRef.bootstrap()` does all of this; `createComponent` does not, and we\n // deliberately do not use `bootstrap()` because it wants a DOM selector. Order and\n // bookkeeping both matter, so this mirrors `_loadComponent` step for step.\n applicationRef.componentTypes.push(component);\n applicationRef.attachView(componentRef.hostView);\n // Before the listeners, so the root component's template has run and any outlet in it has\n // registered itself by the time the router's initial navigation activates a route.\n applicationRef.tick();\n // Load-bearing, not bookkeeping: the router's bootstrap listener returns early unless the\n // ref it is handed is `ApplicationRef.components[0]`, so with an empty array the initial\n // navigation never runs and a routed app renders nothing but its outlet's host.\n applicationRef.components.push(componentRef);\n // Text laid out before its face registered is laid out again when it does: `loadFonts` is not\n // awaited before `mount` behind a splash screen.\n const stopFonts = onFontsRegistered((families) => engine.fontsRegistered(families));\n const stopSettled = onFontsSettled((families) => engine.fontsSettled(families));\n componentRef.onDestroy(() => {\n stopFonts();\n stopSettled();\n applicationRef.detachView(componentRef.hostView);\n const at = applicationRef.components.indexOf(componentRef);\n if (at !== -1) applicationRef.components.splice(at, 1);\n });\n\n for (const listener of injector.get(APP_BOOTSTRAP_LISTENER, [])) {\n listener(componentRef);\n }\n\n return { componentRef, applicationRef, factory, engine };\n}\n"]}
|
package/dist/http.d.ts
CHANGED
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
* });
|
|
8
8
|
* ```
|
|
9
9
|
*
|
|
10
|
-
* Use this instead of `provideHttpClient()`, which
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* Use this instead of `provideHttpClient()`, which can fail silently. Angular's default backend
|
|
11
|
+
* is `fetch`, and it reads a response body only through `response.body`'s stream. Expo's `fetch`
|
|
12
|
+
* streams one, but Metro runs Expo's runtime only when the bundle imports `expo`: a debug build
|
|
13
|
+
* does through `mount()`'s reload hook, and a release build only if the app's `main.ts` does.
|
|
14
|
+
* Without it, or with `EXPO_PUBLIC_USE_RN_FETCH` set, the global `fetch` is React Native's,
|
|
15
|
+
* `whatwg-fetch` over XHR, whose `Response` has no `body`, so every request resolves with `null`
|
|
16
|
+
* and nothing reports why. RN's `XMLHttpRequest` is native and complete, upload progress included,
|
|
17
|
+
* and the same in every build, so the XHR backend is the one to use.
|
|
15
18
|
*
|
|
16
19
|
* A separate entry point so an app that never makes a request does not need `@angular/common`.
|
|
17
20
|
*/
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAqBA,OAAO,EACL,iBAAiB,EACjB,OAAO,GAGR,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,uBAAuB,CACrC,GAAG,QAAwC;IAE3C,OAAO,iBAAiB,CAAC,OAAO,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC;AACnD,CAAC","sourcesContent":["/**\n * `HttpClient`, configured for React Native.\n *\n * ```ts\n * mount(rootTag, App, getFabricUIManager(), {\n * providers: [provideNativeHttpClient(withInterceptors([auth]))],\n * });\n * ```\n *\n * Use this instead of `provideHttpClient()`, which can fail silently. Angular's default backend\n * is `fetch`, and it reads a response body only through `response.body`'s stream. Expo's `fetch`\n * streams one, but Metro runs Expo's runtime only when the bundle imports `expo`: a debug build\n * does through `mount()`'s reload hook, and a release build only if the app's `main.ts` does.\n * Without it, or with `EXPO_PUBLIC_USE_RN_FETCH` set, the global `fetch` is React Native's,\n * `whatwg-fetch` over XHR, whose `Response` has no `body`, so every request resolves with `null`\n * and nothing reports why. RN's `XMLHttpRequest` is native and complete, upload progress included,\n * and the same in every build, so the XHR backend is the one to use.\n *\n * A separate entry point so an app that never makes a request does not need `@angular/common`.\n */\nimport type { EnvironmentProviders } from '@angular/core';\nimport {\n provideHttpClient,\n withXhr,\n type HttpFeature,\n type HttpFeatureKind,\n} from '@angular/common/http';\n\nexport function provideNativeHttpClient(\n ...features: HttpFeature<HttpFeatureKind>[]\n): EnvironmentProviders {\n return provideHttpClient(withXhr(), ...features);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-native/platform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Angular Native's Renderer2 and bootstrap: mounts an Angular application onto React Native's Fabric.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@ng-native/fabric": "0.
|
|
33
|
+
"@ng-native/fabric": "0.4.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@angular/core": "^22.0.0",
|