@blotch/angular-lynx 22.2.1 → 22.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +3 -1
  2. package/fesm2022/blotch-angular-lynx-web-glass-8MFrhPz0.mjs +951 -0
  3. package/fesm2022/blotch-angular-lynx-web-glass-8MFrhPz0.mjs.map +1 -0
  4. package/fesm2022/blotch-angular-lynx.mjs +8084 -0
  5. package/fesm2022/blotch-angular-lynx.mjs.map +1 -0
  6. package/package.json +11 -6
  7. package/schematics/add-i18n/index.js +168 -0
  8. package/schematics/add-i18n/schema.js +2 -0
  9. package/schematics/add-tailwind/index.js +100 -0
  10. package/schematics/add-tailwind/schema.js +2 -0
  11. package/schematics/add-testing/index.js +80 -0
  12. package/schematics/add-testing/schema.js +2 -0
  13. package/schematics/collection.json +7 -2
  14. package/schematics/component/index.js +110 -0
  15. package/schematics/component/schema.js +2 -0
  16. package/schematics/component/schema.json +102 -25
  17. package/schematics/eject/index.js +87 -0
  18. package/schematics/eject/schema.js +2 -0
  19. package/schematics/eject/schema.json +24 -0
  20. package/schematics/files/src/rspeedy-env.d.ts.template +1 -1
  21. package/schematics/migrations/accessibility-traits/index.js +56 -0
  22. package/schematics/migrations/dev-logs-gitignore/index.js +9 -0
  23. package/schematics/migrations/extract-i18n-target/index.js +31 -0
  24. package/schematics/migrations/tailwind-html-templates/index.js +44 -0
  25. package/schematics/migrations.json +25 -0
  26. package/schematics/ng-add/index.js +480 -0
  27. package/schematics/ng-add/schema.js +2 -0
  28. package/schematics/ng-add/schema.json +6 -2
  29. package/schematics/ng-add/versions.js +57 -0
  30. package/schematics/package.json +3 -0
  31. package/schematics/utility/dev-logs-gitignore.js +25 -0
  32. package/schematics/utility/extract-i18n-target.js +58 -0
  33. package/types/blotch-angular-lynx.d.ts +4789 -0
  34. package/schematics/files/lynx.config.ts.template +0 -17
@@ -0,0 +1,4789 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ApplicationConfig, ApplicationRef, ComponentRef, EmbeddedViewRef, EnvironmentInjector, EnvironmentProviders, ErrorDetails, ErrorHandler, Injector, OnChanges, OnDestroy, SimpleChanges, TemplateRef, Type, ViewContainerRef, signal } from "@angular/core";
3
+ import { Animation, AnimationOptions, Element as Element$1 } from "@lynx-js/types/main-thread";
4
+ import { AnyObject } from "@lynx-js/types/common";
5
+ import { ControlValueAccessor } from "@angular/forms";
6
+ import { BaseAnimationEvent, BaseKeyEvent, BaseMouseEvent, BaseTouchEvent, BaseTransitionEvent, BaseWheelEvent, LayoutChangeDetailEvent, UIAppearanceDetailEvent } from "@lynx-js/types/events";
7
+ import { MouseEvent, PlatformType, ResourcePrefetchData, ResourcePrefetchResult, TextInfo, TextMetrics, TouchEvent } from "@lynx-js/types";
8
+ import { LocationChangeListener, LocationStrategy, PlatformLocation } from "@angular/common";
9
+ import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy, RouterFeatures, Routes } from "@angular/router";
10
+ import { Subject } from "rxjs";
11
+ /**
12
+ * Programmatic accessibility control for screen readers on Lynx.
13
+ *
14
+ * Provides two imperative APIs that complement the declarative accessibility
15
+ * attributes (`accessibility-element`, `accessibility-label`, etc.) already
16
+ * available on Lynx element directives.
17
+ *
18
+ * @usageNotes
19
+ * ```typescript
20
+ * const a11y = inject(LynxAccessibility);
21
+ *
22
+ * // Announce a state change to screen readers
23
+ * await a11y.announce('Item added to cart');
24
+ *
25
+ * // Move accessibility focus to a specific element
26
+ * await a11y.requestFocus('#confirmation-message');
27
+ * ```
28
+ */
29
+ export declare class LynxAccessibility {
30
+ /**
31
+ * Makes screen readers announce the specified text content.
32
+ *
33
+ * Use this to notify visually impaired users of state changes or
34
+ * operation results that aren't reflected by focus movement alone
35
+ * (e.g. toast messages, background task completion, live counters).
36
+ *
37
+ * Wraps `lynx.accessibilityAnnounce()`. Only the background thread's `lynx`
38
+ * has it, and event handlers run on the main thread, so the call goes
39
+ * through the background thread (see background-call.ts).
40
+ */
41
+ announce(content: string): Promise<void>;
42
+ /**
43
+ * Programmatically moves accessibility focus (screen reader cursor)
44
+ * to the element matching the given selector.
45
+ *
46
+ * The target element should have `accessibility-element="true"` set.
47
+ * Only ID selectors are reliably supported (e.g. `'#myElement'`).
48
+ *
49
+ * Wraps `lynx.createSelectorQuery().select(selector).invoke({ method: 'requestAccessibilityFocus' }).exec()`.
50
+ * The main thread's `lynx` has no createSelectorQuery, but it's where event
51
+ * handlers run and where the native elements live, so there the element is
52
+ * found and called directly.
53
+ */
54
+ requestFocus(selector: string): Promise<void>;
55
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxAccessibility, never>;
56
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
57
+ }
58
+ /**
59
+ * Phantom brand symbol — makes each ElementRef variant nominally distinct at
60
+ * the type level even though Lynx PAPI handles have no runtime structure.
61
+ */
62
+ declare const __brand: unique symbol;
63
+ /**
64
+ * Generic opaque handle returned by every __Create* PAPI function.
65
+ * The Tag parameter narrows the type to a specific native element kind,
66
+ * preventing accidental cross-element assignments (e.g. ListElementRef ≠ ViewElementRef).
67
+ */
68
+ type ElementRef<Tag extends string = string> = {
69
+ readonly [__brand]?: Tag;
70
+ };
71
+ /**
72
+ * ComponentElementRef accepts both 'component' and 'page' so that
73
+ * PageElementRef (which is ElementRef<'page'>) remains assignable to it,
74
+ * preserving the original hierarchy: Page ⊆ Component ⊆ ElementRef.
75
+ */
76
+ type ComponentElementRef = ElementRef<'component' | 'page'>;
77
+ type PageElementRef = ElementRef<'page'>;
78
+ type ListElementRef = ElementRef<'list'>;
79
+ type ViewElementRef = ElementRef<'view'>;
80
+ type TextElementRef = ElementRef<'text'>;
81
+ type RawTextElementRef = ElementRef<'raw-text'>;
82
+ type ImageElementRef = ElementRef<'image'>;
83
+ type ScrollElementRef = ElementRef<'scroll'>;
84
+ type WrapperElementRef = ElementRef<'wrapper'>;
85
+ type NoneElementRef = ElementRef<'none'>;
86
+ type IfElementRef = ElementRef<'if'>;
87
+ type ForElementRef = ElementRef<'for'>;
88
+ type BlockElementRef = ElementRef<'block'>;
89
+ type FrameElementRef = ElementRef<'frame'>;
90
+ /**
91
+ * AnyObject = Record<string, any>, sourced from @lynx-js/types rather than
92
+ * duplicating the definition locally.
93
+ */
94
+ type ElementInfo = AnyObject;
95
+ type SelectorParams = {
96
+ onlyCurrentComponent?: boolean;
97
+ };
98
+ type DynamicComponentResult = {
99
+ code: number;
100
+ data: {
101
+ evalResult: (url: string) => {
102
+ name: string;
103
+ };
104
+ };
105
+ };
106
+ /**
107
+ * Global PAPI declarations — these __* functions are injected by the Lynx
108
+ * native engine and are not part of @lynx-js/types (which covers the
109
+ * high-level JS API layer only).
110
+ */
111
+ declare global {
112
+ function __CreatePage(componentId: string, cssId: number, info?: ElementInfo): PageElementRef;
113
+ function __CreateComponent(parentComponentUniId: number, componentId: string, cssId: number, entryName: string, name: string, path: string, config?: Record<string, unknown>): ComponentElementRef;
114
+ function __CreateView(parentComponentUniId: number, info?: ElementInfo): ViewElementRef;
115
+ function __CreateScrollView(parentComponentUniId: number, info?: ElementInfo): ScrollElementRef;
116
+ function __CreateText(parentComponentUniId: number, info?: ElementInfo): TextElementRef;
117
+ function __CreateRawText(text: string, info?: ElementInfo): RawTextElementRef;
118
+ function __CreateImage(parentComponentUniId: number, info?: ElementInfo): ImageElementRef;
119
+ function __CreateWrapperElement(parentComponentUniId: number): WrapperElementRef;
120
+ function __CreateNonElement(parentComponentUniId: number): ElementRef;
121
+ function __CreateIf(parentComponentUniId: number, info?: ElementInfo): IfElementRef;
122
+ function __CreateFor(parentComponentUniId: number, info?: ElementInfo): ForElementRef;
123
+ function __CreateBlock(parentComponentUniId: number, info?: ElementInfo): BlockElementRef;
124
+ function __CreateList(parentComponentUniId: number, componentAtIndex: (listRef: ListElementRef, listId: number, cellIndex: number, opId: number) => number | undefined, enqueueComponent: (listRef: ListElementRef, listId: number, eleId: number) => void, info?: ElementInfo, componentAtIndexes?: (listRef: ListElementRef, listId: number, cellIndexes: number[], opIds: number[], enableReuseNotification: boolean, asyncFlush: boolean) => void): ListElementRef;
125
+ function __UpdateListCallbacks(node: ListElementRef, componentAtIndex: (listRef: ListElementRef, listId: number, cellIndex: number, opId: number) => number | undefined, enqueueComponent: (listRef: ListElementRef, listId: number, eleId: number) => void, componentAtIndexes?: (listRef: ListElementRef, listId: number, cellIndexes: number[], opIds: number[], enableReuseNotification: boolean, asyncFlush: boolean) => void | null): void;
126
+ function __CreateFrame(parentComponentUniId: number, info?: ElementInfo): FrameElementRef;
127
+ function __CreateElement(tag: string, comParentUniID: number, info?: ElementInfo): ElementRef;
128
+ function __AppendElement(parent: ElementRef, current: ElementRef): ElementRef;
129
+ function __RemoveElement(parent: ElementRef, current: ElementRef): ElementRef;
130
+ function __InsertElementBefore(parent: ElementRef, current: ElementRef, marker: ElementRef): ElementRef;
131
+ function __SwapElement(a: ElementRef, b: ElementRef): void;
132
+ function __ReplaceElement(a: ElementRef, b: ElementRef): void;
133
+ function __ReplaceElements(parent: ElementRef, a: ElementRef | ElementRef[] | undefined, b: ElementRef | ElementRef[] | undefined): void;
134
+ function __GetParent(current: ElementRef): ElementRef | null;
135
+ function __GetChildren(current: ElementRef): ElementRef[];
136
+ function __FirstElement(current: ElementRef): ElementRef;
137
+ function __LastElement(current: ElementRef): ElementRef;
138
+ function __NextElement(node: ElementRef): ElementRef;
139
+ function __GetTag(node: ElementRef): string;
140
+ function __SetAttribute(current: ElementRef, attrName: string, value: any): void;
141
+ function __AddClass(current: ElementRef, className: string): void;
142
+ function __SetClasses(current: ElementRef, className: string | undefined): void;
143
+ function __GetClasses(current: ElementRef): string[];
144
+ function __SetStaticStyle(node: ElementRef, key: number, value: unknown): void;
145
+ function __SetInlineStyles(node: ElementRef, value: unknown): void;
146
+ function __GetInlineStyle(node: ElementRef, propertyId: number): string;
147
+ function __GetInlineStyles(node: ElementRef): string;
148
+ function __SetID(node: ElementRef, id: string | undefined): void;
149
+ function __GetID(node: ElementRef): string;
150
+ function __SetCSSId(node: ElementRef, cssId: number, entryName?: string): void;
151
+ function __AddEvent(node: ElementRef, type: string, name: string, func: string | Record<string, unknown> | undefined): void;
152
+ function __SetEvents(node: ElementRef, events: Record<string, unknown>[] | undefined): void;
153
+ function __GetEvent(node: ElementRef, name: string, type: string): Record<string, any>;
154
+ function __GetEvents(node: ElementRef): Record<string, any>[];
155
+ function __AddDataset(node: ElementRef, key: string, value: unknown): void;
156
+ function __SetDataset(node: ElementRef, value: Record<string, unknown> | undefined): void;
157
+ function __GetDataset(node: ElementRef): Record<string, unknown>;
158
+ function __GetDataByKey(node: ElementRef, key: string): any;
159
+ function __GetElementUniqueID(node: ElementRef): number;
160
+ function __ElementIsEqual(left: ElementRef, right: ElementRef): boolean;
161
+ function __UpdateComponentID(node: ElementRef, id: string): void;
162
+ function __GetComponentID(node: ElementRef): string;
163
+ function __UpdateComponentInfo(node: ElementRef, params: {
164
+ componentID?: string;
165
+ name?: string;
166
+ path?: string;
167
+ entry?: string;
168
+ cssID?: number;
169
+ }): void;
170
+ function __FlushElementTree(element?: ElementRef, options?: {
171
+ triggerLayout?: boolean;
172
+ triggerDataUpdated?: boolean;
173
+ operationID?: number;
174
+ operationIDs?: number[];
175
+ nativeUpdateDataOrder?: number;
176
+ __lynx_timing_flag?: string;
177
+ elementID?: number;
178
+ elementIDs?: number[];
179
+ reloadTemplate?: boolean;
180
+ listID?: number;
181
+ pipelineOptions?: Record<string, any>;
182
+ /**
183
+ * Delegate async scheduling to the native engine (used in componentAtIndexes batch path).
184
+ */
185
+ asyncFlush?: boolean;
186
+ }): void;
187
+ function __AsyncResolveElement(element: ElementRef): void;
188
+ function __OnLifecycleEvent(args: any[]): void;
189
+ function _ReportError(err: Error, info: {
190
+ errorCode: number;
191
+ }): void;
192
+ function __ElementFromBinary(elementTemplateKey: string, parentComponentUniId: number): ElementRef[];
193
+ function __GetTemplateParts(ele: ElementRef): Record<string, ElementRef>;
194
+ function __CloneElement(ele: ElementRef, options: Record<string, any>): ElementRef;
195
+ function __IsTemplateElement(ele: ElementRef): boolean;
196
+ function __MarkTemplateElement(ele: ElementRef): void;
197
+ function __MarkPartElement(ele: ElementRef, key: string): void;
198
+ function __QuerySelector(root: ElementRef, cssSelector: string, params: SelectorParams): ElementRef;
199
+ function __QuerySelectorAll(root: ElementRef, cssSelector: string, params: SelectorParams): ElementRef[];
200
+ function __AddConfig(ele: ElementRef, key: string, value: any): void;
201
+ function __SetConfig(ele: ElementRef, config: Record<string, any>): void;
202
+ function __GetElementConfig(ele: ElementRef): Record<string, unknown>;
203
+ function __QueryComponent(source: string, callback: (evalResult: DynamicComponentResult) => void): {
204
+ evalResult: unknown;
205
+ };
206
+ function __AddInlineStyle(e: ElementRef, key: number | string, value: unknown): void;
207
+ function __ElementAnimate(element: ElementRef, args: [operation: 0, name: string, keyframes: Record<string, string | number>[], options?: LynxAnimationOptions] | [operation: 1 | 2 | 3, name: string]): void;
208
+ function __GetAttributeByName(e: ElementRef, name: string): any;
209
+ function __GetAttributeNames(e: ElementRef): string[];
210
+ function __GetAttributes(e: ElementRef): Record<string, any>;
211
+ function __GetComputedStyleByKey(e: ElementRef, key: string): string;
212
+ function __GetPageElement(): ElementRef;
213
+ function __InvokeUIMethod(e: ElementRef, method: string, params: Record<string, unknown>, callback: (res: {
214
+ code: number;
215
+ data: unknown;
216
+ }) => void): ElementRef[];
217
+ function __LoadLepusChunk(name: string, cfg: {
218
+ chunkType: number;
219
+ }): void;
220
+ function __CreateGestureDetector(node: ElementRef, gestureID: number, gestureType: number, config: {
221
+ callbacks: Array<{
222
+ name: string;
223
+ callback: unknown;
224
+ }>;
225
+ config?: Record<string, unknown>;
226
+ }, relationMap: Record<string, number[]>): void;
227
+ function __SetGestureDetector(node: ElementRef, gestureID: number, gestureType: number, config: {
228
+ callbacks: Array<{
229
+ name: string;
230
+ callback: unknown;
231
+ }>;
232
+ config?: Record<string, unknown>;
233
+ }, relationMap: Record<string, number[]>): void;
234
+ function __RemoveGestureDetector(node: ElementRef, gestureID: number): void;
235
+ function __SetGestureState(node: ElementRef, gestureID: number, state: number): void;
236
+ function __ConsumeGesture(node: ElementRef, gestureID: number, options: Record<string, boolean>): void;
237
+ function __GeneratePipelineOptions(): Record<string, any>;
238
+ function __OnPipelineStart(pipeLineId: string, pipeLineOrigin: string): void;
239
+ function __BindPipelineIDWithTimingFlag(pipeLineId: string, timingFlag: string): void;
240
+ function __MarkTiming(pipeLineId: string, timingFlag: string): void;
241
+ function __AddTimingListener(): void;
242
+ function __SetLepusInitData(initData: Record<string, unknown>): void;
243
+ function __GetElementByUniqueID(elementId: number): ElementRef | undefined;
244
+ function __UpdateIfNodeIndex(node: IfElementRef, ifIndex: number): void;
245
+ function __UpdateForChildCount(node: ForElementRef, childCount: number): void;
246
+ }
247
+ /**
248
+ * Extends the official AnimationOptions with Lynx-native property aliases
249
+ * and relaxed types that accept string values (e.g. "300ms").
250
+ */
251
+ type LynxAnimationOptions = AnimationOptions & {
252
+ iterationCount?: number | string;
253
+ fillMode?: string;
254
+ timingFunction?: string;
255
+ };
256
+ /**
257
+ * The public API of an animation, which `BaseLynxElement.animate()` returns.
258
+ * LynxAnimation uses ES private fields (#element, #count), which brand the
259
+ * class, so a structural type lets other implementations, such as a test
260
+ * double, satisfy it.
261
+ */
262
+ type BaseLynxAnimation = Pick<Animation, 'id' | 'cancel' | 'pause' | 'play'>;
263
+ /**
264
+ * Represents a running animation on a Lynx element.
265
+ * Created by calling `element.animate()` on a LynxElement.
266
+ * Mirrors the Animation class from React Lynx's worklet-runtime, except for
267
+ * the key a named animation is controlled by (see the constructor).
268
+ */
269
+ export declare class LynxAnimation implements Pick<Animation, 'id' | 'cancel' | 'pause' | 'play'> {
270
+ #private;
271
+ readonly id: string;
272
+ constructor(element: ElementRef, keyframes: Record<string, string | number>[], options: LynxAnimationOptions);
273
+ play(): void;
274
+ pause(): void;
275
+ cancel(): void;
276
+ }
277
+ /**
278
+ * Profiling counters collected by the renderer during a session.
279
+ * Only populated in development builds, where `__PROFILE__` is true — in
280
+ * production, instrumentation is dead-code-eliminated and all values stay 0.
281
+ */
282
+ type DevToolsStats = {
283
+ cdCycles: number;
284
+ elementCreated: number;
285
+ elementRemoved: number;
286
+ flushCount: number;
287
+ lastCdDurationMs: number;
288
+ };
289
+ /**
290
+ * Options for `LynxPerformance.profileStart()` and `profileMark()`. The same
291
+ * shape as Lynx's own `TraceOption`; `performance.ts` passes it to Lynx as
292
+ * one, so the compiler keeps the two in step.
293
+ */
294
+ type LynxTraceOptions = {
295
+ flowId?: number;
296
+ flowIds?: number[];
297
+ args?: Record<string, string>;
298
+ };
299
+ /**
300
+ * Wraps Lynx's native performance tracing APIs (`lynx.performance`).
301
+ *
302
+ * All methods are no-ops when `lynx.performance` is unavailable (e.g. in tests
303
+ * or non-Lynx environments) or when profiling is not actively recording.
304
+ *
305
+ * Unlike the `LynxDevTools` counters, the calls aren't gated by `__PROFILE__`,
306
+ * so they stay in production builds. A trace is worth recording from the build
307
+ * you ship, without development mode's extra work in it. They cost little
308
+ * there: release builds of the Lynx engine compile tracing out, so each call
309
+ * returns at once.
310
+ *
311
+ * @usageNotes
312
+ * ```typescript
313
+ * const perf = inject(LynxPerformance);
314
+ *
315
+ * perf.profileStart('MyComponent::render', { args: { itemCount: '42' } });
316
+ * // ... do work ...
317
+ * perf.profileEnd();
318
+ *
319
+ * perf.profileMark('dataLoaded', { args: { source: 'cache' } });
320
+ * ```
321
+ */
322
+ export declare class LynxPerformance {
323
+ #private;
324
+ /**
325
+ * Whether profiling is actively recording traces.
326
+ * Returns false when `lynx.performance` is unavailable.
327
+ */
328
+ isRecording(): boolean;
329
+ /**
330
+ * Begin a named trace. Must be paired with `profileEnd()`.
331
+ * Traces nest — multiple `profileStart` calls create a stack.
332
+ */
333
+ profileStart(name: string, options?: LynxTraceOptions): void;
334
+ /**
335
+ * End the current trace (top of the trace stack).
336
+ */
337
+ profileEnd(): void;
338
+ /**
339
+ * Emit a discrete mark event in the trace timeline.
340
+ */
341
+ profileMark(name: string, options?: LynxTraceOptions): void;
342
+ /**
343
+ * Generate a unique flow ID for correlating multi-threaded traces.
344
+ */
345
+ profileFlowId(): number;
346
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxPerformance, never>;
347
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
348
+ }
349
+ /**
350
+ * High-level DevTools service exposing performance stats as Angular signals.
351
+ *
352
+ * Stats are only meaningful in development builds, where the build plugin sets
353
+ * `__PROFILE__` to true. In production builds, counters are never incremented
354
+ * (the instrumentation code is dead-code-eliminated), so all values remain
355
+ * zero.
356
+ *
357
+ * @usageNotes
358
+ * ```typescript
359
+ * const devtools = inject(LynxDevTools);
360
+ *
361
+ * // Read stats reactively in a template
362
+ * <text>CD cycles: {{ devtools.stats().cdCycles }}</text>
363
+ *
364
+ * // Take a one-shot snapshot
365
+ * const snap = devtools.snapshot();
366
+ * console.log('Elements created:', snap.elementCreated);
367
+ *
368
+ * // Reset counters
369
+ * devtools.reset();
370
+ * ```
371
+ */
372
+ export declare class LynxDevTools {
373
+ #private;
374
+ /**
375
+ * Reactive stats snapshot. Re-reads from `devStats` each time
376
+ * `refresh()` is called, or automatically after `reset()`.
377
+ */
378
+ readonly stats: import("@angular/core").Signal<DevToolsStats>;
379
+ /**
380
+ * Take a non-reactive snapshot of current counters.
381
+ */
382
+ snapshot(): DevToolsStats;
383
+ /**
384
+ * Bump the signal so `stats()` re-evaluates with latest counter values.
385
+ */
386
+ refresh(): void;
387
+ /**
388
+ * Zero all counters and update the reactive signal.
389
+ */
390
+ reset(): void;
391
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxDevTools, never>;
392
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
393
+ }
394
+ /**
395
+ * Module-level counters for hot-path instrumentation.
396
+ * Plain object avoids DI/signal overhead on every element operation.
397
+ * Only incremented when __PROFILE__ is true (dead-code-eliminated otherwise).
398
+ */
399
+ declare const devStats: DevToolsStats & {
400
+ reset(): void;
401
+ };
402
+ /**
403
+ * Starts timing a change-detection cycle. The renderer factory calls it from
404
+ * `begin()`, and `endCdTiming()` from `end()`.
405
+ */
406
+ declare const startCdTiming: () => void;
407
+ /**
408
+ * Stops timing the innermost change-detection cycle in progress, and records
409
+ * its duration in `devStats.lastCdDurationMs`.
410
+ */
411
+ declare const endCdTiming: () => void;
412
+ /**
413
+ * Extend this interface to type the raw data passed from native before processing.
414
+ *
415
+ * @example
416
+ * // This export makes the file a module, so the block below adds to
417
+ * // @blotch/angular-lynx's types instead of replacing them.
418
+ * export {};
419
+ *
420
+ * declare module '@blotch/angular-lynx' {
421
+ * interface InitDataRaw { userId: string; }
422
+ * }
423
+ */
424
+ interface InitDataRaw extends Record<string, unknown> {}
425
+ /**
426
+ * Extend this interface to type the processed init data used throughout the app.
427
+ *
428
+ * @example
429
+ * // This export makes the file a module, so the block below adds to
430
+ * // @blotch/angular-lynx's types instead of replacing them.
431
+ * export {};
432
+ *
433
+ * declare module '@blotch/angular-lynx' {
434
+ * interface InitData { userId: string; }
435
+ * }
436
+ */
437
+ interface InitData extends Record<string, unknown> {}
438
+ /**
439
+ * Extend this interface to type the global data passed from the native host.
440
+ *
441
+ * @example
442
+ * // This export makes the file a module, so the block below adds to
443
+ * // @blotch/angular-lynx's types instead of replacing them.
444
+ * export {};
445
+ *
446
+ * declare module '@blotch/angular-lynx' {
447
+ * interface GlobalData { theme: 'light' | 'dark'; }
448
+ * }
449
+ */
450
+ interface GlobalData extends Record<string, unknown> {}
451
+ type DataProcessorDefinition = {
452
+ /**
453
+ * Transform raw native init data before it is stored in LynxInitData.
454
+ */
455
+ defaultDataProcessor?: (rawInitData: InitDataRaw) => InitData;
456
+ /**
457
+ * Named processors callable by the native side via processData(data, processorName).
458
+ */
459
+ dataProcessors?: Record<string, (...args: any[]) => any>;
460
+ };
461
+ /**
462
+ * Register data processor functions that the native Lynx runtime calls before
463
+ * delivering init data to the app. Maps to the global `processData` callback.
464
+ *
465
+ * Call this before bootstrapApplication. The engine runs the default processor
466
+ * on the InitData before passing it to renderPage, so its result is what
467
+ * LynxInitData starts with.
468
+ *
469
+ * @example
470
+ * registerDataProcessors({
471
+ * defaultDataProcessor: (raw) => ({ ...raw, theme: raw.theme ?? 'light' }),
472
+ * });
473
+ * bootstrapApplication(App, appConfig);
474
+ */
475
+ export declare const registerDataProcessors: (definition: DataProcessorDefinition) => void;
476
+ export declare class LynxGlobalData {
477
+ readonly globalData: import("@angular/core").WritableSignal<GlobalData>;
478
+ constructor();
479
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxGlobalData, never>;
480
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
481
+ }
482
+ export declare class LynxInitData {
483
+ readonly initData: import("@angular/core").WritableSignal<InitData>;
484
+ constructor();
485
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxInitData, never>;
486
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
487
+ }
488
+ /**
489
+ * Angular ErrorHandler that routes errors to the native Lynx error reporting API.
490
+ *
491
+ * Automatically provided by provideRenderer(). Also writes to __lynxLastError
492
+ * so components can surface errors as <text> elements (no console on device).
493
+ */
494
+ export declare class LynxErrorHandler implements ErrorHandler {
495
+ handleError(error: unknown): void;
496
+ /**
497
+ * Called by Angular for rendering errors caught by an `@boundary` block.
498
+ *
499
+ * Without this override Angular falls back to `handleError`, which reports a
500
+ * fatal LEPUS error — on device that raises the red error overlay even though
501
+ * the boundary already swapped in its `@error` fallback and the app is still
502
+ * usable. A caught error is recoverable by definition, so it goes to
503
+ * `lynx.reportError` at `warning` level instead: monitoring still sees it,
504
+ * but it isn't treated as a crash.
505
+ *
506
+ * Angular calls this synchronously mid-render, so it must not write to
507
+ * signals (NG0600) — it only touches a plain global and the native bridge.
508
+ */
509
+ onViewError(error: Error, _details: ErrorDetails): void;
510
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxErrorHandler, never>;
511
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
512
+ }
513
+ export declare class LynxExposure implements OnDestroy {
514
+ #private;
515
+ readonly visible: import("@angular/core").WritableSignal<boolean>;
516
+ constructor();
517
+ ngOnDestroy(): void;
518
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxExposure, never>;
519
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxExposure, "[lynxExposure]", ["lynxExposure"], {}, {}, never, never, true, never>;
520
+ }
521
+ /**
522
+ * Wire format for individual exposure/disexposure event entries.
523
+ * Dual-cased fields (kebab and camel) match the Lynx engine's output exactly.
524
+ */
525
+ type ExposureEventDetail = {
526
+ 'exposure-id': string;
527
+ 'exposure-scene': string;
528
+ exposureID: string;
529
+ exposureScene: string;
530
+ /**
531
+ * Identifies the native element. Lynx documents it as a string, which iOS
532
+ * and Android send; the web sends the element's numeric unique ID.
533
+ */
534
+ 'unique-id': string | number;
535
+ };
536
+ /**
537
+ * The Lynx engine batches element visibility changes at ~20fps and dispatches
538
+ * them as arrays via GlobalEventEmitter ('exposure' / 'disexposure' events).
539
+ */
540
+ type GlobalExposureEvent = ExposureEventDetail[];
541
+ type ObserverFrameRateOptions = {
542
+ forPageRect?: number;
543
+ forExposureCheck?: number;
544
+ };
545
+ export declare class LynxGlobalExposure {
546
+ #private;
547
+ readonly exposures: import("@angular/core").WritableSignal<GlobalExposureEvent>;
548
+ readonly disexposures: import("@angular/core").WritableSignal<GlobalExposureEvent>;
549
+ readonly active: import("@angular/core").WritableSignal<boolean>;
550
+ constructor();
551
+ /**
552
+ * Pauses global exposure detection. Elements with exposure-id stop generating
553
+ * exposure/disexposure GlobalEventEmitter events. Element-level
554
+ * binduiappear/binduidisappear events continue to fire.
555
+ */
556
+ stopExposure(options?: {
557
+ sendEvent: boolean;
558
+ }): void;
559
+ resumeExposure(): void;
560
+ /**
561
+ * Sets how often Lynx checks for exposure. Only the background thread's
562
+ * `lynx` has setObserverFrameRate, so a call from an event handler, which
563
+ * runs on the main thread, goes through the background thread (see
564
+ * background-call.ts). Resolves once it's applied.
565
+ */
566
+ setObserverFrameRate(options?: ObserverFrameRateOptions): Promise<void>;
567
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxGlobalExposure, never>;
568
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
569
+ }
570
+ /**
571
+ * Configuration for a custom font face to register dynamically via `lynx.addFont()`.
572
+ *
573
+ * Only `fontFamily` and `src` are supported by the Lynx engine.
574
+ * Platform formats: Android (TTF, OTF, TTC), iOS (TTF, OTF, WOFF, WOFF2).
575
+ */
576
+ type LynxFontFaceConfig = {
577
+ fontFamily: string;
578
+ src: string;
579
+ };
580
+ type LynxFontStatus = 'idle' | 'loading' | 'loaded' | 'error';
581
+ type LynxFontEntry = {
582
+ fontFamily: string;
583
+ src: string;
584
+ status: LynxFontStatus;
585
+ error?: Error;
586
+ };
587
+ /**
588
+ * Wraps `lynx.addFont()` with a Promise-based API and reactive signal state.
589
+ * Only the background thread's `lynx` has addFont, so a call from an event
590
+ * handler, which runs on the main thread, goes through the background thread
591
+ * (see background-call.ts).
592
+ *
593
+ * Use CSS `@font-face` in stylesheets for fonts known at build time (the
594
+ * standard Angular approach). Use this service only for fonts that must be
595
+ * loaded dynamically at runtime.
596
+ *
597
+ * @usageNotes
598
+ * ```typescript
599
+ * const fontService = inject(LynxFont);
600
+ *
601
+ * await fontService.addFont({
602
+ * fontFamily: 'CustomFont',
603
+ * src: 'https://example.com/custom-font.ttf',
604
+ * });
605
+ *
606
+ * // Reactive state
607
+ * const loaded = fontService.loadedFamilies(); // ReadonlySet<string>
608
+ * ```
609
+ */
610
+ export declare class LynxFont {
611
+ #private;
612
+ readonly fonts: import("@angular/core").Signal<ReadonlyMap<string, LynxFontEntry>>;
613
+ readonly loadedFamilies: import("@angular/core").Signal<ReadonlySet<string>>;
614
+ addFont(config: LynxFontFaceConfig): Promise<void>;
615
+ isLoaded(fontFamily: string): boolean;
616
+ getStatus(fontFamily: string): LynxFontStatus;
617
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxFont, never>;
618
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
619
+ }
620
+ /**
621
+ * Loads an external Lynx component bundle at runtime and returns the Angular
622
+ * component type. Wraps the native `__QueryComponent` PAPI — bundles must be
623
+ * built with `experimental_isLazyBundle: true` in the rsbuild plugin.
624
+ */
625
+ export declare const loadLazyBundle: (source: string) => Promise<Type<unknown>>;
626
+ /**
627
+ * The parts of webpack's `module.hot` API that {@link ɵhmrAccept} uses.
628
+ */
629
+ type HotModule = {
630
+ accept(): void;
631
+ dispose(callback: (data: Record<string, unknown>) => void): void;
632
+ invalidate(): void;
633
+ /** What the module's previous version passed to its dispose handlers. */
634
+ data?: Record<string, unknown>;
635
+ };
636
+ /**
637
+ * Takes a hot update of a module that defines components. The build plugin
638
+ * adds a call to the end of each such module in a development build, which
639
+ * reassigns the module's component classes to what it returns.
640
+ *
641
+ * On the main thread, where the app runs, a new version of the module either
642
+ * updates the running app in place or passes the update on:
643
+ *
644
+ * - **Only a template or stylesheet changed** (the source `signature`, which
645
+ * leaves those out, is the same, and the compiled `code` isn't): each
646
+ * component's new definition replaces the old one with Angular's
647
+ * `ɵɵreplaceMetadata()`, which Angular's own dev server uses for the same
648
+ * edits. It re-renders every view of the component in place and keeps the
649
+ * component instances, so their state survives. The module's bindings are
650
+ * pointed back at the old classes, so every module keeps using the one
651
+ * class the app's instances and injectors know.
652
+ * - **Anything else changed**, such as the class, an import, or a module this
653
+ * one imports: the update can't be applied to the running instances, so
654
+ * `hot.invalidate()` passes it on to the modules that import this one, up
655
+ * to the app's entry, which bootstraps the app again (see
656
+ * `bootstrapApplication`).
657
+ *
658
+ * The background thread runs no Angular, only the module-level code that
659
+ * registers background functions. It accepts every version, which re-runs
660
+ * the module and registers them again.
661
+ *
662
+ * @param hot - The module's `import.meta.webpackHot`.
663
+ * @param components - The component classes this version of the module defines.
664
+ * @param signature - A hash of the module's source without its components'
665
+ * templates and styles.
666
+ * @param code - A hash of the module's compiled code.
667
+ * @returns The classes the module should use from now on.
668
+ */
669
+ export declare const ɵhmrAccept: (hot: HotModule, components: Type<unknown>[], signature: string, code: string) => Type<unknown>[];
670
+ /**
671
+ * The app's own locale: `sourceLocale` from angular.json, which the build
672
+ * injects as `__LYNX_SOURCE_LOCALE__`, or `'en-US'` without one.
673
+ */
674
+ declare const getSourceLocale: () => string;
675
+ /**
676
+ * Reads `lynx.__globalProps.appLocale` directly, without Angular DI.
677
+ *
678
+ * Use this before `bootstrapApplication()` runs — e.g. to conditionally call
679
+ * `loadTranslations()` — since no injector exists yet at that point. Once the
680
+ * app is bootstrapped, prefer injecting `LynxLocale` for reactive access.
681
+ *
682
+ * Returns `undefined` outside a Lynx environment or when the host hasn't set
683
+ * a locale; callers decide their own fallback.
684
+ *
685
+ * @usageNotes
686
+ * ```typescript
687
+ * if (getLynxAppLocale() === 'fr') {
688
+ * loadTranslations({ 'app.greeting': 'Bonjour le monde !' });
689
+ * }
690
+ *
691
+ * bootstrapApplication(App, appConfig);
692
+ * ```
693
+ */
694
+ export declare const getLynxAppLocale: () => string | undefined;
695
+ /**
696
+ * Provides reactive access to the current locale on Lynx.
697
+ *
698
+ * Reads `lynx.__globalProps.appLocale` (set by the native host). Falls back to
699
+ * the `sourceLocale` from angular.json (injected as `__LYNX_SOURCE_LOCALE__`
700
+ * at build time), then to `'en-US'`.
701
+ *
702
+ * @usageNotes
703
+ * ```typescript
704
+ * const locale = inject(LynxLocale);
705
+ *
706
+ * // Reactive in templates
707
+ * template: `<text>Current locale: {{ locale.locale() }}</text>`
708
+ *
709
+ * // For LOCALE_ID integration, add provideLocale() to your app config
710
+ * ```
711
+ */
712
+ export declare class LynxLocale {
713
+ #private;
714
+ /**
715
+ * The current locale. Reactive — updates when global props change.
716
+ */
717
+ readonly locale: import("@angular/core").Signal<string>;
718
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxLocale, never>;
719
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
720
+ }
721
+ /**
722
+ * Provides Angular's `LOCALE_ID` token from the Lynx runtime locale.
723
+ *
724
+ * Add this to your application's providers to automatically configure
725
+ * Angular's locale-aware features (pipes, i18n) with the locale from
726
+ * `lynx.__globalProps.appLocale`.
727
+ *
728
+ * The apps that `ng build --platform` makes send the phone's language, which
729
+ * the app may not support. When Angular has no locale data for it (see
730
+ * `registerLocaleData()`), `LOCALE_ID` is the app's source locale instead, as
731
+ * a native app shows its own language on a phone set to one it lacks.
732
+ * Otherwise Angular's date and number pipes would throw.
733
+ *
734
+ * @usageNotes
735
+ * ```typescript
736
+ * bootstrapApplication(App, {
737
+ * providers: [provideRenderer(), provideLocale()],
738
+ * });
739
+ * ```
740
+ */
741
+ export declare const provideLocale: () => EnvironmentProviders;
742
+ /**
743
+ * Controls gesture state from within a callback.
744
+ * Wraps __SetGestureState and __ConsumeGesture PAPI calls.
745
+ * Passed as the second argument to gesture callbacks so handlers can
746
+ * programmatically drive the gesture state machine (e.g. activate a gesture
747
+ * only when a condition is met, or fail it early to let a competing gesture win).
748
+ */
749
+ export declare class GestureStateManager {
750
+ #private;
751
+ constructor(element: ElementRef, gestureId: number);
752
+ /**
753
+ * State codes match Lynx's native gesture state enum:
754
+ * 1 = ACTIVE, 2 = FAILED, 3 = END
755
+ */
756
+ fail(): void;
757
+ activate(): void;
758
+ end(): void;
759
+ /**
760
+ * `{ consume }` stops the gesture from bubbling up to ancestor elements.
761
+ * Use this when this element should handle the gesture exclusively and
762
+ * parent scroll containers or gesture detectors should not also receive it.
763
+ */
764
+ consumeGesture(consume?: boolean): void;
765
+ /**
766
+ * `{ inner: intercept }` intercepts gestures from DESCENDANT elements —
767
+ * the opposite direction of consumeGesture. Use this on a parent to claim
768
+ * a gesture before children can handle it (e.g. a pull-to-refresh view
769
+ * intercepting scrolls inside its list child).
770
+ */
771
+ interceptGesture(intercept?: boolean): void;
772
+ }
773
+ /**
774
+ * Gesture type IDs matching the Lynx native engine (from @lynx-js/react gesture-runtime).
775
+ */
776
+ export declare enum GestureType {
777
+ PAN = 0,
778
+ FLING = 1,
779
+ DEFAULT = 2,
780
+ TAP = 3,
781
+ LONGPRESS = 4,
782
+ ROTATION = 5,
783
+ PINCH = 6,
784
+ NATIVE = 7
785
+ }
786
+ export declare enum GestureState {
787
+ UNDETERMINED = 0,
788
+ BEGAN = 1,
789
+ ACTIVE = 2,
790
+ END = 3,
791
+ FAILED = 4,
792
+ CANCELED = 5
793
+ }
794
+ type GestureEvent = {
795
+ /**
796
+ * Optional: the native engine conveys the phase through the callback that
797
+ * fires (onBegin/onStart/onUpdate/onEnd), not a field on the event payload,
798
+ * so `state` is usually absent at runtime.
799
+ */
800
+ state?: GestureState;
801
+ /**
802
+ * Absolute (page-relative) coordinates, derived at runtime by mapGestureEvent
803
+ * from the native `pageX`/`pageY`. Optional (was required) because they're
804
+ * only present when the gesture's payload carries coordinates — making the
805
+ * type promise a `number` that isn't always there was a latent footgun.
806
+ */
807
+ absoluteX?: number;
808
+ absoluteY?: number;
809
+ /**
810
+ * The untouched native params dict (Lynx field names: scrollX, pageX, x, y,
811
+ * isAtStart, …). Escape hatch for reading fields that have no flat alias —
812
+ * the flat properties above are derived from it. See mapGestureEvent.
813
+ */
814
+ params?: Record<string, unknown>;
815
+ };
816
+ type PanGestureEvent = {
817
+ translationX: number;
818
+ translationY: number;
819
+ velocityX: number;
820
+ velocityY: number;
821
+ } & GestureEvent;
822
+ type TapGestureEvent = {
823
+ x: number;
824
+ y: number;
825
+ } & GestureEvent;
826
+ type FlingGestureEvent = {
827
+ velocityX: number;
828
+ velocityY: number;
829
+ } & GestureEvent;
830
+ type PinchGestureEvent = {
831
+ scale: number;
832
+ velocity: number;
833
+ } & GestureEvent;
834
+ type RotationGestureEvent = {
835
+ rotation: number;
836
+ velocity: number;
837
+ } & GestureEvent;
838
+ type LongPressGestureEvent = {
839
+ x: number;
840
+ y: number;
841
+ duration: number;
842
+ } & GestureEvent;
843
+ /**
844
+ * Bitmask values — combine with bitwise OR for multi-direction fling:
845
+ * e.g. FlingDirection.LEFT | FlingDirection.RIGHT for horizontal fling.
846
+ */
847
+ export declare enum FlingDirection {
848
+ RIGHT = 1,
849
+ LEFT = 2,
850
+ UP = 4,
851
+ DOWN = 8
852
+ }
853
+ type GestureCallback<TEvent extends GestureEvent = GestureEvent> = (event: TEvent) => void;
854
+ type GestureCallbackWithState<TEvent extends GestureEvent = GestureEvent> = (event: TEvent, stateManager: GestureStateManager) => void;
855
+ export declare abstract class BaseGesture<TEvent extends GestureEvent = GestureEvent, TSelf extends BaseGesture<TEvent, any> = any> {
856
+ readonly id: number;
857
+ abstract readonly type: GestureType;
858
+ /**
859
+ * @internal — accessed by the directive to build the PAPI config.
860
+ * GestureCallback<any> avoids an invariance error when assigning concrete gesture
861
+ * subclasses (e.g. PanGesture) to BaseGesture<GestureEvent, any>. The directive
862
+ * already casts callbacks to any when invoking them, so the wider type is safe.
863
+ */
864
+ _callbacks: Record<string, GestureCallback<any>>;
865
+ /**
866
+ * @internal
867
+ *
868
+ * Starts as `{ enabled: true }`, like React Lynx's gesture-runtime, so every
869
+ * gesture sends a config, even one with no options of its own (Fling, Pinch,
870
+ * Rotation). Gestures whose native handler reads options seed the rest of
871
+ * their defaults too: once a config is present, iOS reads each key it leaves
872
+ * out as `0` (see ./const).
873
+ */
874
+ _config: Record<string, unknown>;
875
+ /**
876
+ * @internal
877
+ */
878
+ _waitFor: BaseGesture[];
879
+ /**
880
+ * @internal
881
+ */
882
+ _simultaneousWith: BaseGesture[];
883
+ /**
884
+ * @internal
885
+ */
886
+ _continueWith: BaseGesture[];
887
+ /**
888
+ * Fires when the gesture starts tracking a touch, before it's recognized:
889
+ * at touch-down for most gestures, and when the finger lifts for a fling.
890
+ *
891
+ * A continuous gesture doesn't need one for its `onStart` and `onEnd` to
892
+ * fire. LynxGestureDetector registers an empty `onBegin` when you don't, since
893
+ * Lynx's native handlers skip those callbacks without it. See
894
+ * gesture-detector.ts.
895
+ */
896
+ onBegin(cb: GestureCallbackWithState<TEvent>): TSelf;
897
+ /**
898
+ * Fires when the gesture is RECOGNIZED (transitions to active). For a tap this
899
+ * is the only callback that fires exclusively on success — see `onEnd`.
900
+ */
901
+ onStart(cb: GestureCallbackWithState<TEvent>): TSelf;
902
+ /**
903
+ * Fires when the gesture ends.
904
+ *
905
+ * For discrete gestures (tap, long-press) LynxGestureDetector normalizes this
906
+ * to fire ONLY when the gesture was actually recognized. Lynx's native engine
907
+ * emits `onEnd` on failure too — the iOS `fail` path calls it — so a drag that
908
+ * overshoots a tap's `maxDistance` would otherwise still trigger `onEnd`. The
909
+ * directive suppresses that failed-gesture `onEnd`; continuous gestures pass
910
+ * through unchanged. See gesture-detector.ts.
911
+ */
912
+ onEnd(cb: GestureCallbackWithState<TEvent>): TSelf;
913
+ onTouchesDown(cb: GestureCallbackWithState<TEvent>): TSelf;
914
+ onTouchesUp(cb: GestureCallbackWithState<TEvent>): TSelf;
915
+ /**
916
+ * Delays this gesture until all listed gestures have failed.
917
+ * Use to give higher-priority gestures (e.g. double-tap) first right of refusal.
918
+ * `as unknown as TSelf` is needed because TypeScript can't prove that `this`
919
+ * satisfies the concrete TSelf bound — the double cast is intentional.
920
+ */
921
+ waitFor(...gestures: BaseGesture[]): TSelf;
922
+ /**
923
+ * Allows this gesture and the listed gestures to be active at the same time.
924
+ * Without this, Lynx's gesture system lets only one gesture be active per element.
925
+ */
926
+ simultaneousWith(...gestures: BaseGesture[]): TSelf;
927
+ /**
928
+ * This gesture activates after the listed gestures END (not fail).
929
+ * Useful for chaining: e.g. a long-press followed by a drag.
930
+ */
931
+ continueWith(...gestures: BaseGesture[]): TSelf;
932
+ /**
933
+ * ⚠️ Not read by Lynx's native gesture handlers yet (as of Lynx 4.1, no
934
+ * handler looks up `enabled`), so a disabled gesture still fires on a
935
+ * device. Unbind the gesture from `[lynxGesture]` to turn it off. Kept for
936
+ * API parity with Lynx's gesture-runtime.
937
+ */
938
+ enabled(value: boolean): TSelf;
939
+ }
940
+ /**
941
+ * Continuous gestures (pan, fling, rotation, pinch) have an onUpdate callback
942
+ * that fires on every frame while the gesture is active.
943
+ */
944
+ export declare abstract class ContinuousGesture<TEvent extends GestureEvent = GestureEvent, TSelf extends ContinuousGesture<TEvent, any> = any> extends BaseGesture<TEvent, TSelf> {
945
+ onUpdate(cb: GestureCallbackWithState<TEvent>): TSelf;
946
+ }
947
+ type AnyGesture$1 = BaseGesture<any, any>;
948
+ export declare class ComposedGesture {
949
+ readonly gestures: AnyGesture$1[];
950
+ readonly compositionType: 'simultaneous' | 'exclusive' | 'race';
951
+ constructor(gestures: AnyGesture$1[], compositionType: 'simultaneous' | 'exclusive' | 'race');
952
+ }
953
+ export declare const Gesture: {
954
+ Simultaneous(...gestures: AnyGesture$1[]): ComposedGesture;
955
+ Exclusive(...gestures: AnyGesture$1[]): ComposedGesture;
956
+ Race(...gestures: AnyGesture$1[]): ComposedGesture;
957
+ };
958
+ /**
959
+ * Lynx's fling follows the momentum of a drag after the finger lifts: `onBegin`
960
+ * fires on release, `onUpdate` on every frame (with `deltaX`/`deltaY` in the
961
+ * params), and `onEnd` when it stops. Lynx starts that fling in its BEGAN
962
+ * state and never activates it, so `onStart` doesn't fire
963
+ * (LynxFlingGestureHandler.m / FlingGestureHandler.java). Lynx also flings only
964
+ * the element that won the touch, and a fling ignores the touch until the
965
+ * finger lifts, so it needs a pan on the same element (`Gesture.Simultaneous`).
966
+ */
967
+ export declare class FlingGesture extends ContinuousGesture<FlingGestureEvent, FlingGesture> {
968
+ readonly type = GestureType.FLING;
969
+ /**
970
+ * FlingDirection is a bitmask — combine values with | for multi-direction:
971
+ * e.g. FlingDirection.LEFT | FlingDirection.RIGHT recognizes horizontal flings.
972
+ *
973
+ * ⚠️ Not read by Lynx's native fling handlers yet: as of Lynx 4.1, iOS's
974
+ * `handleConfigMap` is a TODO and Android's is empty, so every fling fires,
975
+ * in any direction. Kept for API parity with Lynx's gesture-runtime.
976
+ */
977
+ direction(dir: FlingDirection): this;
978
+ /**
979
+ * The gesture only recognizes when exactly `count` fingers are involved.
980
+ * Defaults to 1 if not set.
981
+ *
982
+ * ⚠️ Not read by Lynx's native fling handlers yet (see `direction`).
983
+ */
984
+ numberOfPointers(count: number): this;
985
+ }
986
+ type AnyGesture = BaseGesture<any, any>;
987
+ type GestureInput = AnyGesture | AnyGesture[] | ComposedGesture;
988
+ /**
989
+ * Directive that bridges Angular's gesture binding to Lynx's native gesture
990
+ * system (__SetGestureDetector / __RemoveGestureDetector). Accepts a single
991
+ * gesture, an array of gestures, or a ComposedGesture (simultaneous/exclusive).
992
+ * Each gesture is registered with the native engine via its unique numeric ID.
993
+ *
994
+ * Cross-package prerequisite (easy to miss when debugging): the native engine
995
+ * silently ignores every __SetGestureDetector call unless the compiled page
996
+ * config has `enableNewGesture: true`. @blotch/rsbuild-plugin-angular-lynx
997
+ * defaults that flag ON, so this directive works out of the box — but if
998
+ * gestures ever go dead app-wide with no error, that build flag is the first
999
+ * thing to check, not this directive.
1000
+ */
1001
+ export declare class LynxGestureDetector implements OnChanges, OnDestroy {
1002
+ #private;
1003
+ lynxGesture: GestureInput;
1004
+ constructor();
1005
+ /**
1006
+ * Full teardown + re-register on every input change. This is safe because
1007
+ * gesture IDs are stable (assigned once in BaseGesture constructor), so
1008
+ * inter-gesture relationships (waitFor, simultaneousWith) stay valid.
1009
+ */
1010
+ ngOnChanges(_changes: SimpleChanges): void;
1011
+ ngOnDestroy(): void;
1012
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxGestureDetector, never>;
1013
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxGestureDetector, "[lynxGesture]", never, {
1014
+ "lynxGesture": {
1015
+ "alias": "lynxGesture";
1016
+ "required": false;
1017
+ };
1018
+ }, {}, never, never, true, never>;
1019
+ }
1020
+ export declare class LongPressGesture extends BaseGesture<LongPressGestureEvent, LongPressGesture> {
1021
+ readonly type = GestureType.LONGPRESS;
1022
+ /**
1023
+ * Seed the FULL default config on construction. Without an explicit
1024
+ * `maxDistance`, calling only `minDuration()` would send a partial config and
1025
+ * the native handler would read `maxDistance` back as `0` — failing the
1026
+ * long-press on the tiniest finger jitter. Mirrors Lynx's own gesture-runtime
1027
+ * LongPressGesture defaults. See ./const for the full explanation.
1028
+ */
1029
+ _config: Record<string, unknown>;
1030
+ /**
1031
+ * Minimum hold time in ms before the gesture is recognized.
1032
+ * Shorter presses are treated as taps and ignored.
1033
+ */
1034
+ minDuration(ms: number): this;
1035
+ /**
1036
+ * If the finger drifts more than `px` pixels from the initial touch point
1037
+ * during the hold, the gesture fails — allowing a scroll to take over.
1038
+ */
1039
+ maxDistance(px: number): this;
1040
+ }
1041
+ export declare class PanGesture extends ContinuousGesture<PanGestureEvent, PanGesture> {
1042
+ readonly type = GestureType.PAN;
1043
+ /**
1044
+ * Seed the default config on construction so a complete config is always sent
1045
+ * to native, keeping behavior consistent with the other gestures. Mirrors
1046
+ * Lynx's own gesture-runtime PanGesture defaults. See ./const.
1047
+ */
1048
+ _config: Record<string, unknown>;
1049
+ minDistance(distance: number): this;
1050
+ /**
1051
+ * activeOffset: the gesture activates once the finger moves past this
1052
+ * threshold. A number means "any direction" (symmetrical); a tuple [min, max]
1053
+ * means the offset must be within that range. Example: activeOffsetX(20)
1054
+ * activates after 20px of horizontal movement.
1055
+ *
1056
+ * ⚠️ Not read by Lynx's native pan handlers yet: as of Lynx 4.1 they read
1057
+ * only `minDistance` (LynxPanGestureHandler.m / PanGestureHandler.java
1058
+ * `handleConfigMap`). The same goes for activeOffsetY, failOffsetX/Y and
1059
+ * min/maxPointers. Kept for API parity with Lynx's gesture-runtime.
1060
+ */
1061
+ activeOffsetX(offset: number | [number, number]): this;
1062
+ activeOffsetY(offset: number | [number, number]): this;
1063
+ /**
1064
+ * failOffset: if the finger moves past this threshold in the perpendicular
1065
+ * direction, the gesture fails (ceding to a competing gesture). Example:
1066
+ * failOffsetY(10) on a horizontal pan: if the user moves >10px vertically
1067
+ * before activating, the gesture fails and a vertical scroll can take over.
1068
+ *
1069
+ * ⚠️ Not read by Lynx's native pan handlers yet (see `activeOffsetX`). Call
1070
+ * the state manager's `fail()` from `onUpdate` instead.
1071
+ */
1072
+ failOffsetX(offset: number | [number, number]): this;
1073
+ failOffsetY(offset: number | [number, number]): this;
1074
+ minPointers(count: number): this;
1075
+ maxPointers(count: number): this;
1076
+ }
1077
+ export declare class PinchGesture extends ContinuousGesture<PinchGestureEvent, PinchGesture> {
1078
+ readonly type = GestureType.PINCH;
1079
+ }
1080
+ export declare class RotationGesture extends ContinuousGesture<RotationGestureEvent, RotationGesture> {
1081
+ readonly type = GestureType.ROTATION;
1082
+ }
1083
+ export declare class TapGesture extends BaseGesture<TapGestureEvent, TapGesture> {
1084
+ readonly type = GestureType.TAP;
1085
+ /**
1086
+ * Seed the FULL default config on construction. The native iOS handler reads
1087
+ * any absent config key as `0` once a config is present, so shipping a partial
1088
+ * config (e.g. only `numberOfTaps`) would zero out `maxDuration`/`maxDistance`
1089
+ * and make every tap fail instantly. Mirrors Lynx's own gesture-runtime
1090
+ * TapGesture defaults. See ./const for the full explanation.
1091
+ */
1092
+ _config: Record<string, unknown>;
1093
+ /**
1094
+ * For double/triple tap, pair with waitFor on the single-tap gesture so
1095
+ * the single-tap handler doesn't fire prematurely before the count is met.
1096
+ *
1097
+ * ⚠️ NOT enforced by the Lynx native runtime — no platform handler implements
1098
+ * multi-tap counting (a whole-tree search of the Lynx source turns up nothing
1099
+ * that reads `numberOfTaps`), so setting this is currently a no-op on-device.
1100
+ * To detect a double-tap, time successive taps yourself in the callback. Kept
1101
+ * for API parity with Lynx's gesture-runtime.
1102
+ */
1103
+ numberOfTaps(count: number): this;
1104
+ /**
1105
+ * Maximum time between finger-down and finger-up for a tap to register.
1106
+ * Touches held longer than this are treated as a long-press.
1107
+ */
1108
+ maxDuration(ms: number): this;
1109
+ /**
1110
+ * If the finger travels more than `px` pixels before lifting, the tap fails.
1111
+ * Keeps a tap distinct from a small drag.
1112
+ */
1113
+ maxDistance(px: number): this;
1114
+ }
1115
+ /**
1116
+ * A length Lynx's exposure detection parses, such as `'20px'` or `'-10rpx'`.
1117
+ * Lynx reads the margins as strings, so a bare number has no effect.
1118
+ */
1119
+ type ExposureMargin = `${number}px` | `${number}rpx`;
1120
+ /**
1121
+ * @Directive() is required so that ng-packagr's Angular partial compiler
1122
+ * recognizes this base class as an Angular artifact. The selector is left
1123
+ * empty — the class is never used directly as a directive.
1124
+ *
1125
+ * DESIGN NOTES — why these are directives, not components:
1126
+ *
1127
+ * 1. No @Component: Components have their own template (<ng-content/>). When a
1128
+ * component wraps content, Angular treats that content as "projected" — the
1129
+ * native parent is not yet established while Angular initializes projected
1130
+ * nodes. Any directive inside the projected content that injects
1131
+ * ViewContainerRef (e.g. RouterOutlet) will crash because insertAnchorNode
1132
+ * calls renderer.insertBefore(null, anchor) — null being the not-yet-resolved
1133
+ * native parent. Using @Directive avoids projection entirely; children are
1134
+ * rendered as direct element children just like without LYNX_ELEMENTS.
1135
+ *
1136
+ * 2. Properties are declared as inputs so that Angular's template checker
1137
+ * accepts property bindings like [src]="url" without errors. Angular
1138
+ * intercepts these bindings and sets them on the directive instance. The
1139
+ * ngOnChanges hook forwards every input change to the native Lynx element
1140
+ * via BaseLynxElement.setAttribute(), which calls __SetAttribute — the same
1141
+ * endpoint that renderer.setProperty() would reach.
1142
+ *
1143
+ * 3. Events (bindtap, catchtap, bindinput, bindscroll, …) are NOT declared as
1144
+ * @Output() because Angular would intercept them and skip the renderer's
1145
+ * listen() call, breaking native Lynx event delivery. They continue to work
1146
+ * via renderer.listen() which handles all unrecognized event names.
1147
+ */
1148
+ declare class LynxElementBase implements OnChanges {
1149
+ #private;
1150
+ ngOnChanges(changes: SimpleChanges): void;
1151
+ id?: string;
1152
+ /**
1153
+ * Named reference accessible via lynx.getElementById / findViewByName.
1154
+ */
1155
+ name?: string;
1156
+ /**
1157
+ * Whether this element is an accessibility node.
1158
+ */
1159
+ 'accessibility-element'?: boolean;
1160
+ /**
1161
+ * Text read aloud by screen readers.
1162
+ */
1163
+ 'accessibility-label'?: string;
1164
+ /**
1165
+ * The kind of element a screen reader announces. Plural, as Lynx reads it:
1166
+ * iOS, Android and Harmony ignore `accessibility-trait`. @default 'none'
1167
+ */
1168
+ 'accessibility-traits'?: 'text' | 'image' | 'button' | 'link' | 'header' | 'search' | 'selected' | 'playable' | 'keyboard' | 'summary' | 'disabled' | 'updating' | 'adjustable' | 'tabbar' | 'none';
1169
+ /**
1170
+ * Comma-separated `id`s of the child elements a screen reader visits, in
1171
+ * order. iOS and Android look each one up as an `id` selector.
1172
+ */
1173
+ 'accessibility-elements'?: string;
1174
+ 'accessibility-elements-hidden'?: boolean;
1175
+ /**
1176
+ * Whether this element exclusively captures accessibility focus.
1177
+ */
1178
+ 'accessibility-exclusive-focus'?: boolean;
1179
+ /**
1180
+ * Accessibility identifier (separate from name).
1181
+ */
1182
+ 'a11y-id'?: string;
1183
+ /**
1184
+ * Whether the element receives touch events (default: true).
1185
+ */
1186
+ 'user-interaction-enabled'?: boolean;
1187
+ /**
1188
+ * Whether the element receives platform-native gestures.
1189
+ */
1190
+ 'native-interaction-enabled'?: boolean;
1191
+ /**
1192
+ * Whether touch events pass through to elements below.
1193
+ */
1194
+ 'event-through'?: boolean;
1195
+ /**
1196
+ * Extends the touch target area. Object or CSS-shorthand string.
1197
+ */
1198
+ 'hit-slop'?: string | object;
1199
+ /**
1200
+ * Whether the element consumes native iOS/Android gestures.
1201
+ */
1202
+ 'block-native-event'?: boolean;
1203
+ /**
1204
+ * Whether focus events are suppressed.
1205
+ */
1206
+ 'ignore-focus'?: boolean;
1207
+ /**
1208
+ * Allow simultaneous touch recognition (iOS).
1209
+ */
1210
+ 'ios-enable-simultaneous-touch'?: boolean;
1211
+ /**
1212
+ * Lets Lynx draw the element into its parent's native view instead of
1213
+ * creating its own (Android). `false` gives it its own view, which sticky
1214
+ * positioning, text selection and reliable clipping need. @default true
1215
+ */
1216
+ flatten?: boolean;
1217
+ /**
1218
+ * Direction in which the element takes pan gestures from native views
1219
+ * outside Lynx: 0 = horizontal, 1 = vertical.
1220
+ */
1221
+ 'pan-intercept-direction'?: 0 | 1;
1222
+ /**
1223
+ * Which views `pan-intercept-direction` takes pans from: 0 = self,
1224
+ * 1 = ancestors, 2 = descendants, 3 = self and ancestors, 4 = self and
1225
+ * descendants, 5 = all.
1226
+ */
1227
+ 'pan-intercept-scope'?: 0 | 1 | 2 | 3 | 4 | 5;
1228
+ /**
1229
+ * Swipe angle ranges, `[start, end]` in degrees, that the element keeps
1230
+ * from platform gestures.
1231
+ */
1232
+ 'consume-slide-event'?: [number, number][];
1233
+ /**
1234
+ * Whether `:active` also applies to the ancestors on the touch's event path.
1235
+ */
1236
+ 'enable-touch-pseudo-propagation'?: boolean;
1237
+ /**
1238
+ * Unique ID used for impression/exposure analytics.
1239
+ */
1240
+ 'exposure-id'?: string;
1241
+ /**
1242
+ * Scene identifier grouping exposure events.
1243
+ */
1244
+ 'exposure-scene'?: string;
1245
+ /**
1246
+ * How much of the element must be visible to count as exposed, as a
1247
+ * percentage string such as `'50%'`. @default '0%'
1248
+ */
1249
+ 'exposure-area'?: `${number}%`;
1250
+ /**
1251
+ * Extends/shrinks the viewport detection zone (top edge).
1252
+ */
1253
+ 'exposure-screen-margin-top'?: ExposureMargin;
1254
+ /**
1255
+ * Extends/shrinks the viewport detection zone (bottom edge).
1256
+ */
1257
+ 'exposure-screen-margin-bottom'?: ExposureMargin;
1258
+ /**
1259
+ * Extends/shrinks the viewport detection zone (left edge).
1260
+ */
1261
+ 'exposure-screen-margin-left'?: ExposureMargin;
1262
+ /**
1263
+ * Extends/shrinks the viewport detection zone (right edge).
1264
+ */
1265
+ 'exposure-screen-margin-right'?: ExposureMargin;
1266
+ /**
1267
+ * Adjusts the element's own bounding rect for exposure detection (top).
1268
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1269
+ */
1270
+ 'exposure-ui-margin-top'?: ExposureMargin;
1271
+ /**
1272
+ * Adjusts the element's own bounding rect for exposure detection (bottom).
1273
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1274
+ */
1275
+ 'exposure-ui-margin-bottom'?: ExposureMargin;
1276
+ /**
1277
+ * Adjusts the element's own bounding rect for exposure detection (left).
1278
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1279
+ */
1280
+ 'exposure-ui-margin-left'?: ExposureMargin;
1281
+ /**
1282
+ * Adjusts the element's own bounding rect for exposure detection (right).
1283
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1284
+ */
1285
+ 'exposure-ui-margin-right'?: ExposureMargin;
1286
+ /**
1287
+ * Turns on `exposure-ui-margin-*` on iOS and Android (always on for Harmony
1288
+ * and the web). It also changes how they apply `exposure-screen-margin-*`.
1289
+ * @default false
1290
+ */
1291
+ 'enable-exposure-ui-margin'?: boolean;
1292
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxElementBase, never>;
1293
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxElementBase, never, never, {
1294
+ "id": {
1295
+ "alias": "id";
1296
+ "required": false;
1297
+ };
1298
+ "name": {
1299
+ "alias": "name";
1300
+ "required": false;
1301
+ };
1302
+ "accessibility-element": {
1303
+ "alias": "accessibility-element";
1304
+ "required": false;
1305
+ };
1306
+ "accessibility-label": {
1307
+ "alias": "accessibility-label";
1308
+ "required": false;
1309
+ };
1310
+ "accessibility-value": {
1311
+ "alias": "accessibility-value";
1312
+ "required": false;
1313
+ };
1314
+ "accessibility-actions": {
1315
+ "alias": "accessibility-actions";
1316
+ "required": false;
1317
+ };
1318
+ "accessibility-traits": {
1319
+ "alias": "accessibility-traits";
1320
+ "required": false;
1321
+ };
1322
+ "accessibility-elements": {
1323
+ "alias": "accessibility-elements";
1324
+ "required": false;
1325
+ };
1326
+ "accessibility-elements-hidden": {
1327
+ "alias": "accessibility-elements-hidden";
1328
+ "required": false;
1329
+ };
1330
+ "accessibility-exclusive-focus": {
1331
+ "alias": "accessibility-exclusive-focus";
1332
+ "required": false;
1333
+ };
1334
+ "a11y-id": {
1335
+ "alias": "a11y-id";
1336
+ "required": false;
1337
+ };
1338
+ "user-interaction-enabled": {
1339
+ "alias": "user-interaction-enabled";
1340
+ "required": false;
1341
+ };
1342
+ "native-interaction-enabled": {
1343
+ "alias": "native-interaction-enabled";
1344
+ "required": false;
1345
+ };
1346
+ "event-through": {
1347
+ "alias": "event-through";
1348
+ "required": false;
1349
+ };
1350
+ "hit-slop": {
1351
+ "alias": "hit-slop";
1352
+ "required": false;
1353
+ };
1354
+ "block-native-event": {
1355
+ "alias": "block-native-event";
1356
+ "required": false;
1357
+ };
1358
+ "ignore-focus": {
1359
+ "alias": "ignore-focus";
1360
+ "required": false;
1361
+ };
1362
+ "ios-enable-simultaneous-touch": {
1363
+ "alias": "ios-enable-simultaneous-touch";
1364
+ "required": false;
1365
+ };
1366
+ "flatten": {
1367
+ "alias": "flatten";
1368
+ "required": false;
1369
+ };
1370
+ "pan-intercept-direction": {
1371
+ "alias": "pan-intercept-direction";
1372
+ "required": false;
1373
+ };
1374
+ "pan-intercept-scope": {
1375
+ "alias": "pan-intercept-scope";
1376
+ "required": false;
1377
+ };
1378
+ "consume-slide-event": {
1379
+ "alias": "consume-slide-event";
1380
+ "required": false;
1381
+ };
1382
+ "enable-touch-pseudo-propagation": {
1383
+ "alias": "enable-touch-pseudo-propagation";
1384
+ "required": false;
1385
+ };
1386
+ "exposure-id": {
1387
+ "alias": "exposure-id";
1388
+ "required": false;
1389
+ };
1390
+ "exposure-scene": {
1391
+ "alias": "exposure-scene";
1392
+ "required": false;
1393
+ };
1394
+ "exposure-area": {
1395
+ "alias": "exposure-area";
1396
+ "required": false;
1397
+ };
1398
+ "exposure-screen-margin-top": {
1399
+ "alias": "exposure-screen-margin-top";
1400
+ "required": false;
1401
+ };
1402
+ "exposure-screen-margin-bottom": {
1403
+ "alias": "exposure-screen-margin-bottom";
1404
+ "required": false;
1405
+ };
1406
+ "exposure-screen-margin-left": {
1407
+ "alias": "exposure-screen-margin-left";
1408
+ "required": false;
1409
+ };
1410
+ "exposure-screen-margin-right": {
1411
+ "alias": "exposure-screen-margin-right";
1412
+ "required": false;
1413
+ };
1414
+ "exposure-ui-margin-top": {
1415
+ "alias": "exposure-ui-margin-top";
1416
+ "required": false;
1417
+ };
1418
+ "exposure-ui-margin-bottom": {
1419
+ "alias": "exposure-ui-margin-bottom";
1420
+ "required": false;
1421
+ };
1422
+ "exposure-ui-margin-left": {
1423
+ "alias": "exposure-ui-margin-left";
1424
+ "required": false;
1425
+ };
1426
+ "exposure-ui-margin-right": {
1427
+ "alias": "exposure-ui-margin-right";
1428
+ "required": false;
1429
+ };
1430
+ "enable-exposure-ui-margin": {
1431
+ "alias": "enable-exposure-ui-margin";
1432
+ "required": false;
1433
+ };
1434
+ }, {}, never, never, true, never>;
1435
+ static "ngAcceptInputType_accessibility-element": boolean | "" | "true" | "false" | undefined;
1436
+ static "ngAcceptInputType_accessibility-elements-hidden": boolean | "" | "true" | "false" | undefined;
1437
+ static "ngAcceptInputType_accessibility-exclusive-focus": boolean | "" | "true" | "false" | undefined;
1438
+ static "ngAcceptInputType_user-interaction-enabled": boolean | "" | "true" | "false" | undefined;
1439
+ static "ngAcceptInputType_native-interaction-enabled": boolean | "" | "true" | "false" | undefined;
1440
+ static "ngAcceptInputType_event-through": boolean | "" | "true" | "false" | undefined;
1441
+ static "ngAcceptInputType_block-native-event": boolean | "" | "true" | "false" | undefined;
1442
+ static "ngAcceptInputType_ignore-focus": boolean | "" | "true" | "false" | undefined;
1443
+ static "ngAcceptInputType_ios-enable-simultaneous-touch": boolean | "" | "true" | "false" | undefined;
1444
+ static ngAcceptInputType_flatten: boolean | "" | "true" | "false" | undefined;
1445
+ static "ngAcceptInputType_pan-intercept-direction": 0 | 1 | "0" | "1" | undefined;
1446
+ static "ngAcceptInputType_pan-intercept-scope": 0 | 1 | 2 | 3 | 4 | 5 | "0" | "1" | "2" | "3" | "4" | "5" | undefined;
1447
+ static "ngAcceptInputType_enable-touch-pseudo-propagation": boolean | "" | "true" | "false" | undefined;
1448
+ static "ngAcceptInputType_enable-exposure-ui-margin": boolean | "" | "true" | "false" | undefined;
1449
+ }
1450
+ /**
1451
+ * Backdrop blur: blurs the content rendered behind the element, like CSS
1452
+ * `backdrop-filter: blur()`. On iOS, `blur-effect="glass"` renders the
1453
+ * Liquid Glass material.
1454
+ *
1455
+ * Android only has the plain blur, a Gaussian blur of `blur-radius`. There
1456
+ * the runtime approximates `blur-effect`, `glass-style` and
1457
+ * `glass-tint-color` with a translucent background and rim over the blur,
1458
+ * which a background, background image or shadow the app sets replaces.
1459
+ * Nothing refracts, and `glass-interactive` and `spacing` do nothing.
1460
+ */
1461
+ export declare class LynxBlurView extends LynxElementBase {
1462
+ /**
1463
+ * Gaussian blur radius (Android/iOS/Harmony). @default '0px'
1464
+ */
1465
+ 'blur-radius'?: string;
1466
+ /**
1467
+ * Downsampling ratio of the blurred area. Higher is faster but softer (Android). @default 6
1468
+ */
1469
+ 'blur-sampling'?: number;
1470
+ /**
1471
+ * Whether the blur updates automatically as content behind it changes (Android). @default true
1472
+ */
1473
+ 'enable-auto-blur'?: boolean;
1474
+ /**
1475
+ * Raw id of the view to capture and blur; it must have `flatten="false"`
1476
+ * (Android). The runtime points it at the page, so a blur-view inside
1477
+ * another blur-view still blurs what's behind it; an empty string restores
1478
+ * Android's own choice, the nearest ancestor that clips or contains it.
1479
+ */
1480
+ 'android-capture-target'?: string;
1481
+ /**
1482
+ * Switches the internal blur-buffer refresh path (Android, experimental).
1483
+ */
1484
+ 'experimental-update-blur-radius'?: boolean;
1485
+ /**
1486
+ * Blur material (iOS). `glass` renders Liquid Glass; `glass-container`
1487
+ * merges nested glass `<blur-view>`s into one combined effect. Android
1488
+ * gets a tint that approximates it. @default 'light'
1489
+ */
1490
+ 'blur-effect'?: 'light' | 'extra-light' | 'dark' | 'glass' | 'glass-container';
1491
+ /**
1492
+ * Distance at which glass elements inside a `glass-container` start to merge (iOS). @default 0
1493
+ */
1494
+ spacing?: number;
1495
+ /**
1496
+ * Whether the glass reacts to touches (iOS). @default false
1497
+ */
1498
+ 'glass-interactive'?: boolean;
1499
+ /**
1500
+ * Tint color applied to the glass (iOS; approximated on Android). @default 'transparent'
1501
+ */
1502
+ 'glass-tint-color'?: string;
1503
+ /**
1504
+ * Glass variant (iOS; approximated on Android). @default 'regular'
1505
+ */
1506
+ 'glass-style'?: 'regular' | 'clear';
1507
+ /**
1508
+ * Forces a light or dark appearance for the material (iOS, Lynx 4.1+).
1509
+ */
1510
+ 'ios-user-interface-style'?: 'dark' | 'light';
1511
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxBlurView, never>;
1512
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxBlurView, "blur-view", never, {
1513
+ "blur-radius": {
1514
+ "alias": "blur-radius";
1515
+ "required": false;
1516
+ };
1517
+ "blur-sampling": {
1518
+ "alias": "blur-sampling";
1519
+ "required": false;
1520
+ };
1521
+ "enable-auto-blur": {
1522
+ "alias": "enable-auto-blur";
1523
+ "required": false;
1524
+ };
1525
+ "android-capture-target": {
1526
+ "alias": "android-capture-target";
1527
+ "required": false;
1528
+ };
1529
+ "experimental-update-blur-radius": {
1530
+ "alias": "experimental-update-blur-radius";
1531
+ "required": false;
1532
+ };
1533
+ "blur-effect": {
1534
+ "alias": "blur-effect";
1535
+ "required": false;
1536
+ };
1537
+ "spacing": {
1538
+ "alias": "spacing";
1539
+ "required": false;
1540
+ };
1541
+ "glass-interactive": {
1542
+ "alias": "glass-interactive";
1543
+ "required": false;
1544
+ };
1545
+ "glass-tint-color": {
1546
+ "alias": "glass-tint-color";
1547
+ "required": false;
1548
+ };
1549
+ "glass-style": {
1550
+ "alias": "glass-style";
1551
+ "required": false;
1552
+ };
1553
+ "ios-user-interface-style": {
1554
+ "alias": "ios-user-interface-style";
1555
+ "required": false;
1556
+ };
1557
+ }, {}, never, never, true, never>;
1558
+ }
1559
+ /**
1560
+ * Renders its children above embedded native views such as `<webview>`
1561
+ * (Clay Windows/macOS only). Has no element-specific attributes.
1562
+ */
1563
+ export declare class LynxCoverView extends LynxElementBase {
1564
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxCoverView, never>;
1565
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxCoverView, "cover-view", never, {}, {}, never, never, true, never>;
1566
+ }
1567
+ /**
1568
+ * ControlValueAccessor for <input> elements. Bridges Angular's form model
1569
+ * (reactive forms, template-driven NgModel, Signal Forms [formField]) to Lynx's
1570
+ * native events (bindinput, bindblur) instead of the standard DOM input/change events.
1571
+ *
1572
+ * Activated only when a form directive is present (formControl, formControlName,
1573
+ * ngModel, or formField) — bare <input> elements continue to use LynxInput alone.
1574
+ */
1575
+ export declare class LynxInputValueAccessor implements ControlValueAccessor {
1576
+ #private;
1577
+ onInput(event: Event): void;
1578
+ onBlur(): void;
1579
+ writeValue(value: string): void;
1580
+ registerOnChange(fn: (value: string) => void): void;
1581
+ registerOnTouched(fn: () => void): void;
1582
+ setDisabledState(isDisabled: boolean): void;
1583
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxInputValueAccessor, never>;
1584
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxInputValueAccessor, "input[formControlName],input[formControl],input[ngModel],input[formField]", never, {}, {}, never, never, true, never>;
1585
+ }
1586
+ /**
1587
+ * ControlValueAccessor for <textarea> elements. Bridges Angular's form model
1588
+ * (reactive forms, template-driven NgModel, Signal Forms [formField]) to Lynx's
1589
+ * native events (bindinput, bindblur) instead of the standard DOM input/change events.
1590
+ *
1591
+ * Activated only when a form directive is present (formControl, formControlName,
1592
+ * ngModel, or formField) — bare <textarea> elements continue to use LynxTextarea alone.
1593
+ */
1594
+ export declare class LynxTextareaValueAccessor implements ControlValueAccessor {
1595
+ #private;
1596
+ onInput(event: Event): void;
1597
+ onBlur(): void;
1598
+ writeValue(value: string): void;
1599
+ registerOnChange(fn: (value: string) => void): void;
1600
+ registerOnTouched(fn: () => void): void;
1601
+ setDisabledState(isDisabled: boolean): void;
1602
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTextareaValueAccessor, never>;
1603
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxTextareaValueAccessor, "textarea[formControlName],textarea[formControl],textarea[ngModel],textarea[formField]", never, {}, {}, never, never, true, never>;
1604
+ }
1605
+ /**
1606
+ * Both Lynx form value accessors as a single importable array.
1607
+ */
1608
+ export declare const LYNX_FORM_ACCESSORS: readonly [typeof LynxInputValueAccessor, typeof LynxTextareaValueAccessor];
1609
+ /**
1610
+ * Embeds a separate Lynx bundle as a nested page.
1611
+ */
1612
+ export declare class LynxFrame extends LynxElementBase {
1613
+ /**
1614
+ * URL of the `.lynx.bundle` file to embed.
1615
+ */
1616
+ src?: string;
1617
+ /**
1618
+ * Initial data passed into the embedded page.
1619
+ */
1620
+ data?: Record<string, unknown>;
1621
+ /**
1622
+ * Global props forwarded to the embedded page's global scope.
1623
+ */
1624
+ 'global-props'?: Record<string, unknown>;
1625
+ /**
1626
+ * Size the frame to match its content width.
1627
+ */
1628
+ 'auto-width'?: boolean;
1629
+ /**
1630
+ * Size the frame to match its content height.
1631
+ */
1632
+ 'auto-height'?: boolean;
1633
+ /**
1634
+ * Width used before the embedded page reports its content size (e.g. `'200px'`).
1635
+ */
1636
+ 'preset-width'?: string;
1637
+ /**
1638
+ * Height used before the embedded page reports its content size (e.g. `'200px'`).
1639
+ */
1640
+ 'preset-height'?: string;
1641
+ /**
1642
+ * Override the host's multi-async-thread setting for the embedded page.
1643
+ */
1644
+ 'enable-multi-async-thread'?: boolean;
1645
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxFrame, never>;
1646
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxFrame, "frame", never, {
1647
+ "src": {
1648
+ "alias": "src";
1649
+ "required": false;
1650
+ };
1651
+ "data": {
1652
+ "alias": "data";
1653
+ "required": false;
1654
+ };
1655
+ "global-props": {
1656
+ "alias": "global-props";
1657
+ "required": false;
1658
+ };
1659
+ "auto-width": {
1660
+ "alias": "auto-width";
1661
+ "required": false;
1662
+ };
1663
+ "auto-height": {
1664
+ "alias": "auto-height";
1665
+ "required": false;
1666
+ };
1667
+ "preset-width": {
1668
+ "alias": "preset-width";
1669
+ "required": false;
1670
+ };
1671
+ "preset-height": {
1672
+ "alias": "preset-height";
1673
+ "required": false;
1674
+ };
1675
+ "enable-multi-async-thread": {
1676
+ "alias": "enable-multi-async-thread";
1677
+ "required": false;
1678
+ };
1679
+ }, {}, never, never, true, never>;
1680
+ }
1681
+ /**
1682
+ * Displays raster images, base64 data URIs, and animated GIFs.
1683
+ */
1684
+ export declare class LynxImage extends LynxElementBase {
1685
+ /**
1686
+ * Remote URL, local asset path, or base64 data URI.
1687
+ */
1688
+ src?: string;
1689
+ /**
1690
+ * How the image is scaled to fit its container.
1691
+ * @default 'scaleToFill'
1692
+ */
1693
+ mode?: 'scaleToFill' | 'aspectFit' | 'aspectFill' | 'center';
1694
+ /**
1695
+ * Placeholder image shown while the main image loads.
1696
+ */
1697
+ placeholder?: string;
1698
+ /**
1699
+ * Gaussian blur radius applied to the image.
1700
+ */
1701
+ 'blur-radius'?: string;
1702
+ /**
1703
+ * Nine-slice cap insets for stretching images (CSS shorthand, e.g. "10px 10px 10px 10px").
1704
+ */
1705
+ 'cap-insets'?: string;
1706
+ 'cap-insets-scale'?: number;
1707
+ /**
1708
+ * Automatically size the element to the image's intrinsic dimensions.
1709
+ */
1710
+ 'auto-size'?: boolean;
1711
+ /**
1712
+ * Auto-play for animated GIF images.
1713
+ */
1714
+ autoplay?: boolean;
1715
+ /**
1716
+ * Number of times to loop the animation (0 = infinite).
1717
+ */
1718
+ 'loop-count'?: number;
1719
+ /**
1720
+ * Tint color applied over the image (CSS color string).
1721
+ */
1722
+ 'tint-color'?: string;
1723
+ /**
1724
+ * Bitmap color format hint (Android).
1725
+ */
1726
+ 'image-config'?: 'ARGB_8888' | 'RGB_565';
1727
+ /**
1728
+ * Pre-declared width for prefetch optimization.
1729
+ */
1730
+ 'prefetch-width'?: string;
1731
+ 'prefetch-height'?: string;
1732
+ /**
1733
+ * Keep showing the current image while the new src loads.
1734
+ */
1735
+ 'defer-src-invalidation'?: boolean;
1736
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxImage, never>;
1737
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxImage, "image", never, {
1738
+ "src": {
1739
+ "alias": "src";
1740
+ "required": false;
1741
+ };
1742
+ "mode": {
1743
+ "alias": "mode";
1744
+ "required": false;
1745
+ };
1746
+ "placeholder": {
1747
+ "alias": "placeholder";
1748
+ "required": false;
1749
+ };
1750
+ "blur-radius": {
1751
+ "alias": "blur-radius";
1752
+ "required": false;
1753
+ };
1754
+ "cap-insets": {
1755
+ "alias": "cap-insets";
1756
+ "required": false;
1757
+ };
1758
+ "cap-insets-scale": {
1759
+ "alias": "cap-insets-scale";
1760
+ "required": false;
1761
+ };
1762
+ "auto-size": {
1763
+ "alias": "auto-size";
1764
+ "required": false;
1765
+ };
1766
+ "autoplay": {
1767
+ "alias": "autoplay";
1768
+ "required": false;
1769
+ };
1770
+ "loop-count": {
1771
+ "alias": "loop-count";
1772
+ "required": false;
1773
+ };
1774
+ "tint-color": {
1775
+ "alias": "tint-color";
1776
+ "required": false;
1777
+ };
1778
+ "image-config": {
1779
+ "alias": "image-config";
1780
+ "required": false;
1781
+ };
1782
+ "prefetch-width": {
1783
+ "alias": "prefetch-width";
1784
+ "required": false;
1785
+ };
1786
+ "prefetch-height": {
1787
+ "alias": "prefetch-height";
1788
+ "required": false;
1789
+ };
1790
+ "defer-src-invalidation": {
1791
+ "alias": "defer-src-invalidation";
1792
+ "required": false;
1793
+ };
1794
+ }, {}, never, never, true, never>;
1795
+ }
1796
+ /**
1797
+ * Single-line text input field.
1798
+ */
1799
+ export declare class LynxInput extends LynxElementBase {
1800
+ #private;
1801
+ ngOnChanges(changes: SimpleChanges): void;
1802
+ /**
1803
+ * Keyboard type shown when this input gains focus.
1804
+ */
1805
+ type?: 'text' | 'number' | 'digit' | 'password' | 'tel' | 'email';
1806
+ /**
1807
+ * Greyed-out hint text shown when the field is empty.
1808
+ */
1809
+ placeholder?: string;
1810
+ /**
1811
+ * Current value of the field.
1812
+ */
1813
+ value?: string;
1814
+ /**
1815
+ * Maximum character count (-1 = unlimited).
1816
+ */
1817
+ maxlength?: number;
1818
+ /**
1819
+ * Whether the field is read-only.
1820
+ */
1821
+ readonly?: boolean;
1822
+ /**
1823
+ * Whether the field and keyboard are disabled.
1824
+ */
1825
+ disabled?: boolean;
1826
+ /**
1827
+ * Label for the soft-keyboard confirm button. @default 'done'
1828
+ */
1829
+ 'confirm-type'?: 'search' | 'send' | 'go' | 'done' | 'next';
1830
+ /**
1831
+ * Input character whitelist — a regular expression pattern string.
1832
+ */
1833
+ 'input-filter'?: string;
1834
+ /**
1835
+ * Whether tapping the field shows the soft keyboard. @default true
1836
+ */
1837
+ 'show-soft-input-on-focus'?: boolean;
1838
+ /**
1839
+ * Enable auto-correction on iOS.
1840
+ */
1841
+ 'ios-auto-correct'?: boolean;
1842
+ /**
1843
+ * Enable spell-checking on iOS.
1844
+ */
1845
+ 'ios-spell-check'?: boolean;
1846
+ /**
1847
+ * Enter full-screen editing mode on Android.
1848
+ */
1849
+ 'android-fullscreen-mode'?: boolean;
1850
+ /**
1851
+ * Initial content. Applied on first render only and doesn't fire `bindinput`.
1852
+ * Prefer `value` (or a form control) when the text must stay in sync.
1853
+ */
1854
+ 'default-value'?: string;
1855
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxInput, never>;
1856
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxInput, "input", never, {
1857
+ "type": {
1858
+ "alias": "type";
1859
+ "required": false;
1860
+ };
1861
+ "placeholder": {
1862
+ "alias": "placeholder";
1863
+ "required": false;
1864
+ };
1865
+ "value": {
1866
+ "alias": "value";
1867
+ "required": false;
1868
+ };
1869
+ "maxlength": {
1870
+ "alias": "maxlength";
1871
+ "required": false;
1872
+ };
1873
+ "readonly": {
1874
+ "alias": "readonly";
1875
+ "required": false;
1876
+ };
1877
+ "disabled": {
1878
+ "alias": "disabled";
1879
+ "required": false;
1880
+ };
1881
+ "confirm-type": {
1882
+ "alias": "confirm-type";
1883
+ "required": false;
1884
+ };
1885
+ "input-filter": {
1886
+ "alias": "input-filter";
1887
+ "required": false;
1888
+ };
1889
+ "show-soft-input-on-focus": {
1890
+ "alias": "show-soft-input-on-focus";
1891
+ "required": false;
1892
+ };
1893
+ "ios-auto-correct": {
1894
+ "alias": "ios-auto-correct";
1895
+ "required": false;
1896
+ };
1897
+ "ios-spell-check": {
1898
+ "alias": "ios-spell-check";
1899
+ "required": false;
1900
+ };
1901
+ "android-fullscreen-mode": {
1902
+ "alias": "android-fullscreen-mode";
1903
+ "required": false;
1904
+ };
1905
+ "default-value": {
1906
+ "alias": "default-value";
1907
+ "required": false;
1908
+ };
1909
+ }, {}, never, never, true, never>;
1910
+ }
1911
+ /**
1912
+ * Multi-line text input field.
1913
+ */
1914
+ export declare class LynxTextarea extends LynxElementBase {
1915
+ #private;
1916
+ ngOnChanges(changes: SimpleChanges): void;
1917
+ type?: 'text' | 'number' | 'digit' | 'tel' | 'email';
1918
+ placeholder?: string;
1919
+ value?: string;
1920
+ maxlength?: number;
1921
+ /**
1922
+ * Maximum number of visible lines.
1923
+ */
1924
+ maxlines?: number;
1925
+ /**
1926
+ * Extra spacing between lines in px.
1927
+ */
1928
+ 'line-spacing'?: number;
1929
+ readonly?: boolean;
1930
+ disabled?: boolean;
1931
+ 'confirm-type'?: 'search' | 'send' | 'go' | 'done' | 'next';
1932
+ 'input-filter'?: string;
1933
+ 'show-soft-input-on-focus'?: boolean;
1934
+ bounces?: boolean;
1935
+ 'enable-scroll-bar'?: boolean;
1936
+ 'ios-auto-correct'?: boolean;
1937
+ 'ios-spell-check'?: boolean;
1938
+ 'android-fullscreen-mode'?: boolean;
1939
+ /**
1940
+ * Initial content. Applied on first render only and doesn't fire `bindinput`.
1941
+ * Prefer `value` (or a form control) when the text must stay in sync.
1942
+ */
1943
+ 'default-value'?: string;
1944
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTextarea, never>;
1945
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxTextarea, "textarea", never, {
1946
+ "type": {
1947
+ "alias": "type";
1948
+ "required": false;
1949
+ };
1950
+ "placeholder": {
1951
+ "alias": "placeholder";
1952
+ "required": false;
1953
+ };
1954
+ "value": {
1955
+ "alias": "value";
1956
+ "required": false;
1957
+ };
1958
+ "maxlength": {
1959
+ "alias": "maxlength";
1960
+ "required": false;
1961
+ };
1962
+ "maxlines": {
1963
+ "alias": "maxlines";
1964
+ "required": false;
1965
+ };
1966
+ "line-spacing": {
1967
+ "alias": "line-spacing";
1968
+ "required": false;
1969
+ };
1970
+ "readonly": {
1971
+ "alias": "readonly";
1972
+ "required": false;
1973
+ };
1974
+ "disabled": {
1975
+ "alias": "disabled";
1976
+ "required": false;
1977
+ };
1978
+ "confirm-type": {
1979
+ "alias": "confirm-type";
1980
+ "required": false;
1981
+ };
1982
+ "input-filter": {
1983
+ "alias": "input-filter";
1984
+ "required": false;
1985
+ };
1986
+ "show-soft-input-on-focus": {
1987
+ "alias": "show-soft-input-on-focus";
1988
+ "required": false;
1989
+ };
1990
+ "bounces": {
1991
+ "alias": "bounces";
1992
+ "required": false;
1993
+ };
1994
+ "enable-scroll-bar": {
1995
+ "alias": "enable-scroll-bar";
1996
+ "required": false;
1997
+ };
1998
+ "ios-auto-correct": {
1999
+ "alias": "ios-auto-correct";
2000
+ "required": false;
2001
+ };
2002
+ "ios-spell-check": {
2003
+ "alias": "ios-spell-check";
2004
+ "required": false;
2005
+ };
2006
+ "android-fullscreen-mode": {
2007
+ "alias": "android-fullscreen-mode";
2008
+ "required": false;
2009
+ };
2010
+ "default-value": {
2011
+ "alias": "default-value";
2012
+ "required": false;
2013
+ };
2014
+ }, {}, never, never, true, never>;
2015
+ }
2016
+ /**
2017
+ * High-performance virtualized list, equivalent to RecyclerView / UITableView.
2018
+ *
2019
+ * Gaps between items aren't attributes: `list-main-axis-gap` and
2020
+ * `list-cross-axis-gap` are CSS properties, which Lynx's list reads from its
2021
+ * computed style, so set them in `style` (`[style.list-main-axis-gap]`).
2022
+ */
2023
+ export declare class LynxList extends LynxElementBase {
2024
+ /**
2025
+ * Layout algorithm.
2026
+ * - `'single'` — one item per row/column
2027
+ * - `'flow'` — fixed column count, items fill left-to-right
2028
+ * - `'waterfall'` — Pinterest-style varying-height columns
2029
+ */
2030
+ 'list-type'?: 'single' | 'flow' | 'waterfall';
2031
+ /**
2032
+ * Number of columns (flow/waterfall) or rows (horizontal single).
2033
+ */
2034
+ 'span-count'?: number;
2035
+ /**
2036
+ * Scroll axis. @default 'vertical'
2037
+ */
2038
+ 'scroll-orientation'?: 'vertical' | 'horizontal';
2039
+ 'enable-scroll'?: boolean;
2040
+ 'enable-nested-scroll'?: boolean;
2041
+ bounces?: boolean;
2042
+ sticky?: boolean;
2043
+ /**
2044
+ * Offset in px for sticky items.
2045
+ */
2046
+ 'sticky-offset'?: number;
2047
+ 'scroll-bar-enable'?: boolean;
2048
+ /**
2049
+ * Scroll to this item index on first render.
2050
+ */
2051
+ 'initial-scroll-index'?: number;
2052
+ /**
2053
+ * Number of items from the top that triggers bindscrolltoupper.
2054
+ */
2055
+ 'upper-threshold-item-count'?: number;
2056
+ /**
2057
+ * Number of items from the bottom that triggers bindscrolltolower.
2058
+ */
2059
+ 'lower-threshold-item-count'?: number;
2060
+ /**
2061
+ * Minimum interval in ms between scroll events.
2062
+ */
2063
+ 'scroll-event-throttle'?: number;
2064
+ /**
2065
+ * Include visible item info in scroll event payloads.
2066
+ */
2067
+ 'need-visible-item-info'?: boolean;
2068
+ /**
2069
+ * Include layout completion info in events.
2070
+ */
2071
+ 'need-layout-complete-info'?: boolean;
2072
+ /**
2073
+ * Number of items to preload beyond the visible area.
2074
+ */
2075
+ 'preload-buffer-count'?: number;
2076
+ /**
2077
+ * Snap behavior: `{ factor: 0–1, offset: px }`.
2078
+ */
2079
+ 'item-snap'?: {
2080
+ factor: number;
2081
+ offset: number;
2082
+ };
2083
+ /**
2084
+ * Insert/remove animation style.
2085
+ */
2086
+ 'update-animation'?: 'default' | 'none';
2087
+ /**
2088
+ * Required by Lynx's native list UI whenever the app uses the standard
2089
+ * dual-thread engine strategy (always true for AngularLynx) — without it
2090
+ * the native list silently never applies its data source, so
2091
+ * `componentAtIndex` is never called and no items render. The renderer
2092
+ * sets this to `true` by default at element creation; bind it explicitly
2093
+ * only to opt back into the sync (all-on-UI) engine strategy.
2094
+ * @default true
2095
+ */
2096
+ 'enable-async-list'?: boolean;
2097
+ /**
2098
+ * Insert list-item platform views via the C++ list's operations. Recommended
2099
+ * with multi-thread engine strategies. @default false
2100
+ */
2101
+ 'enable-insert-platform-view-operation'?: boolean;
2102
+ /**
2103
+ * How the list picks a reference anchor when on-screen items are removed:
2104
+ * 0 = none, 1 = toward start, 2 = toward end (experimental). @default 0
2105
+ */
2106
+ 'experimental-search-ref-anchor-strategy'?: 0 | 1 | 2;
2107
+ /**
2108
+ * Allow scrolling when the content is smaller than the list (Harmony). @default false
2109
+ */
2110
+ 'harmony-scroll-edge-effect'?: boolean;
2111
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxList, never>;
2112
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxList, "list", never, {
2113
+ "list-type": {
2114
+ "alias": "list-type";
2115
+ "required": false;
2116
+ };
2117
+ "span-count": {
2118
+ "alias": "span-count";
2119
+ "required": false;
2120
+ };
2121
+ "scroll-orientation": {
2122
+ "alias": "scroll-orientation";
2123
+ "required": false;
2124
+ };
2125
+ "enable-scroll": {
2126
+ "alias": "enable-scroll";
2127
+ "required": false;
2128
+ };
2129
+ "enable-nested-scroll": {
2130
+ "alias": "enable-nested-scroll";
2131
+ "required": false;
2132
+ };
2133
+ "bounces": {
2134
+ "alias": "bounces";
2135
+ "required": false;
2136
+ };
2137
+ "sticky": {
2138
+ "alias": "sticky";
2139
+ "required": false;
2140
+ };
2141
+ "sticky-offset": {
2142
+ "alias": "sticky-offset";
2143
+ "required": false;
2144
+ };
2145
+ "scroll-bar-enable": {
2146
+ "alias": "scroll-bar-enable";
2147
+ "required": false;
2148
+ };
2149
+ "initial-scroll-index": {
2150
+ "alias": "initial-scroll-index";
2151
+ "required": false;
2152
+ };
2153
+ "upper-threshold-item-count": {
2154
+ "alias": "upper-threshold-item-count";
2155
+ "required": false;
2156
+ };
2157
+ "lower-threshold-item-count": {
2158
+ "alias": "lower-threshold-item-count";
2159
+ "required": false;
2160
+ };
2161
+ "scroll-event-throttle": {
2162
+ "alias": "scroll-event-throttle";
2163
+ "required": false;
2164
+ };
2165
+ "need-visible-item-info": {
2166
+ "alias": "need-visible-item-info";
2167
+ "required": false;
2168
+ };
2169
+ "need-layout-complete-info": {
2170
+ "alias": "need-layout-complete-info";
2171
+ "required": false;
2172
+ };
2173
+ "preload-buffer-count": {
2174
+ "alias": "preload-buffer-count";
2175
+ "required": false;
2176
+ };
2177
+ "item-snap": {
2178
+ "alias": "item-snap";
2179
+ "required": false;
2180
+ };
2181
+ "update-animation": {
2182
+ "alias": "update-animation";
2183
+ "required": false;
2184
+ };
2185
+ "enable-async-list": {
2186
+ "alias": "enable-async-list";
2187
+ "required": false;
2188
+ };
2189
+ "enable-insert-platform-view-operation": {
2190
+ "alias": "enable-insert-platform-view-operation";
2191
+ "required": false;
2192
+ };
2193
+ "experimental-search-ref-anchor-strategy": {
2194
+ "alias": "experimental-search-ref-anchor-strategy";
2195
+ "required": false;
2196
+ };
2197
+ "harmony-scroll-edge-effect": {
2198
+ "alias": "harmony-scroll-edge-effect";
2199
+ "required": false;
2200
+ };
2201
+ }, {}, never, never, true, never>;
2202
+ }
2203
+ /**
2204
+ * Child of `<list>`; represents a single virtualized cell.
2205
+ */
2206
+ export declare class LynxListItem extends LynxElementBase {
2207
+ /**
2208
+ * Stable unique key for this item — used for diffing and recycling.
2209
+ * Must be unique within the list.
2210
+ */
2211
+ 'item-key'?: string;
2212
+ /**
2213
+ * Whether this item spans all columns (full-width in flow/waterfall).
2214
+ */
2215
+ 'full-span'?: boolean;
2216
+ /**
2217
+ * Stick this item to the top of the list while scrolling.
2218
+ */
2219
+ 'sticky-top'?: boolean;
2220
+ /**
2221
+ * Stick this item to the bottom of the list while scrolling.
2222
+ */
2223
+ 'sticky-bottom'?: boolean;
2224
+ /**
2225
+ * Whether this item's view can be recycled. @default true
2226
+ */
2227
+ recyclable?: boolean;
2228
+ /**
2229
+ * Reuse pool identifier — items with the same identifier share views.
2230
+ */
2231
+ 'reuse-identifier'?: string;
2232
+ /**
2233
+ * Estimated item size in px for layout pre-calculation.
2234
+ */
2235
+ 'estimated-main-axis-size-px'?: number;
2236
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxListItem, never>;
2237
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxListItem, "list-item", never, {
2238
+ "item-key": {
2239
+ "alias": "item-key";
2240
+ "required": false;
2241
+ };
2242
+ "full-span": {
2243
+ "alias": "full-span";
2244
+ "required": false;
2245
+ };
2246
+ "sticky-top": {
2247
+ "alias": "sticky-top";
2248
+ "required": false;
2249
+ };
2250
+ "sticky-bottom": {
2251
+ "alias": "sticky-bottom";
2252
+ "required": false;
2253
+ };
2254
+ "recyclable": {
2255
+ "alias": "recyclable";
2256
+ "required": false;
2257
+ };
2258
+ "reuse-identifier": {
2259
+ "alias": "reuse-identifier";
2260
+ "required": false;
2261
+ };
2262
+ "estimated-main-axis-size-px": {
2263
+ "alias": "estimated-main-axis-size-px";
2264
+ "required": false;
2265
+ };
2266
+ }, {}, never, never, true, never>;
2267
+ }
2268
+ /**
2269
+ * Anonymous grouping element with no visual output.
2270
+ */
2271
+ export declare class LynxBlock extends LynxElementBase {
2272
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxBlock, never>;
2273
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxBlock, "block", never, {}, {}, never, never, true, never>;
2274
+ }
2275
+ /**
2276
+ * Lynx native conditional element.
2277
+ * Note: Angular's `@if` control flow is a separate, unrelated construct.
2278
+ */
2279
+ export declare class LynxIf extends LynxElementBase {
2280
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxIf, never>;
2281
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxIf, "if", never, {}, {}, never, never, true, never>;
2282
+ }
2283
+ /**
2284
+ * Lynx native iteration element.
2285
+ * Note: Angular's `@for` control flow is a separate, unrelated construct.
2286
+ */
2287
+ export declare class LynxFor extends LynxElementBase {
2288
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxFor, never>;
2289
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxFor, "for", never, {}, {}, never, never, true, never>;
2290
+ }
2291
+ /**
2292
+ * Floating layer rendered above the main document flow.
2293
+ */
2294
+ export declare class LynxOverlay extends LynxElementBase {
2295
+ /**
2296
+ * Whether the overlay is shown.
2297
+ */
2298
+ visible?: boolean;
2299
+ /**
2300
+ * The layer the overlay sits in when several are open: 1 is the top layer
2301
+ * and 4 the lowest. Within a layer the last one shown is on top. Lynx reads
2302
+ * it only while the overlay is hidden. @default 1
2303
+ */
2304
+ level?: 1 | 2 | 3 | 4;
2305
+ /**
2306
+ * Presentation mode on iOS (`'window'` | `'top'` | `'page'`).
2307
+ */
2308
+ mode?: string;
2309
+ /**
2310
+ * Whether the iOS swipe-back gesture dismisses the overlay.
2311
+ */
2312
+ 'ios-enable-swipe-back'?: boolean;
2313
+ /**
2314
+ * Android navigation bar background/appearance while the overlay is shown.
2315
+ * `transparent` also requires `android-adapt-edge-to-edge`. (Lynx 4.1+) @default 'auto'
2316
+ */
2317
+ 'android-navigation-bar-style'?: 'auto' | 'light' | 'dark' | 'transparent';
2318
+ /**
2319
+ * Limit the overlay to the Fragment that owns its LynxView (Android, Lynx 4.3+). @default 'global'
2320
+ */
2321
+ 'android-overlay-scope'?: 'global' | 'fragment';
2322
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxOverlay, never>;
2323
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxOverlay, "overlay", never, {
2324
+ "visible": {
2325
+ "alias": "visible";
2326
+ "required": false;
2327
+ };
2328
+ "level": {
2329
+ "alias": "level";
2330
+ "required": false;
2331
+ };
2332
+ "mode": {
2333
+ "alias": "mode";
2334
+ "required": false;
2335
+ };
2336
+ "ios-enable-swipe-back": {
2337
+ "alias": "ios-enable-swipe-back";
2338
+ "required": false;
2339
+ };
2340
+ "android-navigation-bar-style": {
2341
+ "alias": "android-navigation-bar-style";
2342
+ "required": false;
2343
+ };
2344
+ "android-overlay-scope": {
2345
+ "alias": "android-overlay-scope";
2346
+ "required": false;
2347
+ };
2348
+ }, {}, never, never, true, never>;
2349
+ }
2350
+ /**
2351
+ * Pull-to-refresh container. Accepts `<refresh-header>` and a scrollable `<view>` as direct children.
2352
+ */
2353
+ export declare class LynxRefresh extends LynxElementBase {
2354
+ /**
2355
+ * Whether dragging down or calling autoStartRefresh can trigger the startrefresh event. @default true
2356
+ */
2357
+ 'enable-refresh'?: boolean;
2358
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxRefresh, never>;
2359
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxRefresh, "refresh", never, {
2360
+ "enable-refresh": {
2361
+ "alias": "enable-refresh";
2362
+ "required": false;
2363
+ };
2364
+ }, {}, never, never, true, never>;
2365
+ }
2366
+ /**
2367
+ * Customizable header revealed during a pull-to-refresh gesture. Must be a direct child of `<refresh>`.
2368
+ */
2369
+ export declare class LynxRefreshHeader extends LynxElementBase {
2370
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxRefreshHeader, never>;
2371
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxRefreshHeader, "refresh-header", never, {}, {}, never, never, true, never>;
2372
+ }
2373
+ /**
2374
+ * Nested scroll coordination container. Synchronizes a foldable header, sticky toolbar, and scrollable content slot.
2375
+ */
2376
+ export declare class LynxScrollCoordinator extends LynxElementBase {
2377
+ /**
2378
+ * Whether the coordinator can scroll vertically. @default true
2379
+ */
2380
+ 'enable-scroll'?: boolean;
2381
+ /**
2382
+ * Enable bounce effect when scrolling past boundary (iOS/Harmony). @default true
2383
+ */
2384
+ bounces?: boolean;
2385
+ /**
2386
+ * Event response granularity for bindoffset. @default 0.01
2387
+ */
2388
+ granularity?: number;
2389
+ /**
2390
+ * Whether header appears over slot when overflowing. @default false
2391
+ */
2392
+ 'header-over-slot'?: boolean;
2393
+ /**
2394
+ * Refresh mode: 'none', 'page', or 'fold' (iOS). @default 'none'
2395
+ */
2396
+ 'refresh-mode'?: 'none' | 'page' | 'fold';
2397
+ /**
2398
+ * Show scrollbar during scrolling (iOS/Harmony). @default false
2399
+ */
2400
+ 'enable-scroll-bar'?: boolean;
2401
+ /**
2402
+ * Enable nested scroll as child in other scrolling widgets (Android). @default false
2403
+ */
2404
+ 'android-nested-scroll-as-child'?: boolean;
2405
+ /**
2406
+ * Force nested-vertical-scroll-behavior invalid (iOS). @default false
2407
+ */
2408
+ 'ios-force-scroll-detach'?: boolean;
2409
+ /**
2410
+ * Scroll to top when tapping status bar (iOS). @default false
2411
+ */
2412
+ 'ios-scrolls-to-top'?: boolean;
2413
+ /**
2414
+ * Adjust the offset when the active slot is empty or too short to scroll (Android). @default false
2415
+ */
2416
+ 'android-adapt-to-empty-slot'?: boolean;
2417
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollCoordinator, never>;
2418
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollCoordinator, "scroll-coordinator", never, {
2419
+ "enable-scroll": {
2420
+ "alias": "enable-scroll";
2421
+ "required": false;
2422
+ };
2423
+ "bounces": {
2424
+ "alias": "bounces";
2425
+ "required": false;
2426
+ };
2427
+ "granularity": {
2428
+ "alias": "granularity";
2429
+ "required": false;
2430
+ };
2431
+ "header-over-slot": {
2432
+ "alias": "header-over-slot";
2433
+ "required": false;
2434
+ };
2435
+ "refresh-mode": {
2436
+ "alias": "refresh-mode";
2437
+ "required": false;
2438
+ };
2439
+ "enable-scroll-bar": {
2440
+ "alias": "enable-scroll-bar";
2441
+ "required": false;
2442
+ };
2443
+ "android-nested-scroll-as-child": {
2444
+ "alias": "android-nested-scroll-as-child";
2445
+ "required": false;
2446
+ };
2447
+ "ios-force-scroll-detach": {
2448
+ "alias": "ios-force-scroll-detach";
2449
+ "required": false;
2450
+ };
2451
+ "ios-scrolls-to-top": {
2452
+ "alias": "ios-scrolls-to-top";
2453
+ "required": false;
2454
+ };
2455
+ "android-adapt-to-empty-slot": {
2456
+ "alias": "android-adapt-to-empty-slot";
2457
+ "required": false;
2458
+ };
2459
+ }, {}, never, never, true, never>;
2460
+ }
2461
+ /**
2462
+ * Header content that scrolls out of view. Must be a direct child of `<scroll-coordinator>`.
2463
+ */
2464
+ export declare class LynxScrollCoordinatorHeader extends LynxElementBase {
2465
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollCoordinatorHeader, never>;
2466
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollCoordinatorHeader, "scroll-coordinator-header", never, {}, {}, never, never, true, never>;
2467
+ }
2468
+ /**
2469
+ * Sticky toolbar that remains visible at the top. Must be a direct child of `<scroll-coordinator>`.
2470
+ */
2471
+ export declare class LynxScrollCoordinatorToolbar extends LynxElementBase {
2472
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollCoordinatorToolbar, never>;
2473
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollCoordinatorToolbar, "scroll-coordinator-toolbar", never, {}, {}, never, never, true, never>;
2474
+ }
2475
+ /**
2476
+ * Container for scrollable content (typically a `<list>`). Must be a direct child of `<scroll-coordinator>`.
2477
+ */
2478
+ export declare class LynxScrollCoordinatorSlot extends LynxElementBase {
2479
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollCoordinatorSlot, never>;
2480
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollCoordinatorSlot, "scroll-coordinator-slot", never, {}, {}, never, never, true, never>;
2481
+ }
2482
+ /**
2483
+ * Slot variant whose content can be dragged up/down to fold and unfold the
2484
+ * header. Must be a direct child of `<scroll-coordinator>`.
2485
+ */
2486
+ export declare class LynxScrollCoordinatorSlotDrag extends LynxElementBase {
2487
+ /**
2488
+ * Whether vertical drag gestures fold/unfold the header. @default true
2489
+ */
2490
+ 'enable-drag'?: boolean;
2491
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollCoordinatorSlotDrag, never>;
2492
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollCoordinatorSlotDrag, "scroll-coordinator-slot-drag", never, {
2493
+ "enable-drag": {
2494
+ "alias": "enable-drag";
2495
+ "required": false;
2496
+ };
2497
+ }, {}, never, never, true, never>;
2498
+ }
2499
+ /**
2500
+ * Scrollable single-child container.
2501
+ */
2502
+ export declare class LynxScrollView extends LynxElementBase {
2503
+ /**
2504
+ * Scroll axis. @default 'vertical'
2505
+ */
2506
+ 'scroll-orientation'?: 'vertical' | 'horizontal';
2507
+ /**
2508
+ * Whether scrolling is enabled. @default true
2509
+ */
2510
+ 'enable-scroll'?: boolean;
2511
+ /**
2512
+ * Whether the scroll view bounces past the content edge (iOS/Harmony).
2513
+ */
2514
+ bounces?: boolean;
2515
+ /**
2516
+ * Whether the platform scroll indicator is shown.
2517
+ */
2518
+ 'scroll-bar-enable'?: boolean;
2519
+ /**
2520
+ * Distance from the top/left edge that triggers bindscrolltoupper.
2521
+ */
2522
+ 'upper-threshold'?: number;
2523
+ /**
2524
+ * Distance from the bottom/right edge that triggers bindscrolltolower.
2525
+ */
2526
+ 'lower-threshold'?: number;
2527
+ /**
2528
+ * Initial scroll offset in px.
2529
+ */
2530
+ 'initial-scroll-offset'?: number;
2531
+ /**
2532
+ * Scroll to item at this index on mount.
2533
+ */
2534
+ 'initial-scroll-to-index'?: number;
2535
+ /**
2536
+ * Whether nested scrolling is enabled.
2537
+ */
2538
+ 'enable-nested-scroll'?: boolean;
2539
+ /**
2540
+ * Use the new overflow clipping implementation (Android, Lynx 4.2+, experimental). @default true
2541
+ */
2542
+ 'experimental-android-enable-new-overflow'?: boolean;
2543
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxScrollView, never>;
2544
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxScrollView, "scroll-view", never, {
2545
+ "scroll-orientation": {
2546
+ "alias": "scroll-orientation";
2547
+ "required": false;
2548
+ };
2549
+ "enable-scroll": {
2550
+ "alias": "enable-scroll";
2551
+ "required": false;
2552
+ };
2553
+ "bounces": {
2554
+ "alias": "bounces";
2555
+ "required": false;
2556
+ };
2557
+ "scroll-bar-enable": {
2558
+ "alias": "scroll-bar-enable";
2559
+ "required": false;
2560
+ };
2561
+ "upper-threshold": {
2562
+ "alias": "upper-threshold";
2563
+ "required": false;
2564
+ };
2565
+ "lower-threshold": {
2566
+ "alias": "lower-threshold";
2567
+ "required": false;
2568
+ };
2569
+ "initial-scroll-offset": {
2570
+ "alias": "initial-scroll-offset";
2571
+ "required": false;
2572
+ };
2573
+ "initial-scroll-to-index": {
2574
+ "alias": "initial-scroll-to-index";
2575
+ "required": false;
2576
+ };
2577
+ "enable-nested-scroll": {
2578
+ "alias": "enable-nested-scroll";
2579
+ "required": false;
2580
+ };
2581
+ "experimental-android-enable-new-overflow": {
2582
+ "alias": "experimental-android-enable-new-overflow";
2583
+ "required": false;
2584
+ };
2585
+ }, {}, never, never, true, never>;
2586
+ }
2587
+ /**
2588
+ * Renders SVG content from a URL or an inline XML string.
2589
+ */
2590
+ export declare class LynxSvg extends LynxElementBase {
2591
+ /**
2592
+ * URL pointing to an SVG resource.
2593
+ */
2594
+ src?: string;
2595
+ /**
2596
+ * Inline SVG XML string.
2597
+ */
2598
+ content?: string;
2599
+ /**
2600
+ * Color used for `currentColor` in the SVG. Doesn't override explicit `fill`/`stroke`.
2601
+ */
2602
+ 'current-color'?: string;
2603
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxSvg, never>;
2604
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxSvg, "svg", never, {
2605
+ "src": {
2606
+ "alias": "src";
2607
+ "required": false;
2608
+ };
2609
+ "content": {
2610
+ "alias": "content";
2611
+ "required": false;
2612
+ };
2613
+ "current-color": {
2614
+ "alias": "current-color";
2615
+ "required": false;
2616
+ };
2617
+ }, {}, never, never, true, never>;
2618
+ }
2619
+ /**
2620
+ * Displays text content. Supports inline child `<text>` elements for mixed styling.
2621
+ */
2622
+ export declare class LynxText extends LynxElementBase {
2623
+ /**
2624
+ * Maximum number of lines the text is laid out in. The text box ends after
2625
+ * that many lines, but the ellipsis needs `text-overflow: ellipsis`
2626
+ * (Tailwind's `text-ellipsis`). Without it, iOS cuts the text off at the
2627
+ * last line, and Android draws the remaining lines past the box.
2628
+ */
2629
+ 'text-maxline'?: number;
2630
+ /**
2631
+ * Vertical alignment for single-line text.
2632
+ * @default 'normal'
2633
+ */
2634
+ 'text-single-line-vertical-align'?: 'normal' | 'top' | 'center' | 'bottom';
2635
+ /**
2636
+ * Whether the user can select the text.
2637
+ */
2638
+ 'text-selection'?: boolean;
2639
+ /**
2640
+ * Whether a custom context menu is shown on long-press.
2641
+ */
2642
+ 'custom-context-menu'?: boolean;
2643
+ /**
2644
+ * Add extra font padding on Android.
2645
+ */
2646
+ 'include-font-padding'?: boolean;
2647
+ 'tail-color-convert'?: boolean;
2648
+ /**
2649
+ * Synthesize bold when the font has no bold face (Android/iOS). @default false
2650
+ */
2651
+ 'text-fake-bold'?: boolean;
2652
+ /**
2653
+ * Hand selection/copy gestures to your own handlers; requires `text-selection`. @default false
2654
+ */
2655
+ 'custom-text-selection'?: boolean;
2656
+ /**
2657
+ * Render emoji with the Emoji2 compatibility library (Android; the app must include it). @default false
2658
+ */
2659
+ 'android-emoji-compat'?: boolean;
2660
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxText, never>;
2661
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxText, "text", never, {
2662
+ "text-maxline": {
2663
+ "alias": "text-maxline";
2664
+ "required": false;
2665
+ };
2666
+ "text-single-line-vertical-align": {
2667
+ "alias": "text-single-line-vertical-align";
2668
+ "required": false;
2669
+ };
2670
+ "text-selection": {
2671
+ "alias": "text-selection";
2672
+ "required": false;
2673
+ };
2674
+ "custom-context-menu": {
2675
+ "alias": "custom-context-menu";
2676
+ "required": false;
2677
+ };
2678
+ "include-font-padding": {
2679
+ "alias": "include-font-padding";
2680
+ "required": false;
2681
+ };
2682
+ "tail-color-convert": {
2683
+ "alias": "tail-color-convert";
2684
+ "required": false;
2685
+ };
2686
+ "text-fake-bold": {
2687
+ "alias": "text-fake-bold";
2688
+ "required": false;
2689
+ };
2690
+ "custom-text-selection": {
2691
+ "alias": "custom-text-selection";
2692
+ "required": false;
2693
+ };
2694
+ "android-emoji-compat": {
2695
+ "alias": "android-emoji-compat";
2696
+ "required": false;
2697
+ };
2698
+ }, {}, never, never, true, never>;
2699
+ }
2700
+ /**
2701
+ * Custom content shown at the end of a `<text>` in place of the ellipsis when
2702
+ * the text is truncated by `text-maxline`. Must be a direct child of `<text>`.
2703
+ */
2704
+ export declare class LynxInlineTruncation extends LynxElementBase {
2705
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxInlineTruncation, never>;
2706
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxInlineTruncation, "inline-truncation", never, {}, {}, never, never, true, never>;
2707
+ }
2708
+ /**
2709
+ * Draggable region of a custom window title bar, like CSS `app-region: drag`
2710
+ * (Clay Windows/macOS only).
2711
+ */
2712
+ export declare class LynxTitleBarView extends LynxElementBase {
2713
+ /**
2714
+ * Whether dragging this region moves the window. @default false
2715
+ */
2716
+ moveable?: boolean;
2717
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTitleBarView, never>;
2718
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxTitleBarView, "title-bar-view", never, {
2719
+ "moveable": {
2720
+ "alias": "moveable";
2721
+ "required": false;
2722
+ };
2723
+ }, {}, never, never, true, never>;
2724
+ }
2725
+ /**
2726
+ * Native video player (experimental, Lynx 4.1+). Control playback with the
2727
+ * `play` / `pause` / `stop` / `seek` UI methods via SelectorQuery.
2728
+ */
2729
+ export declare class LynxVideo extends LynxElementBase {
2730
+ /**
2731
+ * Video URL. Only online network URLs are supported.
2732
+ */
2733
+ src?: string;
2734
+ /**
2735
+ * Whether playback loops. @default false
2736
+ */
2737
+ loop?: boolean;
2738
+ /**
2739
+ * Playback volume from 0 to 1. @default 1
2740
+ */
2741
+ volume?: number;
2742
+ /**
2743
+ * Whether audio is muted. @default false
2744
+ */
2745
+ muted?: boolean;
2746
+ /**
2747
+ * Playback rate from 0.1 to 2.0. @default 1
2748
+ */
2749
+ speed?: number;
2750
+ /**
2751
+ * How the video is scaled into the element box. @default 'contain'
2752
+ */
2753
+ 'object-fit'?: 'contain' | 'cover' | 'fill';
2754
+ /**
2755
+ * How queued UI method calls are executed. @default 'queue'
2756
+ */
2757
+ mode?: 'queue' | 'direct' | 'latest';
2758
+ /**
2759
+ * Minimum interval between `bindtimeupdate` events, in seconds. @default 0.33
2760
+ */
2761
+ 'timeupdate-interval'?: number;
2762
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxVideo, never>;
2763
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxVideo, "video", never, {
2764
+ "src": {
2765
+ "alias": "src";
2766
+ "required": false;
2767
+ };
2768
+ "loop": {
2769
+ "alias": "loop";
2770
+ "required": false;
2771
+ };
2772
+ "volume": {
2773
+ "alias": "volume";
2774
+ "required": false;
2775
+ };
2776
+ "muted": {
2777
+ "alias": "muted";
2778
+ "required": false;
2779
+ };
2780
+ "speed": {
2781
+ "alias": "speed";
2782
+ "required": false;
2783
+ };
2784
+ "object-fit": {
2785
+ "alias": "object-fit";
2786
+ "required": false;
2787
+ };
2788
+ "mode": {
2789
+ "alias": "mode";
2790
+ "required": false;
2791
+ };
2792
+ "timeupdate-interval": {
2793
+ "alias": "timeupdate-interval";
2794
+ "required": false;
2795
+ };
2796
+ }, {}, never, never, true, never>;
2797
+ }
2798
+ /**
2799
+ * General-purpose container element, equivalent to HTML `<div>`. Its
2800
+ * attributes (`flatten`, the pan-intercept ones, …) work on every element, so
2801
+ * they live on {@link LynxElementBase}.
2802
+ */
2803
+ export declare class LynxView extends LynxElementBase {
2804
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxView, never>;
2805
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxView, "view", never, {}, {}, never, never, true, never>;
2806
+ }
2807
+ /**
2808
+ * Horizontally swipeable paging container.
2809
+ */
2810
+ export declare class LynxViewPager extends LynxElementBase {
2811
+ /**
2812
+ * Page index to display on first render. @default 0
2813
+ */
2814
+ 'initial-select-index'?: number;
2815
+ /**
2816
+ * Whether horizontal scroll gesture is enabled. @default true
2817
+ */
2818
+ 'enable-scroll'?: boolean;
2819
+ /**
2820
+ * Whether the pager bounces past edge (iOS/Harmony/Clay). @default true
2821
+ */
2822
+ bounces?: boolean;
2823
+ /**
2824
+ * Enable bounce effect at edges on Android. @default false
2825
+ */
2826
+ 'android-always-overscroll'?: boolean;
2827
+ /**
2828
+ * Block gesture pass-through to parent on Android. @default false
2829
+ */
2830
+ 'android-force-can-scroll'?: boolean;
2831
+ /**
2832
+ * Allow outer container swipe at edges (iOS). @default false
2833
+ */
2834
+ 'ios-gesture-direction'?: boolean;
2835
+ /**
2836
+ * Left edge exclusion zone for swipe gesture (iOS, px). @default 0
2837
+ */
2838
+ 'ios-gesture-offset'?: number;
2839
+ /**
2840
+ * UIGestureRecognizer class name for simultaneous recognition (iOS).
2841
+ */
2842
+ 'ios-recognized-gesture-class'?: string;
2843
+ /**
2844
+ * UIView tag for simultaneous gesture recognition (iOS). @default 0
2845
+ */
2846
+ 'ios-recognized-view-tag'?: number;
2847
+ /**
2848
+ * Enable lazy load mode with early exposure. @default false
2849
+ */
2850
+ 'keep-item-view'?: boolean;
2851
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxViewPager, never>;
2852
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxViewPager, "viewpager", never, {
2853
+ "initial-select-index": {
2854
+ "alias": "initial-select-index";
2855
+ "required": false;
2856
+ };
2857
+ "enable-scroll": {
2858
+ "alias": "enable-scroll";
2859
+ "required": false;
2860
+ };
2861
+ "bounces": {
2862
+ "alias": "bounces";
2863
+ "required": false;
2864
+ };
2865
+ "android-always-overscroll": {
2866
+ "alias": "android-always-overscroll";
2867
+ "required": false;
2868
+ };
2869
+ "android-force-can-scroll": {
2870
+ "alias": "android-force-can-scroll";
2871
+ "required": false;
2872
+ };
2873
+ "ios-gesture-direction": {
2874
+ "alias": "ios-gesture-direction";
2875
+ "required": false;
2876
+ };
2877
+ "ios-gesture-offset": {
2878
+ "alias": "ios-gesture-offset";
2879
+ "required": false;
2880
+ };
2881
+ "ios-recognized-gesture-class": {
2882
+ "alias": "ios-recognized-gesture-class";
2883
+ "required": false;
2884
+ };
2885
+ "ios-recognized-view-tag": {
2886
+ "alias": "ios-recognized-view-tag";
2887
+ "required": false;
2888
+ };
2889
+ "keep-item-view": {
2890
+ "alias": "keep-item-view";
2891
+ "required": false;
2892
+ };
2893
+ }, {}, never, never, true, never>;
2894
+ }
2895
+ /**
2896
+ * Single page container inside a viewpager.
2897
+ */
2898
+ export declare class LynxViewPagerItem extends LynxElementBase {
2899
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxViewPagerItem, never>;
2900
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxViewPagerItem, "viewpager-item", never, {}, {}, never, never, true, never>;
2901
+ }
2902
+ /**
2903
+ * Native web view that loads a URL or an inline HTML string. Use `<frame>`
2904
+ * instead to embed another Lynx bundle.
2905
+ */
2906
+ export declare class LynxWebView extends LynxElementBase {
2907
+ /**
2908
+ * URL to load. Changing it reloads the page.
2909
+ */
2910
+ src?: string;
2911
+ /**
2912
+ * Inline HTML to load. Ignored when `src` is set.
2913
+ */
2914
+ html?: string;
2915
+ /**
2916
+ * Enable the bounce effect (iOS). @default false
2917
+ */
2918
+ bounces?: boolean;
2919
+ /**
2920
+ * Show the scroll bar (iOS). @default false
2921
+ */
2922
+ 'scroll-bar-enable'?: boolean;
2923
+ /**
2924
+ * Params forwarded to a custom web view implementation (Android/iOS).
2925
+ */
2926
+ params?: Record<string, unknown>;
2927
+ /**
2928
+ * Which web view implementation (injected via LynxService) to use. @default 'default'
2929
+ */
2930
+ 'webview-type'?: string;
2931
+ /**
2932
+ * Allow remote debugging (Chrome DevTools / Safari Web Inspector). @default false
2933
+ */
2934
+ 'enable-debug'?: boolean;
2935
+ /**
2936
+ * JavaScript executed when the document is ready (Clay desktop).
2937
+ */
2938
+ initjs?: string;
2939
+ /**
2940
+ * Cookies preset before loading (Clay).
2941
+ */
2942
+ cookies?: {
2943
+ name: string;
2944
+ value: string;
2945
+ domain?: string;
2946
+ path?: string;
2947
+ secure?: boolean;
2948
+ httpOnly?: boolean;
2949
+ sameSite: string;
2950
+ }[];
2951
+ /**
2952
+ * Render off-screen (Clay). @default false
2953
+ */
2954
+ 'use-osr'?: boolean;
2955
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxWebView, never>;
2956
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxWebView, "webview", never, {
2957
+ "src": {
2958
+ "alias": "src";
2959
+ "required": false;
2960
+ };
2961
+ "html": {
2962
+ "alias": "html";
2963
+ "required": false;
2964
+ };
2965
+ "bounces": {
2966
+ "alias": "bounces";
2967
+ "required": false;
2968
+ };
2969
+ "scroll-bar-enable": {
2970
+ "alias": "scroll-bar-enable";
2971
+ "required": false;
2972
+ };
2973
+ "params": {
2974
+ "alias": "params";
2975
+ "required": false;
2976
+ };
2977
+ "webview-type": {
2978
+ "alias": "webview-type";
2979
+ "required": false;
2980
+ };
2981
+ "enable-debug": {
2982
+ "alias": "enable-debug";
2983
+ "required": false;
2984
+ };
2985
+ "initjs": {
2986
+ "alias": "initjs";
2987
+ "required": false;
2988
+ };
2989
+ "cookies": {
2990
+ "alias": "cookies";
2991
+ "required": false;
2992
+ };
2993
+ "use-osr": {
2994
+ "alias": "use-osr";
2995
+ "required": false;
2996
+ };
2997
+ }, {}, never, never, true, never>;
2998
+ }
2999
+ /**
3000
+ * All Lynx native element directives as a single importable array.
3001
+ * Add to the `imports` of any component whose template uses Lynx elements.
3002
+ */
3003
+ export declare const LYNX_ELEMENTS: readonly [typeof LynxView, typeof LynxText, typeof LynxInlineTruncation, typeof LynxImage, typeof LynxScrollView, typeof LynxList, typeof LynxListItem, typeof LynxBlock, typeof LynxIf, typeof LynxFor, typeof LynxFrame, typeof LynxInput, typeof LynxTextarea, typeof LynxInputValueAccessor, typeof LynxTextareaValueAccessor, typeof LynxOverlay, typeof LynxRefresh, typeof LynxRefreshHeader, typeof LynxScrollCoordinator, typeof LynxScrollCoordinatorHeader, typeof LynxScrollCoordinatorSlot, typeof LynxScrollCoordinatorSlotDrag, typeof LynxScrollCoordinatorToolbar, typeof LynxSvg, typeof LynxViewPager, typeof LynxViewPagerItem, typeof LynxBlurView, typeof LynxVideo, typeof LynxWebView, typeof LynxCoverView, typeof LynxTitleBarView];
3004
+ export declare class LynxLogger {
3005
+ #private;
3006
+ log(...args: unknown[]): void;
3007
+ warn(...args: unknown[]): void;
3008
+ error(...args: unknown[]): void;
3009
+ info(...args: unknown[]): void;
3010
+ debug(...args: unknown[]): void;
3011
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxLogger, never>;
3012
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3013
+ }
3014
+ /**
3015
+ * Extensible map of custom native modules declared by the host app.
3016
+ *
3017
+ * App developers augment this interface to get type-safe access
3018
+ * via {@link LynxNativeModule.getNativeModule}. Describe each module's
3019
+ * methods as the host implements them; `getNativeModule()` turns their
3020
+ * return values into promises (see {@link NativeModuleProxy}):
3021
+ *
3022
+ * ```typescript
3023
+ * // This export makes the file a module, so the block below adds to
3024
+ * // @blotch/angular-lynx's types instead of replacing them.
3025
+ * export {};
3026
+ *
3027
+ * declare module '@blotch/angular-lynx' {
3028
+ * interface NativeModuleMap {
3029
+ * NativeLocalStorageModule: {
3030
+ * setStorageItem(key: string, value: string): void;
3031
+ * getStorageItem(key: string, callback: (value: string) => void): void;
3032
+ * clearStorage(): void;
3033
+ * };
3034
+ * }
3035
+ * }
3036
+ * ```
3037
+ */
3038
+ interface NativeModuleMap {}
3039
+ /**
3040
+ * A native module as {@link LynxNativeModule.getNativeModule} returns it on
3041
+ * the main thread, where Angular runs.
3042
+ *
3043
+ * Native modules exist only on the background thread, so each method call is
3044
+ * relayed there: the method returns a promise of its result (copied as JSON),
3045
+ * and function arguments are called back on the main thread. Only methods
3046
+ * cross; other properties of the module aren't reachable.
3047
+ */
3048
+ type NativeModuleProxy<T> = { [K in keyof T as T[K] extends ((...args: any[]) => unknown) ? K : never]: T[K] extends ((...args: infer A) => infer R) ? (...args: A) => Promise<Awaited<R>> : never; };
3049
+ /**
3050
+ * Wraps the Lynx native module bridge and JS module registry as an Angular injectable.
3051
+ *
3052
+ * **Native modules** (`NativeModules` global) let JS code call native platform
3053
+ * functions (iOS / Android / HarmonyOS). The host app registers modules on the
3054
+ * native side; this service provides typed access from Angular.
3055
+ *
3056
+ * **JS modules** (`lynx.getJSModule` / `lynx.registerModule`) share JavaScript
3057
+ * values within a single LynxView. This is the same API used internally by
3058
+ * `LynxInitData` and `LynxGlobalData` (via `GlobalEventEmitter`).
3059
+ *
3060
+ * Lynx provides both only on the background thread, while Angular runs on the
3061
+ * main thread. So on the main thread every method goes through the background
3062
+ * call relay (background-call.ts): calls run on the background thread, their
3063
+ * results and callbacks come back as JSON, and a module is a proxy whose
3064
+ * methods return promises.
3065
+ *
3066
+ * @usageNotes
3067
+ * ```typescript
3068
+ * const modules = inject(LynxNativeModule);
3069
+ *
3070
+ * // Call a native method (Promise-based wrapper over bridge.call)
3071
+ * const result = await modules.call<string>('getDeviceId', {});
3072
+ *
3073
+ * // Listen for native events
3074
+ * modules.on('onDeepLink', (url) => console.log(url));
3075
+ *
3076
+ * // Access a typed custom native module
3077
+ * const storage = modules.getNativeModule('NativeLocalStorageModule');
3078
+ * storage?.setStorageItem('key', 'value');
3079
+ *
3080
+ * // JS module sharing within the LynxView
3081
+ * modules.registerJSModule('mySharedState', { count: 0 });
3082
+ * const state = modules.getJSModule<{ count: number }>('mySharedState');
3083
+ * ```
3084
+ */
3085
+ export declare class LynxNativeModule {
3086
+ #private;
3087
+ /**
3088
+ * Calls a native method via `NativeModules.bridge.call()`.
3089
+ *
3090
+ * The native callback API is wrapped in a Promise for ergonomic
3091
+ * use with `async`/`await`.
3092
+ *
3093
+ * Resolves `undefined` when there is no bridge (web preview, tests).
3094
+ */
3095
+ call<T = unknown>(name: string, params?: Record<string, unknown>): Promise<T | undefined>;
3096
+ /**
3097
+ * Subscribes to a native event via `NativeModules.bridge.on()`. From the
3098
+ * main thread, the callback gets the event's arguments copied as JSON.
3099
+ *
3100
+ * No-op when there is no bridge.
3101
+ */
3102
+ on(name: string, callback: (...args: unknown[]) => void): void;
3103
+ /**
3104
+ * Retrieves a custom native module by name from the `NativeModules` global.
3105
+ *
3106
+ * Augment the {@link NativeModuleMap} interface for type-safe access:
3107
+ *
3108
+ * ```typescript
3109
+ * export {};
3110
+ *
3111
+ * declare module '@blotch/angular-lynx' {
3112
+ * interface NativeModuleMap {
3113
+ * NativeLocalStorageModule: { ... };
3114
+ * }
3115
+ * }
3116
+ *
3117
+ * const storage = modules.getNativeModule('NativeLocalStorageModule');
3118
+ * ```
3119
+ *
3120
+ * On the main thread, which can't reach native modules, it returns a proxy:
3121
+ * each method call runs on the background thread and returns a promise of
3122
+ * its result, and a call to a module or method the host doesn't have
3123
+ * rejects. The return type says so: a module in {@link NativeModuleMap}
3124
+ * comes back as a {@link NativeModuleProxy} of it, and any other name as
3125
+ * `unknown`.
3126
+ *
3127
+ * Returns `undefined` outside Lynx, or on the background thread when the
3128
+ * module is not registered.
3129
+ */
3130
+ getNativeModule<K extends string>(name: K): K extends keyof NativeModuleMap ? NativeModuleProxy<NativeModuleMap[K]> | undefined : unknown;
3131
+ /**
3132
+ * Retrieves a JS module registered within this LynxView.
3133
+ *
3134
+ * This wraps `lynx.getJSModule()` — the same API used internally
3135
+ * for `GlobalEventEmitter`. On the main thread it returns a proxy, as
3136
+ * getNativeModule() does.
3137
+ *
3138
+ * Returns `undefined` when `lynx` is unavailable or, on the background
3139
+ * thread, when the module is not registered.
3140
+ */
3141
+ getJSModule<T = unknown>(name: string): T | undefined;
3142
+ /**
3143
+ * Registers a JS module for sharing within this LynxView.
3144
+ *
3145
+ * Other code (including native callbacks) can retrieve it via
3146
+ * `getJSModule()` or `lynx.getJSModule()`. From the main thread, the
3147
+ * background thread registers a copy whose methods call this module's, with
3148
+ * their arguments copied as JSON and their return values dropped.
3149
+ *
3150
+ * No-op when `lynx` is unavailable.
3151
+ */
3152
+ registerJSModule<T extends object>(name: string, module: T): void;
3153
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxNativeModule, never>;
3154
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3155
+ }
3156
+ type LynxEventType = 'bindEvent' | 'catchEvent' | 'capture-bindEvent' | 'capture-catchEvent' | 'global-bindEvent';
3157
+ declare const EVENT_PREFIXES: [string, LynxEventType][];
3158
+ type BaseLynxElement = Pick<Element$1, 'setAttribute'> & {
3159
+ tagName: string;
3160
+ setProperty(name: string, value: any): void;
3161
+ getAttribute(name: string): string | null;
3162
+ removeAttribute(name: string): void;
3163
+ setStyle(key: string, value: unknown): void;
3164
+ removeStyle(key: string): void;
3165
+ setInlineStyles(inlineStyle: string): void;
3166
+ insertBefore(newChild: BaseLynxElement, refChild: BaseLynxElement | null): void;
3167
+ appendChild(newChild: BaseLynxElement): void;
3168
+ addClass(name: string): void;
3169
+ /**
3170
+ * Adds a class that stays when the whole class list is replaced, for
3171
+ * ViewEncapsulation.Emulated's scope classes (see EmulatedLynxRenderer).
3172
+ */
3173
+ addScopeClass(name: string): void;
3174
+ removeClass(name: string): void;
3175
+ remove(): void;
3176
+ parentNode(): BaseLynxElement | null;
3177
+ nextSibling(): BaseLynxElement | null;
3178
+ querySelector(selector: string): BaseLynxElement | null;
3179
+ querySelectorAll(selector: string): BaseLynxElement[];
3180
+ addEventListener(name: string, cb: (event: any) => any): () => void;
3181
+ animate(keyframes: Record<string, string | number>[], options?: number | LynxAnimationOptions): BaseLynxAnimation;
3182
+ /**
3183
+ * Invokes a native UI method on this element (e.g. setValue, scrollTo).
3184
+ * LynxElement implements it via __InvokeUIMethod.
3185
+ */
3186
+ invoke(methodName: string, params?: Record<string, unknown>): void;
3187
+ };
3188
+ declare class LynxElement implements BaseLynxElement {
3189
+ #private;
3190
+ get element(): ElementRef;
3191
+ tagName: string;
3192
+ /**
3193
+ * When true, this element is the root page element and must not be
3194
+ * re-parented (appendChild/insertBefore) or removed from the tree.
3195
+ * Angular calls appendChild/remove as part of normal component lifecycle,
3196
+ * but the page element is the immutable root — moving or removing it
3197
+ * would corrupt the native element tree.
3198
+ */
3199
+ isRootPageElement: boolean;
3200
+ /**
3201
+ * Virtual tree tracking — used when parent manages children outside the
3202
+ * native element tree (e.g., list manages children via componentAtIndex
3203
+ * callbacks rather than __AppendElement)
3204
+ */
3205
+ _virtualParent: LynxElement | null;
3206
+ _virtualPrev: LynxElement | null;
3207
+ _virtualNext: LynxElement | null;
3208
+ constructor(element: ElementRef);
3209
+ /**
3210
+ * Drops this wrapper's current native id from the registry. Called when the
3211
+ * native ref is swapped (recreate-on-remount) for the STALE id, and by the
3212
+ * renderer's destroyNode when Angular tears the element down, so the registry
3213
+ * doesn't retain wrappers for dead native refs.
3214
+ */
3215
+ deregisterNative(): void;
3216
+ setProperty(name: string, value: any): void;
3217
+ /**
3218
+ * Seeds the cached text for a raw-text element so #recreateSubtree() can
3219
+ * rebuild it via __CreateRawText. Called by LynxDocument right after
3220
+ * construction — raw-text bakes its text in at creation, so it never flows
3221
+ * through a cached setter.
3222
+ */
3223
+ setInitialText(text: string): void;
3224
+ setAttribute(name: string, value: any): void;
3225
+ /**
3226
+ * On Android, gives a blur-view the CSS variables that approximate its iOS
3227
+ * material (see android-blur-material). LynxDocument calls it when it
3228
+ * creates one, and setAttribute whenever an attribute it depends on changes.
3229
+ */
3230
+ updateBlurMaterial(): void;
3231
+ getAttribute(name: string): string;
3232
+ removeAttribute(name: string): void;
3233
+ setStyle(key: string, value: unknown): void;
3234
+ removeStyle(key: string): void;
3235
+ setInlineStyles(inlineStyle: string): void;
3236
+ insertBefore(newChild: LynxElement, refChild: LynxElement | null): void;
3237
+ appendChild(newChild: LynxElement): void;
3238
+ addClass(name: string): void;
3239
+ addScopeClass(name: string): void;
3240
+ /**
3241
+ * Lynx has no __RemoveClass PAPI — we must get current classes, filter,
3242
+ * and set back. This is O(n) per class removal but class lists on Lynx
3243
+ * elements are typically small (1-5 classes for scope/component styling).
3244
+ */
3245
+ removeClass(name: string): void;
3246
+ /**
3247
+ * Requests removal of this element. Two removal paths:
3248
+ * 1. Virtual parent (list) → delegate to removeVirtualChild() SYNCHRONOUSLY,
3249
+ * which updates the JS linked list and schedules an update-list-info diff.
3250
+ * Does NOT call __RemoveElement — list item removal is managed exclusively
3251
+ * through update-list-info's removeAction (calling both would double-remove
3252
+ * and crash). This is never part of an Angular move, so it is not deferred.
3253
+ * 2. Normal parent → QUEUED and committed at the end of the change-detection
3254
+ * cycle (see #pendingRemovals / commitPendingRemovals). If a re-insert
3255
+ * follows in the same cycle it is a move and gets canceled; otherwise
3256
+ * #doRemove() detaches from the native tree.
3257
+ */
3258
+ remove(): void;
3259
+ /**
3260
+ * Commits every queued genuine removal. Called by `LynxRendererFactory2.end()`
3261
+ * once per change-detection cycle, BEFORE `__FlushElementTree()`, so the
3262
+ * `__RemoveElement` calls are committed to the main thread in the same flush as
3263
+ * the cycle's other mutations (see #pendingRemovals for why the timing
3264
+ * matters). Any element that was re-inserted (a move) has already removed
3265
+ * itself from the set via #cancelPendingRemoval, so only genuine destroys
3266
+ * remain.
3267
+ */
3268
+ static commitPendingRemovals(): void;
3269
+ /**
3270
+ * Re-derives displayed whitespace for every text touched this cycle. Each dirty
3271
+ * node is resolved to the OUTERMOST enclosing <text>: a nested <text> is inline
3272
+ * — it shares one inline-formatting-context with the surrounding raw-text, like
3273
+ * an HTML <span> — so the whole subtree is trimmed as a single run of text.
3274
+ * Called by `processPendingTextNormalization()` from `end()` /
3275
+ * `scheduleSettleFlush`, after removals and before the flush.
3276
+ */
3277
+ static commitPendingTextNormalization(): void;
3278
+ /**
3279
+ * Returns the parent element. For list children, the virtual parent (the JS
3280
+ * LynxListElement) is returned instead of the native parent — this maintains
3281
+ * the illusion that list children are parented by the list even though they
3282
+ * may not be __AppendElement'd to the native list yet (lazy append in
3283
+ * componentAtIndex).
3284
+ */
3285
+ parentNode(): LynxElement | null;
3286
+ nextSibling(): LynxElement | null;
3287
+ querySelector(selector: string): LynxElement | null;
3288
+ querySelectorAll(selector: string): LynxElement[];
3289
+ /**
3290
+ * Invokes a native UI method on this element by name.
3291
+ *
3292
+ * This is needed because some Lynx native elements expose behavior only
3293
+ * through UIMethod calls and have no corresponding @LynxProp handler. The
3294
+ * most common case is input/textarea text updates: the native
3295
+ * LynxUIBaseInput class has no @LynxProp for "value", so __SetAttribute
3296
+ * is a no-op for changing the displayed text after user interaction. The
3297
+ * setValue UIMethod is the only way to programmatically update the live
3298
+ * text.
3299
+ *
3300
+ * The result callback is intentionally empty. Callers that need a result
3301
+ * (e.g. getValue, boundingClientRect) should use MainThreadElement.invoke(),
3302
+ * which returns a Promise. This method covers fire-and-forget cases like
3303
+ * setValue where only the side-effect matters.
3304
+ */
3305
+ invoke(methodName: string, params?: Record<string, unknown>): void;
3306
+ animate(keyframes: Record<string, string | number>[], options?: number | LynxAnimationOptions): LynxAnimation;
3307
+ /**
3308
+ * Angular's renderer.listen() calls this with event names like 'bindtap',
3309
+ * 'catchtouchstart', 'bindscroll', etc. We strip the Lynx event prefix
3310
+ * (bind/catch/capture-bind/capture-catch) to extract the native event name
3311
+ * and determine the event type for __AddEvent.
3312
+ * Events that don't match any prefix (e.g. DOM-style 'click') are silently
3313
+ * ignored — Lynx has no equivalent event system for arbitrary names.
3314
+ */
3315
+ addEventListener(name: string, cb: (event: any) => any): () => void;
3316
+ }
3317
+ /**
3318
+ * Commits all queued genuine element removals — a free-function wrapper over
3319
+ * `LynxElement.commitPendingRemovals()` so `LynxRendererFactory2.end()` can
3320
+ * drain them (via the lynx-element barrel) right before `__FlushElementTree()`,
3321
+ * keeping removals in the same flush as the cycle's other mutations.
3322
+ */
3323
+ declare const processPendingRemovals: () => void;
3324
+ /**
3325
+ * Re-derives positional edge whitespace for every text touched this cycle — a
3326
+ * free-function wrapper over `LynxElement.commitPendingTextNormalization()` so
3327
+ * `LynxRendererFactory2.end()` can drain it (via the lynx-element barrel) right
3328
+ * after removals and before `__FlushElementTree()`, keeping the corrected text in
3329
+ * the same flush as the cycle's other mutations. See #pendingTextNormalization.
3330
+ */
3331
+ declare const processPendingTextNormalization: () => void;
3332
+ /**
3333
+ * Safety-net flush for native mutations made OUTSIDE a begin()/end() change-
3334
+ * detection cycle. `LynxRendererFactory2.end()` calls `__FlushElementTree()`
3335
+ * once per CD tick, which is what commits (lays out + paints) the cycle's
3336
+ * element mutations. But a lazy-loaded route component is instantiated by
3337
+ * `RouterOutlet` DURING navigation — outside any such cycle — so its freshly
3338
+ * created elements land in the fiber tree yet are never flushed. On-device
3339
+ * symptom: the route's static shell renders, but its `@if`/`@for`/interpolation
3340
+ * content stays invisible until an unrelated CD (e.g. a tap) triggers the next
3341
+ * end() flush. (Bootstrap sidesteps this via native's implicit post-renderPage
3342
+ * flush.) This mirrors the `<list>` path's own guard for the exact same case —
3343
+ * see `LynxListElement.#scheduleUpdate`.
3344
+ *
3345
+ * Called from `LynxDocument`'s element creators, which only run on the main
3346
+ * thread (Angular doesn't run on the background thread), so no thread guard is
3347
+ * needed here. It schedules ONE
3348
+ * coalesced microtask (matching the list guard's `queueMicrotask`, not
3349
+ * `setTimeout` — flushing from a macrotask crashes the native engine), and is a
3350
+ * no-op while:
3351
+ * - inside a CD cycle — end() will flush;
3352
+ * - the first render is pending — native flushes after renderPage, and any
3353
+ * `<list>` defers its own first flush (see isFirstRenderPending()).
3354
+ * The near-no-op cost when nothing is layout-dirty (the core's `need_layout_`
3355
+ * gate) keeps the steady-state overhead negligible.
3356
+ */
3357
+ declare const scheduleSettleFlush: () => void;
3358
+ /**
3359
+ * Process all pending list updates. Called from LynxRendererFactory2.end()
3360
+ * before __FlushElementTree() so list updates are flushed as part of the
3361
+ * normal Angular CD cycle — never from setTimeout (which crashes native).
3362
+ */
3363
+ declare const processPendingListUpdates: () => void;
3364
+ declare class LynxListElement extends LynxElement {
3365
+ #private;
3366
+ /**
3367
+ * Store the list callbacks so _processUpdate() can re-register them via
3368
+ * __UpdateListCallbacks on every update. React Lynx does this on every
3369
+ * flush (see listUpdateInfo.ts) — the native engine (unlike the web
3370
+ * polyfill) does not invoke componentAtIndex for a fresh update-list-info
3371
+ * unless the callbacks are re-registered alongside it. Without this,
3372
+ * update-list-info is accepted with no crash but componentAtIndex is
3373
+ * silently never called and the list stays blank.
3374
+ */
3375
+ setCallbacks(componentAtIndex: (...args: any[]) => number | undefined, enqueueComponent: (...args: any[]) => void, componentAtIndexes: (...args: any[]) => void): void;
3376
+ remove(): void;
3377
+ appendChild(newChild: LynxElement): void;
3378
+ insertBefore(newChild: LynxElement, refChild: LynxElement | null): void;
3379
+ removeVirtualChild(child: LynxElement): void;
3380
+ /**
3381
+ * Returns ElementRefs of real UI children, excluding NoneElement comment
3382
+ * markers — the invisible <view>s LynxDocument.createComment() creates as
3383
+ * Angular's @for/@if insertion anchors, each tagged tagName === 'comment'.
3384
+ *
3385
+ * Filters on the wrapper's `tagName` (a plain JS string on the LynxElement
3386
+ * object), NOT a WeakSet keyed by the native ElementRef. This is the fix for
3387
+ * the crash-to-home-screen on every list add/remove. The previous
3388
+ * implementation did `#nonElements.has(child.element)`, and hashing a
3389
+ * native-backed element ref in a WeakSet/Map/Set on the main-thread Lepus
3390
+ * context aborts the process — js_map_has → map_find_record → js_strict_eq2
3391
+ * → __JS_FreeValueRT (a QuickJS refcount assertion). _processUpdate() calls
3392
+ * this on every list update, so it detonated as soon as items changed.
3393
+ * (The initial render happened to survive it — the abort is refcount-timing
3394
+ * sensitive — which is why it looked fine until the first mutation.) Reading
3395
+ * a string property off the JS wrapper touches no FFI object and no Map/Set,
3396
+ * so it can never trip it. See create-list-element.ts's componentAtIndex doc
3397
+ * for the general "never key a Set/Map on an element ref" constraint.
3398
+ */
3399
+ getUIChildren(): ElementRef[];
3400
+ /**
3401
+ * The UI children list as of the last _processUpdate() call, pre-filtered
3402
+ * and cached — for componentAtIndex/componentAtIndexes (create-list-element.ts)
3403
+ * to read via plain array indexing. See their call sites' doc comments:
3404
+ * native invokes them synchronously, reentrantly, from deep inside its own
3405
+ * list layout pass, and calling ANY WeakSet/Map method (even a single
3406
+ * `.has()`) from within that reentrant call was observed to crash the
3407
+ * Lepus QuickJS context with a refcounting assertion inside
3408
+ * __JS_FreeValueRT, every time, regardless of how shallow the surrounding
3409
+ * call stack is (confirmed via a genuinely fresh setTimeout-scheduled
3410
+ * invocation that still crashed identically) — so getUIChildren() (which
3411
+ * calls WeakSet.has() per child) must never run from that call path.
3412
+ */
3413
+ getCommittedUIChildren(): ElementRef[];
3414
+ /**
3415
+ * Appended-state is tracked as a plain property directly on the ElementRef
3416
+ * rather than a WeakSet, for the same reason as getCommittedUIChildren():
3417
+ * these are called from componentAtIndex, where WeakSet/Map methods crash.
3418
+ * A plain property get/set compiles to ordinary field access, not a call
3419
+ * into QuickJS's Map/Set native implementation.
3420
+ */
3421
+ isAppendedToNativeList(child: ElementRef): boolean;
3422
+ markAppendedToNativeList(child: ElementRef): void;
3423
+ /**
3424
+ * Compute a diff against the last committed children and send update-list-info.
3425
+ * Called from processPendingListUpdates() — NOT directly.
3426
+ * __FlushElementTree() is called afterwards by the renderer factory.
3427
+ *
3428
+ * Positions in insertAction are indices in the NEW child array.
3429
+ * Positions in removeAction are indices in the OLD (committed) child array.
3430
+ * This matches the React Lynx ListUpdateInfoRecording format.
3431
+ */
3432
+ _processUpdate(): void;
3433
+ }
3434
+ /**
3435
+ * Configuration for creating a portal overlay.
3436
+ */
3437
+ type PortalConfig = {
3438
+ /**
3439
+ * The overlay's layer, from 1 (the top) to 4 (the lowest), as on
3440
+ * `<overlay>`. Lynx's default is 1.
3441
+ */
3442
+ level?: 1 | 2 | 3 | 4;
3443
+ /**
3444
+ * Custom injector for the component's dependency injection context.
3445
+ */
3446
+ injector?: EnvironmentInjector;
3447
+ /**
3448
+ * Initial input values to set on the component after creation.
3449
+ */
3450
+ inputs?: Record<string, unknown>;
3451
+ };
3452
+ /**
3453
+ * Handle for managing a portal instance created by {@link LynxPortal}.
3454
+ *
3455
+ * Call {@link destroy} to tear down the overlay and its content.
3456
+ */
3457
+ export declare class PortalRef<T> {
3458
+ #private;
3459
+ /**
3460
+ * @internal
3461
+ */
3462
+ constructor(overlay: BaseLynxElement, appRef: ApplicationRef, componentRef: ComponentRef<T> | null, viewRef: EmbeddedViewRef<unknown> | null);
3463
+ /**
3464
+ * The component instance. `null` for template portals.
3465
+ */
3466
+ get instance(): T | null;
3467
+ /**
3468
+ * Sets a component input. Only works for component portals.
3469
+ */
3470
+ setInput(name: string, value: unknown): void;
3471
+ /**
3472
+ * Tears down the portal: destroys the component/template view,
3473
+ * detaches from change detection, and removes the native overlay element.
3474
+ */
3475
+ destroy(): void;
3476
+ }
3477
+ /**
3478
+ * Programmatically renders Angular components or templates inside a native
3479
+ * Lynx `<overlay>` element — the equivalent of Angular CDK's
3480
+ * `Overlay` / `DomPortalOutlet`.
3481
+ *
3482
+ * For **declarative** overlays, use `<overlay>` directly in your template.
3483
+ * This service is for **imperative** cases: modal dialogs, toast notifications,
3484
+ * or any content that needs to be created from code rather than a template.
3485
+ *
3486
+ * @usageNotes
3487
+ * ```typescript
3488
+ * const portal = inject(LynxPortal);
3489
+ *
3490
+ * // Open a component in an overlay
3491
+ * const ref = portal.open(ConfirmDialogComponent, {
3492
+ * level: 2,
3493
+ * inputs: { title: 'Delete item?' },
3494
+ * });
3495
+ *
3496
+ * // Update inputs later
3497
+ * ref.setInput('title', 'Are you sure?');
3498
+ *
3499
+ * // Tear down when done
3500
+ * ref.destroy();
3501
+ *
3502
+ * // Open a template in an overlay
3503
+ * const tplRef = portal.openTemplate(myTemplateRef, { level: 1 });
3504
+ * tplRef.destroy();
3505
+ * ```
3506
+ */
3507
+ export declare class LynxPortal {
3508
+ #private;
3509
+ /**
3510
+ * Creates a native `<overlay>` and renders the given component into it.
3511
+ *
3512
+ * The component participates in Angular change detection and is fully
3513
+ * functional (inputs, outputs, dependency injection, lifecycle hooks).
3514
+ */
3515
+ open<T>(component: Type<T>, config?: PortalConfig): PortalRef<T>;
3516
+ /**
3517
+ * * Creates a native `<overlay>` and renders the given template into it.
3518
+ * *
3519
+ * * Use this when you have a `TemplateRef` (from `@ViewChild` or a
3520
+ * * template variable) rather than a component class.
3521
+ * v8 ignore start -- reaching this path requires a real Angular component render that produces a live TemplateRef; the mocked LYNX_DOCUMENT in the spec doesn't drive one, and viewChild.required doesn't resolve without an appRef flush. Coverage is provided by the on-device examples that use openTemplate.
3522
+ */
3523
+ openTemplate<C>(template: TemplateRef<C>, config?: PortalConfig & {
3524
+ context?: C;
3525
+ }): PortalRef<null>;
3526
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxPortal, never>;
3527
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3528
+ }
3529
+ /**
3530
+ * Type definition for main-thread function handles used by {@link mainThreadFn}.
3531
+ */
3532
+ type MainThreadFnHandle<TArgs extends unknown[] = unknown[], TReturn = unknown> = {
3533
+ readonly _wkltId: string;
3534
+ readonly _workletType: 'main-thread';
3535
+ readonly __isMainThreadFn: true;
3536
+ readonly __args?: TArgs;
3537
+ readonly __return?: TReturn;
3538
+ };
3539
+ export declare const mainThreadFn: <TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn) => MainThreadFnHandle<TArgs, TReturn>;
3540
+ /**
3541
+ * Type definition for background function handles used by {@link backgroundFn}.
3542
+ */
3543
+ type BackgroundFnHandle<TArgs extends unknown[] = unknown[], TReturn = unknown> = {
3544
+ readonly _wkltId: string;
3545
+ readonly _workletType: 'background';
3546
+ readonly __isBackgroundFn: true;
3547
+ readonly __args?: TArgs;
3548
+ readonly __return?: TReturn;
3549
+ };
3550
+ /**
3551
+ * Registers `fn` on the background thread and returns a handle that
3552
+ * `runOnBackground()` calls it with from the main thread.
3553
+ *
3554
+ * @param fn - The function to run on the background thread.
3555
+ * @param id - Set by the build for a module-level call, so the handle has the
3556
+ * same ID on both threads. Don't pass it yourself.
3557
+ * @returns The handle.
3558
+ */
3559
+ export declare const backgroundFn: <TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn, id?: string) => BackgroundFnHandle<TArgs, TReturn>;
3560
+ export declare class MainThreadRef<T> {
3561
+ #private;
3562
+ readonly _wvid: number | string;
3563
+ /**
3564
+ * @param initValue - The ref's starting value.
3565
+ * @param id - Set by the build for a ref created at module level, so the
3566
+ * ref has the same ID on both threads. Don't pass it yourself.
3567
+ */
3568
+ constructor(initValue: T, id?: string);
3569
+ get current(): T;
3570
+ set current(value: T);
3571
+ /**
3572
+ * Serialization hook for cross-thread transfer. JSON.stringify calls this
3573
+ * when the ref is passed as a param to dispatchEvent (MTS/background RPC).
3574
+ * The receiving thread resolves { _wvid } back to its own registered
3575
+ * MainThreadRef instance.
3576
+ */
3577
+ toJSON(): {
3578
+ _wvid: number | string;
3579
+ };
3580
+ }
3581
+ /**
3582
+ * Creates a {@link MainThreadRef}.
3583
+ *
3584
+ * @param initValue - The ref's starting value.
3585
+ * @param id - Set by the build for a ref created at module level. Don't pass
3586
+ * it yourself.
3587
+ * @returns The new ref.
3588
+ */
3589
+ export declare const createMainThreadRef: <T>(initValue: T, id?: string) => MainThreadRef<T>;
3590
+ declare namespace MainThread {
3591
+ /**
3592
+ * An element's layout box, from `getBoundingClientRect()`, in pixels.
3593
+ */
3594
+ type BoundingClientRect = {
3595
+ left: number;
3596
+ top: number;
3597
+ right: number;
3598
+ bottom: number;
3599
+ width: number;
3600
+ height: number;
3601
+ };
3602
+ /**
3603
+ * Lynx's main-thread element, plus the `getBoundingClientRect()` that
3604
+ * AngularLynx's MainThreadElement adds. The events below are Lynx's, built on
3605
+ * this element type, so `event.currentTarget.getBoundingClientRect()` type
3606
+ * checks without a cast.
3607
+ */
3608
+ type Element = Element$1 & {
3609
+ getBoundingClientRect(options?: {
3610
+ relativeTo?: string;
3611
+ }): Promise<BoundingClientRect>;
3612
+ };
3613
+ type TouchEvent = BaseTouchEvent<Element>;
3614
+ type MouseEvent = BaseMouseEvent<Element>;
3615
+ type WheelEvent = BaseWheelEvent<Element>;
3616
+ type KeyEvent = BaseKeyEvent<Element>;
3617
+ type AnimationEvent = BaseAnimationEvent<Element>;
3618
+ type TransitionEvent = BaseTransitionEvent<Element>;
3619
+ type LayoutChangeEvent = LayoutChangeDetailEvent<Element>;
3620
+ type UIAppearanceEvent = UIAppearanceDetailEvent<Element>;
3621
+ }
3622
+ /**
3623
+ * Wraps a native ElementRef (elementRefptr) with the @lynx-js/types
3624
+ * MainThread.Element API surface. Created by runWorklet's param transformation
3625
+ * so that main-thread event handlers can call setStyleProperty(), setAttribute(),
3626
+ * etc. on event.currentTarget.
3627
+ */
3628
+ export declare class MainThreadElement {
3629
+ #private;
3630
+ constructor(element: ElementRef);
3631
+ setAttribute(name: string, value: unknown): void;
3632
+ getAttribute(name: string): unknown;
3633
+ getAttributeNames(): string[];
3634
+ setStyleProperty(name: string, value: string): void;
3635
+ setStyleProperties(styles: Record<string, string>): void;
3636
+ querySelector(selector: string): MainThreadElement | null;
3637
+ querySelectorAll(selector: string): MainThreadElement[];
3638
+ /**
3639
+ * Invokes a native UI method on this element (e.g. scrollTo, autoPlay).
3640
+ * __InvokeUIMethod is asynchronous — the result arrives in the callback.
3641
+ * scheduleFlush() must be called AFTER __InvokeUIMethod so the method
3642
+ * invocation is included in the next native render pass.
3643
+ */
3644
+ invoke(methodName: string, params?: Record<string, unknown>): Promise<unknown>;
3645
+ animate(keyframes: Record<string, number | string>[], options?: number | LynxAnimationOptions): LynxAnimation;
3646
+ /**
3647
+ * Measures the element's layout box, by default from the top-left corner of
3648
+ * the LynxView. `relativeTo` takes 'screen', or another element's `id`.
3649
+ *
3650
+ * Not part of the official @lynx-js/types Element interface, but useful for
3651
+ * touch tracking. Unlike the DOM's, it's asynchronous: native Lynx gives a
3652
+ * main-thread script the layout position only through the
3653
+ * `boundingClientRect` UI method. The computed `left` and `top` styles are
3654
+ * CSS offsets, often 0, not where the element is.
3655
+ */
3656
+ getBoundingClientRect(options?: {
3657
+ relativeTo?: string;
3658
+ }): Promise<MainThread.BoundingClientRect>;
3659
+ }
3660
+ /**
3661
+ * Plain functions are also accepted: the worklet build plugin turns one with
3662
+ * the 'main thread' directive into a MainThreadFnHandle at compile time, so
3663
+ * TypeScript only sees the function, and the directive registers any other
3664
+ * function itself.
3665
+ */
3666
+ type MaybeHandle = MainThreadFnHandle | ((...args: any[]) => any) | undefined | null;
3667
+ /**
3668
+ * Bridges Angular template bindings like `(mainThreadBindtap)="handler"` to
3669
+ * Lynx's main-thread (Lepus) event dispatch.
3670
+ *
3671
+ * Why a dedicated directive and not the renderer's listen() path:
3672
+ * - Normal `(bindtap)` handlers run on the main thread too (listen() registers
3673
+ * them as worklets), but each one goes through Angular's listener wrapper,
3674
+ * which marks the view for change detection on every dispatch: too much for
3675
+ * gesture-driven UI (scroll-tracking, drag, pinch) that mutates styles at
3676
+ * native frame rate. Their event's targets are also plain data.
3677
+ * - The `mainThreadBind*` / `mainThreadCatch*` family registers the function
3678
+ * itself as a *worklet* with `_workletType: 'main-thread'`, so Lynx invokes
3679
+ * it directly, and runWorklet hands it MainThreadElement targets, whose
3680
+ * __AddInlineStyle / __SetAttribute calls are synchronous. Angular does no
3681
+ * work per event.
3682
+ * - These inputs cannot be expressed as @Output() because Angular would route
3683
+ * them through its own event subscription system and the underlying
3684
+ * worklet handle would never be passed to __AddEvent.
3685
+ *
3686
+ * The worklet plugin (in rsbuild-plugin-angular-lynx) rewrites any function
3687
+ * annotated with `'main thread'` directive into a `MainThreadFnHandle`
3688
+ * carrying a stable `_wkltId`. That ID is what we hand to __AddEvent here.
3689
+ */
3690
+ export declare class LynxMainThreadEvent implements OnChanges, OnDestroy {
3691
+ #private;
3692
+ mainThreadBindtap?: MaybeHandle;
3693
+ mainThreadCatchtap?: MaybeHandle;
3694
+ mainThreadBindtouchstart?: MaybeHandle;
3695
+ mainThreadCatchtouchstart?: MaybeHandle;
3696
+ mainThreadBindtouchmove?: MaybeHandle;
3697
+ mainThreadCatchtouchmove?: MaybeHandle;
3698
+ mainThreadBindtouchend?: MaybeHandle;
3699
+ mainThreadCatchtouchend?: MaybeHandle;
3700
+ mainThreadBindmousedown?: MaybeHandle;
3701
+ mainThreadCatchmousedown?: MaybeHandle;
3702
+ mainThreadBindmousemove?: MaybeHandle;
3703
+ mainThreadCatchmousemove?: MaybeHandle;
3704
+ mainThreadBindmouseup?: MaybeHandle;
3705
+ mainThreadCatchmouseup?: MaybeHandle;
3706
+ mainThreadBindlongpress?: MaybeHandle;
3707
+ mainThreadCatchlongpress?: MaybeHandle;
3708
+ mainThreadBindscroll?: MaybeHandle;
3709
+ mainThreadCatchscroll?: MaybeHandle;
3710
+ mainThreadBindanimationstart?: MaybeHandle;
3711
+ mainThreadBindanimationend?: MaybeHandle;
3712
+ mainThreadBindtransitionend?: MaybeHandle;
3713
+ mainThreadBindlayoutchange?: MaybeHandle;
3714
+ ngOnChanges(changes: SimpleChanges): void;
3715
+ ngOnDestroy(): void;
3716
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxMainThreadEvent, never>;
3717
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxMainThreadEvent, "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindmousedown],[mainThreadCatchmousedown],[mainThreadBindmousemove],[mainThreadCatchmousemove],[mainThreadBindmouseup],[mainThreadCatchmouseup],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]", never, {
3718
+ "mainThreadBindtap": {
3719
+ "alias": "mainThreadBindtap";
3720
+ "required": false;
3721
+ };
3722
+ "mainThreadCatchtap": {
3723
+ "alias": "mainThreadCatchtap";
3724
+ "required": false;
3725
+ };
3726
+ "mainThreadBindtouchstart": {
3727
+ "alias": "mainThreadBindtouchstart";
3728
+ "required": false;
3729
+ };
3730
+ "mainThreadCatchtouchstart": {
3731
+ "alias": "mainThreadCatchtouchstart";
3732
+ "required": false;
3733
+ };
3734
+ "mainThreadBindtouchmove": {
3735
+ "alias": "mainThreadBindtouchmove";
3736
+ "required": false;
3737
+ };
3738
+ "mainThreadCatchtouchmove": {
3739
+ "alias": "mainThreadCatchtouchmove";
3740
+ "required": false;
3741
+ };
3742
+ "mainThreadBindtouchend": {
3743
+ "alias": "mainThreadBindtouchend";
3744
+ "required": false;
3745
+ };
3746
+ "mainThreadCatchtouchend": {
3747
+ "alias": "mainThreadCatchtouchend";
3748
+ "required": false;
3749
+ };
3750
+ "mainThreadBindmousedown": {
3751
+ "alias": "mainThreadBindmousedown";
3752
+ "required": false;
3753
+ };
3754
+ "mainThreadCatchmousedown": {
3755
+ "alias": "mainThreadCatchmousedown";
3756
+ "required": false;
3757
+ };
3758
+ "mainThreadBindmousemove": {
3759
+ "alias": "mainThreadBindmousemove";
3760
+ "required": false;
3761
+ };
3762
+ "mainThreadCatchmousemove": {
3763
+ "alias": "mainThreadCatchmousemove";
3764
+ "required": false;
3765
+ };
3766
+ "mainThreadBindmouseup": {
3767
+ "alias": "mainThreadBindmouseup";
3768
+ "required": false;
3769
+ };
3770
+ "mainThreadCatchmouseup": {
3771
+ "alias": "mainThreadCatchmouseup";
3772
+ "required": false;
3773
+ };
3774
+ "mainThreadBindlongpress": {
3775
+ "alias": "mainThreadBindlongpress";
3776
+ "required": false;
3777
+ };
3778
+ "mainThreadCatchlongpress": {
3779
+ "alias": "mainThreadCatchlongpress";
3780
+ "required": false;
3781
+ };
3782
+ "mainThreadBindscroll": {
3783
+ "alias": "mainThreadBindscroll";
3784
+ "required": false;
3785
+ };
3786
+ "mainThreadCatchscroll": {
3787
+ "alias": "mainThreadCatchscroll";
3788
+ "required": false;
3789
+ };
3790
+ "mainThreadBindanimationstart": {
3791
+ "alias": "mainThreadBindanimationstart";
3792
+ "required": false;
3793
+ };
3794
+ "mainThreadBindanimationend": {
3795
+ "alias": "mainThreadBindanimationend";
3796
+ "required": false;
3797
+ };
3798
+ "mainThreadBindtransitionend": {
3799
+ "alias": "mainThreadBindtransitionend";
3800
+ "required": false;
3801
+ };
3802
+ "mainThreadBindlayoutchange": {
3803
+ "alias": "mainThreadBindlayoutchange";
3804
+ "required": false;
3805
+ };
3806
+ }, {}, never, never, true, never>;
3807
+ }
3808
+ /**
3809
+ * Injectable service for calling main-thread (Lepus) functions from Angular
3810
+ * code, and getting their return values.
3811
+ *
3812
+ * Angular runs on the main thread only (see bootstrapApplication), so the
3813
+ * call never crosses threads: it invokes the registered worklet in place,
3814
+ * with the arguments as they are, and resolves with its result. Non-
3815
+ * serializable values (element handles, MainThreadRefs) pass through intact.
3816
+ *
3817
+ * It used to send the call across threads when it ran on the background
3818
+ * thread, for the copy of the app that booted there too. That copy is gone
3819
+ * (issue #81), and with it the background-to-main call channel.
3820
+ */
3821
+ export declare class LynxMainThread {
3822
+ runOnMainThread<TArgs extends unknown[], TReturn>(handle: MainThreadFnHandle<TArgs, TReturn>, ...args: TArgs): Promise<TReturn>;
3823
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxMainThread, never>;
3824
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3825
+ }
3826
+ /**
3827
+ * Resource priority hint for the native prefetch engine.
3828
+ */
3829
+ type PrefetchPriority = 'high' | 'medium' | 'low';
3830
+ /**
3831
+ * Cache destination for a prefetched resource.
3832
+ * - `'disk'` — persists across app sessions (larger resources)
3833
+ * - `'bitmap'` — decoded into memory for immediate display (images)
3834
+ */
3835
+ type PrefetchCacheTarget = 'disk' | 'bitmap';
3836
+ /**
3837
+ * Describes a single resource to prefetch.
3838
+ */
3839
+ type PrefetchRequest = {
3840
+ /**
3841
+ * URL of the resource to prefetch.
3842
+ */
3843
+ uri: string;
3844
+ /**
3845
+ * Resource type — determines the native prefetch pipeline.
3846
+ */
3847
+ type: 'image' | 'video';
3848
+ /**
3849
+ * Optional priority hint (default determined by native engine).
3850
+ */
3851
+ priority?: PrefetchPriority;
3852
+ /**
3853
+ * Where to cache the prefetched resource.
3854
+ */
3855
+ cacheTarget?: PrefetchCacheTarget;
3856
+ /**
3857
+ * Custom cache key for manual cache management.
3858
+ */
3859
+ preloadKey?: string;
3860
+ /**
3861
+ * Expected resource size in bytes (helps native allocate buffers).
3862
+ */
3863
+ size?: number;
3864
+ };
3865
+ /**
3866
+ * Per-resource result from a prefetch or cancel operation.
3867
+ */
3868
+ type PrefetchResultDetail = {
3869
+ code: number;
3870
+ msg: string;
3871
+ uri: string;
3872
+ type: 'image' | 'video';
3873
+ };
3874
+ /**
3875
+ * Wraps `lynx.requestResourcePrefetch()` and `lynx.cancelResourcePrefetch()`
3876
+ * with a Promise-based API for preloading images and videos into the native
3877
+ * cache before they're needed for display.
3878
+ *
3879
+ * Lynx has these APIs only on the background thread, while Angular runs on
3880
+ * the main thread, so the calls go through the background call relay
3881
+ * (background-call.ts).
3882
+ *
3883
+ * @usageNotes
3884
+ * ```typescript
3885
+ * const prefetch = inject(LynxResourcePrefetch);
3886
+ *
3887
+ * // Prefetch a single image
3888
+ * const result = await prefetch.request([
3889
+ * { uri: 'https://cdn.example.com/hero.jpg', type: 'image' },
3890
+ * ]);
3891
+ *
3892
+ * // Prefetch multiple resources with priority
3893
+ * await prefetch.request([
3894
+ * { uri: 'https://cdn.example.com/hero.jpg', type: 'image', priority: 'high' },
3895
+ * { uri: 'https://cdn.example.com/promo.mp4', type: 'video', priority: 'low' },
3896
+ * ]);
3897
+ *
3898
+ * // Cancel an in-flight prefetch
3899
+ * await prefetch.cancel([
3900
+ * { uri: 'https://cdn.example.com/promo.mp4', type: 'video' },
3901
+ * ]);
3902
+ * ```
3903
+ */
3904
+ export declare class LynxResourcePrefetch {
3905
+ #private;
3906
+ /**
3907
+ * Request prefetching of one or more resources into the native cache.
3908
+ * Resolves when the native engine acknowledges the request (not necessarily
3909
+ * when the download completes).
3910
+ */
3911
+ request(resources: PrefetchRequest[]): Promise<ResourcePrefetchResult>;
3912
+ /**
3913
+ * Cancel in-flight prefetch requests for the specified resources.
3914
+ * Useful when navigating away before prefetched content is needed.
3915
+ */
3916
+ cancel(resources: PrefetchRequest[]): Promise<ResourcePrefetchResult>;
3917
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxResourcePrefetch, never>;
3918
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3919
+ }
3920
+ /**
3921
+ * CSS `env()` value for the top safe area inset (notch / status bar).
3922
+ */
3923
+ export declare const SAFE_AREA_INSET_TOP = "env(safe-area-inset-top)";
3924
+ /**
3925
+ * CSS `env()` value for the bottom safe area inset (home indicator).
3926
+ */
3927
+ export declare const SAFE_AREA_INSET_BOTTOM = "env(safe-area-inset-bottom)";
3928
+ /**
3929
+ * CSS `env()` value for the left safe area inset.
3930
+ */
3931
+ export declare const SAFE_AREA_INSET_LEFT = "env(safe-area-inset-left)";
3932
+ /**
3933
+ * CSS `env()` value for the right safe area inset.
3934
+ */
3935
+ export declare const SAFE_AREA_INSET_RIGHT = "env(safe-area-inset-right)";
3936
+ /**
3937
+ * Provides device adaptation helpers for notch/safe-area-aware layouts.
3938
+ *
3939
+ * Safe area insets in Lynx are applied via CSS `env(safe-area-inset-*)`,
3940
+ * identical to the web platform. This service exposes the `isNotchScreen`
3941
+ * flag from the native host as a reactive signal for conditional logic.
3942
+ *
3943
+ * @usageNotes
3944
+ *
3945
+ * ### CSS approach (preferred)
3946
+ * ```css
3947
+ * .container {
3948
+ * padding-top: env(safe-area-inset-top);
3949
+ * padding-bottom: env(safe-area-inset-bottom);
3950
+ * }
3951
+ * ```
3952
+ *
3953
+ * ### Conditional logic in TypeScript
3954
+ * ```typescript
3955
+ * const safeArea = inject(LynxSafeArea);
3956
+ *
3957
+ * if (safeArea.isNotchScreen()) {
3958
+ * // Adjust layout for notch devices
3959
+ * }
3960
+ * ```
3961
+ */
3962
+ export declare class LynxSafeArea {
3963
+ #private;
3964
+ /**
3965
+ * Whether the device has a display notch or cutout. Reactive — updates when global props change.
3966
+ */
3967
+ readonly isNotchScreen: import("@angular/core").Signal<boolean>;
3968
+ /**
3969
+ * The current platform (`'iOS'`, `'Android'`, `'Harmony'`, etc.).
3970
+ */
3971
+ get platform(): import("@lynx-js/types").PlatformType;
3972
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxSafeArea, never>;
3973
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3974
+ }
3975
+ /**
3976
+ * Tracks an active session storage subscription so it can be cleaned up.
3977
+ */
3978
+ type SessionStorageSubscription = {
3979
+ readonly key: string;
3980
+ readonly listenerId: number;
3981
+ };
3982
+ /**
3983
+ * Wraps Lynx's session storage API for sharing data across multiple LynxViews.
3984
+ *
3985
+ * Session storage is a key-value store that persists for the lifetime of the
3986
+ * host app session. Unlike browser localStorage, values are objects (not strings)
3987
+ * and reads are asynchronous (callback-based in the native API, Promise-based here).
3988
+ *
3989
+ * The `setSessionStorageItem` / `getSessionStorageItem` / `subscribeSessionStorage` /
3990
+ * `unsubscribeSessionStorage` methods are not declared in `@lynx-js/types`, so we
3991
+ * access them via `any` — the APIs are stable and documented on lynxjs.org.
3992
+ *
3993
+ * The native surface differs by thread, and AngularLynx bootstraps the same
3994
+ * component tree on both (see runtime.ts), so this service must detect which
3995
+ * thread it's on rather than assume one shape everywhere:
3996
+ * - Background thread: `getSessionStorageItem(key, callback)` is async, plus
3997
+ * `subscribeSessionStorage`/`unsubscribeSessionStorage` for pub/sub.
3998
+ * - Main thread (Lepus engine, see `Utils::CreateLynx` in lynx core): only
3999
+ * `setSessionStorageItem`/`getSessionStorageItem` are registered — no
4000
+ * subscribe/unsubscribe at all — and `getSessionStorageItem` is
4001
+ * *synchronous*, taking just the key and returning the value directly.
4002
+ * Calling it with a callback (the background-thread shape) throws a native
4003
+ * "GetSessionStorageItem param size should be 1" fatal error. Subscriptions
4004
+ * made there go through the background thread (see background-call.ts).
4005
+ *
4006
+ * @usageNotes
4007
+ * ```typescript
4008
+ * const sessionStorage = inject(LynxSessionStorage);
4009
+ *
4010
+ * // Write
4011
+ * sessionStorage.setItem('theme', { mode: 'dark' });
4012
+ *
4013
+ * // One-shot read
4014
+ * const theme = await sessionStorage.getItem<{ mode: string }>('theme');
4015
+ *
4016
+ * // Reactive signal (auto-subscribes, auto-cleans up with injection context)
4017
+ * const theme = sessionStorage.watch<{ mode: string }>('theme');
4018
+ * // theme() updates whenever another LynxView calls setItem('theme', ...)
4019
+ * ```
4020
+ */
4021
+ export declare class LynxSessionStorage {
4022
+ #private;
4023
+ /**
4024
+ * Stores a value in session storage, shared across all LynxViews.
4025
+ * Existing subscribers for this key will be notified of the change.
4026
+ *
4027
+ * Two main-thread quirks are handled here, both discovered as on-device
4028
+ * crashes/bugs in the session-storage example:
4029
+ *
4030
+ * 1. **Values must be objects.** The main thread's native
4031
+ * setSessionStorageItem rejects primitives with a fatal
4032
+ * "SetSessionStorageItem param 1 should be Object" error, so a bare
4033
+ * `setItem('counter', 1)` would crash on Increment. We wrap primitives
4034
+ * in `{ __data }` (getItem unwraps them symmetrically).
4035
+ *
4036
+ * 2. **No native pub/sub.** The main thread registers only get/set — there
4037
+ * is no subscribeSessionStorage — so {@link watch}'s subscription falls
4038
+ * back to the local listener map (see {@link subscribe}). A native write
4039
+ * alone therefore never reaches those listeners: the counter signal stays
4040
+ * on its seed value and the UI shows "not set" no matter how many times
4041
+ * the user taps Increment. We bridge the gap by firing the local
4042
+ * listeners ourselves right after the native write.
4043
+ *
4044
+ * The background thread deliberately does NOT call #notifyLocalListeners:
4045
+ * there, watch() subscribes through native subscribeSessionStorage, and the
4046
+ * native layer already fans the change out to every LynxView (including this
4047
+ * one). Firing local listeners too would double-notify. There is no infinite
4048
+ * loop in either case — #notifyLocalListeners only invokes stored callbacks,
4049
+ * it never calls setItem back.
4050
+ */
4051
+ setItem<T = unknown>(key: string, value: T): void;
4052
+ /**
4053
+ * Reads a value from session storage. The native API is callback-based;
4054
+ * this wraps it in a Promise for ergonomic use with `async`/`await`.
4055
+ *
4056
+ * On the main thread, wrapped primitives are unwrapped here to match
4057
+ * the user's expectation that the value they stored is the value they get.
4058
+ */
4059
+ getItem<T = unknown>(key: string): Promise<T>;
4060
+ /**
4061
+ * Subscribes to changes for a session storage key. The callback fires
4062
+ * whenever any LynxView calls `setItem` with the same key.
4063
+ *
4064
+ * Returns the subscription needed for {@link unsubscribe}.
4065
+ */
4066
+ subscribe<T = unknown>(key: string, callback: (value: T) => void): SessionStorageSubscription;
4067
+ /**
4068
+ * Cancels a session storage subscription created by {@link subscribe}.
4069
+ */
4070
+ unsubscribe(subscription: SessionStorageSubscription): void;
4071
+ /**
4072
+ * Creates a reactive signal that tracks a session storage key.
4073
+ *
4074
+ * Seeds the signal with the current value via `getItem`, then subscribes
4075
+ * to future changes. The subscription is automatically cleaned up when the
4076
+ * calling component/service is destroyed.
4077
+ *
4078
+ * Must be called from an injection context (constructor, field initializer,
4079
+ * or `runInInjectionContext`) unless an explicit `injector` is provided.
4080
+ */
4081
+ watch<T = unknown>(key: string, options?: {
4082
+ injector?: Injector;
4083
+ }): ReturnType<typeof signal<T | undefined>>;
4084
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxSessionStorage, never>;
4085
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4086
+ }
4087
+ /**
4088
+ * Wraps the global `SystemInfo` object as an Angular injectable,
4089
+ * providing device and platform information from the Lynx runtime.
4090
+ *
4091
+ * `SystemInfo` is populated once when the Lynx view initializes and
4092
+ * is read-only for the lifetime of the app — the values never change.
4093
+ *
4094
+ * On iOS and Android (Lynx 4.1), the main thread has no global `SystemInfo`,
4095
+ * only `lynx.SystemInfo`, so that's read first. The background thread and the
4096
+ * web have the global.
4097
+ *
4098
+ * @usageNotes
4099
+ * ```typescript
4100
+ * const systemInfo = inject(LynxSystemInfo);
4101
+ *
4102
+ * // Device dimensions in physical pixels
4103
+ * const { pixelWidth, pixelHeight, pixelRatio } = systemInfo;
4104
+ *
4105
+ * // Logical screen dimensions (CSS pixels)
4106
+ * const cssWidth = systemInfo.screenWidth;
4107
+ * const cssHeight = systemInfo.screenHeight;
4108
+ *
4109
+ * // Platform detection
4110
+ * if (systemInfo.platform === 'iOS') {
4111
+ * // iOS-specific logic
4112
+ * }
4113
+ * ```
4114
+ */
4115
+ export declare class LynxSystemInfo {
4116
+ #private;
4117
+ constructor();
4118
+ /**
4119
+ * The platform of the current device (e.g. `'iOS'`, `'Android'`).
4120
+ */
4121
+ get platform(): PlatformType;
4122
+ /**
4123
+ * The Lynx engine version (e.g. `'3.2'`).
4124
+ */
4125
+ get engineVersion(): string;
4126
+ /**
4127
+ * The current operating system version.
4128
+ */
4129
+ get osVersion(): string;
4130
+ /**
4131
+ * Physical pixel width of the device screen.
4132
+ */
4133
+ get pixelWidth(): number;
4134
+ /**
4135
+ * Physical pixel height of the device screen.
4136
+ */
4137
+ get pixelHeight(): number;
4138
+ /**
4139
+ * Device pixel ratio (physical pixels per CSS pixel).
4140
+ */
4141
+ get pixelRatio(): number;
4142
+ /**
4143
+ * The JavaScript engine in use (`'v8'`, `'jsc'`, or `'quickjs'`). Only available on the background thread.
4144
+ */
4145
+ get runtimeType(): 'v8' | 'jsc' | 'quickjs';
4146
+ /**
4147
+ * Screen width in logical/CSS pixels (`pixelWidth / pixelRatio`).
4148
+ */
4149
+ get screenWidth(): number;
4150
+ /**
4151
+ * Screen height in logical/CSS pixels (`pixelHeight / pixelRatio`).
4152
+ */
4153
+ get screenHeight(): number;
4154
+ /**
4155
+ * The theme object, if provided by the host application.
4156
+ */
4157
+ get theme(): object | undefined;
4158
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxSystemInfo, never>;
4159
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4160
+ }
4161
+ /**
4162
+ * Wraps `lynx.getTextInfo()` for measuring text dimensions and
4163
+ * performing line-breaking calculations.
4164
+ *
4165
+ * Only works with built-in platform fonts. Custom fonts loaded via
4166
+ * `@font-face` or `LynxFont` will fall back to the default
4167
+ * system font and produce inaccurate measurements.
4168
+ *
4169
+ * @usageNotes
4170
+ * ```typescript
4171
+ * const textMeasure = inject(LynxTextMeasure);
4172
+ *
4173
+ * const { width } = textMeasure.measure('Hello', { fontSize: '16px' });
4174
+ *
4175
+ * const { content } = textMeasure.measure('Long text...', {
4176
+ * fontSize: '14px',
4177
+ * maxWidth: '200px',
4178
+ * maxLine: 3,
4179
+ * });
4180
+ * ```
4181
+ */
4182
+ export declare class LynxTextMeasure {
4183
+ measure(text: string, options: TextInfo): TextMetrics;
4184
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTextMeasure, never>;
4185
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4186
+ }
4187
+ /**
4188
+ * Provides reactive access to the current Lynx theme ('Dark' or 'Light').
4189
+ *
4190
+ * The theme is driven by `lynx.__globalProps.theme`, which the native host
4191
+ * sets based on the OS appearance setting. It updates reactively when the
4192
+ * host calls `updateGlobalProps`.
4193
+ *
4194
+ * @usageNotes
4195
+ * ```typescript
4196
+ * const theme = inject(LynxTheme);
4197
+ *
4198
+ * // Reactive in templates
4199
+ * template: `<text [style.color]="theme.isDarkMode() ? '#fff' : '#000'">Hello</text>`
4200
+ *
4201
+ * // Or use CSS variables (preferred for styling — see docs/guide/dark-mode.mdx)
4202
+ * ```
4203
+ */
4204
+ export declare class LynxTheme {
4205
+ #private;
4206
+ /**
4207
+ * The current theme: `'Dark'` or `'Light'`. Reactive — updates when global props change.
4208
+ */
4209
+ readonly theme: import("@angular/core").Signal<"Dark" | "Light">;
4210
+ /**
4211
+ * Whether the current theme is dark mode. Reactive.
4212
+ */
4213
+ readonly isDarkMode: import("@angular/core").Signal<boolean>;
4214
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTheme, never>;
4215
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4216
+ }
4217
+ /**
4218
+ * Animates the enter/leave of projected content using CSS `@keyframes`.
4219
+ *
4220
+ * Two classes are toggled on the host element:
4221
+ *
4222
+ * | Phase | Class applied | Plays |
4223
+ * |-------|-----------------|----------------------------------------|
4224
+ * | Enter | `{name}-enter` | on mount, until `duration` elapses |
4225
+ * | Leave | `{name}-leave` | then the element is unmounted |
4226
+ *
4227
+ * **Why keyframes, not a two-phase CSS `transition`.** The obvious Vue-style
4228
+ * approach (mount in a `-enter-from` state, then swap to `-enter-to` one frame
4229
+ * later so a `transition` interpolates) needs a real paint gap between the two
4230
+ * states. Lynx's background thread — where Angular runs — has no reliable frame
4231
+ * boundary: `requestAnimationFrame` is microtask-mapped/absent, and class
4232
+ * mutations made from an rAF/`setTimeout` callback don't go through change
4233
+ * detection so they never reliably flush to the main thread (the element tree is
4234
+ * committed once per CD cycle in `LynxRendererFactory2.end()`). A `@keyframes`
4235
+ * animation sidesteps all of it: a SINGLE class, applied inside the effect (a CD
4236
+ * pass) so it flushes in the same commit that mounts the element, and the native
4237
+ * engine plays the keyframes from 0%. This mirrors the proven single-class
4238
+ * pattern in `examples/animations`.
4239
+ *
4240
+ * Completion is timer-based (`duration`) because the background thread has no
4241
+ * `animationend` bridge — `duration` must match your CSS animation length.
4242
+ *
4243
+ * @usageNotes
4244
+ * ```html
4245
+ * <lynx-transition [show]="isVisible()" name="fade" [duration]="300">
4246
+ * <view class="panel"><text>Hello</text></view>
4247
+ * </lynx-transition>
4248
+ * ```
4249
+ *
4250
+ * ```css
4251
+ * @keyframes fade-enter { from { opacity: 0; } to { opacity: 1; } }
4252
+ * @keyframes fade-leave { from { opacity: 1; } to { opacity: 0; } }
4253
+ * .fade-enter { animation: fade-enter 300ms ease both; }
4254
+ * .fade-leave { animation: fade-leave 300ms ease both; }
4255
+ * ```
4256
+ */
4257
+ export declare class LynxTransition {
4258
+ #private;
4259
+ readonly show: import("@angular/core").InputSignal<boolean>;
4260
+ readonly name: import("@angular/core").InputSignal<string>;
4261
+ readonly duration: import("@angular/core").InputSignal<number>;
4262
+ readonly afterEnter: import("@angular/core").OutputEmitterRef<void>;
4263
+ readonly afterLeave: import("@angular/core").OutputEmitterRef<void>;
4264
+ readonly shouldRender: import("@angular/core").WritableSignal<boolean>;
4265
+ constructor();
4266
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTransition, never>;
4267
+ static ɵcmp: i0.ɵɵComponentDeclaration<LynxTransition, "lynx-transition", never, {
4268
+ "show": {
4269
+ "alias": "show";
4270
+ "required": false;
4271
+ "isSignal": true;
4272
+ };
4273
+ "name": {
4274
+ "alias": "name";
4275
+ "required": false;
4276
+ "isSignal": true;
4277
+ };
4278
+ "duration": {
4279
+ "alias": "duration";
4280
+ "required": false;
4281
+ "isSignal": true;
4282
+ };
4283
+ }, {
4284
+ "afterEnter": "afterEnter";
4285
+ "afterLeave": "afterLeave";
4286
+ }, never, ["*"], true, never>;
4287
+ }
4288
+ /**
4289
+ * Animates enter/leave of list items using CSS `@keyframes`.
4290
+ *
4291
+ * Unlike `LynxTransition` (single element), this manages a collection. Items are
4292
+ * rendered from a user-provided `<ng-template>`, and the component diffs the list
4293
+ * on each change to animate additions and removals.
4294
+ *
4295
+ * Each item's root element gets a single class toggled: `{name}-enter` on
4296
+ * insertion, `{name}-leave` before removal. See `LynxTransition` for why a
4297
+ * single `@keyframes` class is used instead of a two-phase CSS `transition` (the
4298
+ * two-phase approach can't get a reliable paint gap on Lynx's background thread).
4299
+ *
4300
+ * @usageNotes
4301
+ * ```html
4302
+ * <lynx-transition-group [each]="items()" [trackBy]="idFn" name="list" [duration]="300">
4303
+ * <ng-template let-item>
4304
+ * <view>
4305
+ * <text>{{ item.name }}</text>
4306
+ * </view>
4307
+ * </ng-template>
4308
+ * </lynx-transition-group>
4309
+ * ```
4310
+ *
4311
+ * ```css
4312
+ * @keyframes list-enter { from { opacity: 0; transform: translateX(30px); } to { opacity: 1; transform: translateX(0); } }
4313
+ * @keyframes list-leave { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(-30px); } }
4314
+ * .list-enter { animation: list-enter 300ms ease both; }
4315
+ * .list-leave { animation: list-leave 300ms ease both; }
4316
+ * ```
4317
+ */
4318
+ export declare class LynxTransitionGroup<T> {
4319
+ #private;
4320
+ readonly each: import("@angular/core").InputSignal<T[]>;
4321
+ readonly trackBy: import("@angular/core").InputSignal<(item: T) => unknown>;
4322
+ readonly name: import("@angular/core").InputSignal<string>;
4323
+ readonly duration: import("@angular/core").InputSignal<number>;
4324
+ readonly afterEnter: import("@angular/core").OutputEmitterRef<T>;
4325
+ readonly afterLeave: import("@angular/core").OutputEmitterRef<T>;
4326
+ readonly itemTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
4327
+ protected readonly vcr: import("@angular/core").Signal<ViewContainerRef>;
4328
+ constructor();
4329
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxTransitionGroup<any>, never>;
4330
+ static ɵcmp: i0.ɵɵComponentDeclaration<LynxTransitionGroup<any>, "lynx-transition-group", never, {
4331
+ "each": {
4332
+ "alias": "each";
4333
+ "required": false;
4334
+ "isSignal": true;
4335
+ };
4336
+ "trackBy": {
4337
+ "alias": "trackBy";
4338
+ "required": false;
4339
+ "isSignal": true;
4340
+ };
4341
+ "name": {
4342
+ "alias": "name";
4343
+ "required": false;
4344
+ "isSignal": true;
4345
+ };
4346
+ "duration": {
4347
+ "alias": "duration";
4348
+ "required": false;
4349
+ "isSignal": true;
4350
+ };
4351
+ }, {
4352
+ "afterEnter": "afterEnter";
4353
+ "afterLeave": "afterLeave";
4354
+ }, ["itemTemplate"], never, true, never>;
4355
+ }
4356
+ /**
4357
+ * Central DI configuration for the Lynx renderer. Must be included in every
4358
+ * Lynx Angular app's providers (typically via app.config.ts). Sets up:
4359
+ * 1. The document (LynxDocument, or LynxHydrateDocument for SSR)
4360
+ * 2. DOCUMENT stub (Angular requires this token but Lynx has no DOM Document)
4361
+ * 3. APP_BASE_HREF (prevents BrowserPlatformLocation from crashing)
4362
+ * 4. Renderer factory (creates LynxRenderer / EmulatedLynxRenderer)
4363
+ * 5. Error handler (routes to _ReportError + __lynxLastError)
4364
+ */
4365
+ export declare const provideRenderer: () => EnvironmentProviders;
4366
+ /**
4367
+ * Keeps the app on the screen it was showing when a hot update re-bootstraps
4368
+ * it. Called with the old app's injector before it's destroyed, it saves the
4369
+ * old strategy's history, and the next strategy created starts from it. The
4370
+ * router's initial navigation then goes to the current URL instead of `/`,
4371
+ * and Back still has the screens before it.
4372
+ *
4373
+ * Does nothing for an app without the router, or with another strategy.
4374
+ *
4375
+ * @param injector - The injector of the app that's about to be destroyed.
4376
+ */
4377
+ declare const carryOverLocation: (injector: Injector | undefined) => void;
4378
+ /**
4379
+ * In-memory LocationStrategy for Lynx — equivalent to React Router's MemoryRouter.
4380
+ *
4381
+ * Lynx is a native mobile runtime with no browser URL or History API.
4382
+ * Angular's default PathLocationStrategy chains through PlatformLocation →
4383
+ * window.history/window.location, which breaks Lynx's background thread
4384
+ * even with mocked globals.
4385
+ *
4386
+ * This strategy keeps all routing state in memory: a history stack,
4387
+ * current index, and popstate listeners — no browser APIs touched.
4388
+ *
4389
+ * Registered via `provideRouter()` in `lynx-router.ts`.
4390
+ */
4391
+ export declare class LynxLocationStrategy extends LocationStrategy {
4392
+ #private;
4393
+ constructor();
4394
+ /**
4395
+ * Whether there's an entry before the current one, so `back()` goes
4396
+ * somewhere. The Android back button follows it (see lynx-back-button.ts):
4397
+ * while it's false, back leaves the app, as on any root screen.
4398
+ */
4399
+ readonly canGoBack: import("@angular/core").Signal<boolean>;
4400
+ path(): string;
4401
+ prepareExternalUrl(internal: string): string;
4402
+ getBaseHref(): string;
4403
+ getState(): unknown;
4404
+ pushState(state: unknown, _title: string, url: string, queryParams: string): void;
4405
+ replaceState(state: unknown, _title: string, url: string, queryParams: string): void;
4406
+ back(): void;
4407
+ forward(): void;
4408
+ historyGo(relativePosition?: number): void;
4409
+ onPopState(fn: LocationChangeListener): VoidFunction;
4410
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxLocationStrategy, never>;
4411
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4412
+ }
4413
+ /**
4414
+ * PlatformLocation implementation for Lynx.
4415
+ *
4416
+ * Angular's default BrowserPlatformLocation uses `new URL()`, which doesn't
4417
+ * exist in the Lynx JS runtime. This class avoids `URL` entirely by manually
4418
+ * parsing pathname, search, and hash from the URL string.
4419
+ *
4420
+ * Registered via `provideRouter()` in `lynx-router.ts`.
4421
+ *
4422
+ * The `@Injectable()` decorator is required so Angular generates a `ɵfac`
4423
+ * factory for this class. Without it, `getUndecoratedInjectableFactory()`
4424
+ * walks the prototype chain, finds PlatformLocation's factory
4425
+ * (`() => inject(BrowserPlatformLocation)`), and silently creates the wrong
4426
+ * class — which crashes in Lynx because `window.location` doesn't exist.
4427
+ */
4428
+ export declare class LynxPlatformLocation extends PlatformLocation {
4429
+ #private;
4430
+ getBaseHrefFromDOM(): string;
4431
+ get href(): string;
4432
+ get protocol(): string;
4433
+ get hostname(): string;
4434
+ get port(): string;
4435
+ get pathname(): string;
4436
+ get search(): string;
4437
+ get hash(): string;
4438
+ onPopState(fn: LocationChangeListener): VoidFunction;
4439
+ onHashChange(_fn: LocationChangeListener): VoidFunction;
4440
+ replaceState(state: unknown, title: string, url: string): void;
4441
+ pushState(state: unknown, title: string, url: string): void;
4442
+ forward(): void;
4443
+ back(): void;
4444
+ historyGo(relativePosition?: number): void;
4445
+ getState(): unknown;
4446
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxPlatformLocation, never>;
4447
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4448
+ }
4449
+ /**
4450
+ * Route reuse strategy that keeps component views alive across navigations.
4451
+ *
4452
+ * Opt-in: `provideRouter()` doesn't install it, so leaving a route destroys
4453
+ * its components, as Angular does on the web. Provide it yourself to keep
4454
+ * every visited route's component, and its state, alive:
4455
+ *
4456
+ * ```typescript
4457
+ * providers: [
4458
+ * provideRouter(routes),
4459
+ * { provide: RouteReuseStrategy, useClass: LynxRouteReuseStrategy },
4460
+ * ]
4461
+ * ```
4462
+ *
4463
+ * Nothing is ever evicted, and `ngOnDestroy()` doesn't run when you leave a
4464
+ * route.
4465
+ *
4466
+ * ## Why it exists
4467
+ *
4468
+ * `provideRouter()` used to install it. A crash investigation in May 2026
4469
+ * blamed a ~256-slot native element pool that `__RemoveElement` never freed,
4470
+ * and detaching views was meant to reuse their elements. Neither holds on
4471
+ * Lynx 4.1 (measured October 2026 on the iOS Simulator and an Android
4472
+ * emulator, issue #68): 400 navigations between two 300-element routes
4473
+ * created 121,527 native elements without a crash, with this strategy and
4474
+ * with Angular's default alike. A re-attached view's native elements were
4475
+ * destroyed when it was detached, so `LynxElement` rebuilds them from cache
4476
+ * (`#recreateSubtree`), and a revisit creates as many elements as a fresh
4477
+ * route.
4478
+ */
4479
+ export declare class LynxRouteReuseStrategy implements RouteReuseStrategy {
4480
+ #private;
4481
+ shouldDetach(_route: ActivatedRouteSnapshot): boolean;
4482
+ store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void;
4483
+ shouldAttach(route: ActivatedRouteSnapshot): boolean;
4484
+ retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;
4485
+ shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean;
4486
+ static ɵfac: i0.ɵɵFactoryDeclaration<LynxRouteReuseStrategy, never>;
4487
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
4488
+ }
4489
+ /**
4490
+ * Provides Angular Router configured for the Lynx runtime.
4491
+ *
4492
+ * Uses `LynxLocationStrategy` (in-memory routing) instead of Angular's default
4493
+ * `PathLocationStrategy` which relies on browser History/Location APIs. This is
4494
+ * the Angular equivalent of React Router's `MemoryRouter` — Lynx is a native
4495
+ * mobile runtime with no browser URL or History API.
4496
+ */
4497
+ export declare const provideRouter: (routes: Routes, ...features: RouterFeatures[]) => EnvironmentProviders;
4498
+ /**
4499
+ * On-device crash diagnostics.
4500
+ *
4501
+ * There is no console on the Lynx device, so we capture the last unhandled
4502
+ * error/rejection into a global (`__lynxLastError`) that Angular components can
4503
+ * surface via a `<text>` element. LynxErrorHandler covers Angular-managed
4504
+ * errors; the global `onerror`/`onunhandledrejection` handlers registered here
4505
+ * catch crashes that escape Angular entirely — native glue code, promise
4506
+ * rejections outside zones, etc.
4507
+ *
4508
+ * Split out of runtime.ts so `reportToNative` (and the handlers) can be
4509
+ * unit-tested on their own, and so the diagnostic seed runs before any other
4510
+ * runtime side effect.
4511
+ */
4512
+ /**
4513
+ * Forward an error to the native Lynx error reporting API when it exists.
4514
+ * errorCode 1101 = ErrCode::LYNX_ERROR_CODE_LEPUS (matches React Lynx's
4515
+ * convention). No-op off-device where `_ReportError` is absent.
4516
+ */
4517
+ declare const reportToNative: (err: Error) => void;
4518
+ type GlobalExposureBatch = {
4519
+ type: 'exposure' | 'disexposure';
4520
+ events: GlobalExposureEvent;
4521
+ };
4522
+ /**
4523
+ * Every batch of global exposure events, on whichever thread this module runs.
4524
+ * LynxGlobalExposure subscribes.
4525
+ */
4526
+ declare const globalExposureBatches: Subject<GlobalExposureBatch>;
4527
+ /**
4528
+ * The background thread's half of the main thread's `fetch` (see fetch.ts).
4529
+ * Lynx has `fetch` on the background thread only, and Angular runs on the
4530
+ * main thread, so the main thread's `fetch` sends each request here, where
4531
+ * background-call.ts's relay runs it, and this sends the response back.
4532
+ *
4533
+ * Everything crosses as JSON. A body is text when it can be, and base64
4534
+ * otherwise, since JSON can't carry bytes.
4535
+ */
4536
+ /** A request or response body as it crosses threads. */
4537
+ type RelayedBody = {
4538
+ text: string;
4539
+ } | {
4540
+ base64: string;
4541
+ } | null;
4542
+ /** A request as the main thread sends it. */
4543
+ type RelayedRequest = {
4544
+ url: string;
4545
+ method: string;
4546
+ /** Unique names, since the main thread's Headers joins repeated ones. */
4547
+ headers: [string, string][];
4548
+ body: RelayedBody;
4549
+ /** The rest of `RequestInit`, for hosts that use it (Lynx for Web's worker). */
4550
+ options: {
4551
+ cache?: string;
4552
+ credentials?: string;
4553
+ integrity?: string;
4554
+ keepalive?: boolean;
4555
+ mode?: string;
4556
+ priority?: string;
4557
+ redirect?: string;
4558
+ referrer?: string;
4559
+ referrerPolicy?: string;
4560
+ };
4561
+ };
4562
+ /** A response as the background thread sends it back. */
4563
+ type RelayedResponse = {
4564
+ status: number;
4565
+ statusText: string;
4566
+ url: string;
4567
+ redirected: boolean;
4568
+ headers: [string, string][];
4569
+ body: RelayedBody;
4570
+ };
4571
+ /**
4572
+ * Runs a request for the main thread and resolves with the response, body
4573
+ * included. It rejects with a TypeError when the request fails, as `fetch`
4574
+ * does.
4575
+ *
4576
+ * @param id - The main thread's ID for the request, to abort it by.
4577
+ * @param request - The request.
4578
+ * @returns The response.
4579
+ */
4580
+ declare const fetchForMainThread: (id: number, request: RelayedRequest) => Promise<RelayedResponse>;
4581
+ /**
4582
+ * Aborts a request the main thread sent, when its signal aborts. The main
4583
+ * thread has already rejected its own promise; this stops the work here.
4584
+ *
4585
+ * @param id - The main thread's ID for the request.
4586
+ */
4587
+ declare const abortFetchForMainThread: (id: number) => void;
4588
+ /**
4589
+ * `__MAIN_THREAD__` is a build-time define. Unit tests don't define it, and run
4590
+ * as the background thread unless they stub it.
4591
+ *
4592
+ * @returns Whether this code runs on the main thread.
4593
+ */
4594
+ declare const isMainThread: () => boolean;
4595
+ /**
4596
+ * Prepares a relayed call's arguments: on the main thread, each function in
4597
+ * them, or in a plain object or array in them, becomes a marker that the
4598
+ * background thread calls back. Elsewhere the call runs in place, so the
4599
+ * arguments are left alone.
4600
+ *
4601
+ * @param value - The arguments, or one of them.
4602
+ * @returns The value to send.
4603
+ */
4604
+ declare const relayFunctions: (value: unknown) => unknown;
4605
+ /**
4606
+ * Prepares a JS module for registering from the main thread: its methods,
4607
+ * including ones on its prototype such as a class's, become markers bound to
4608
+ * it, and its other fields are copied.
4609
+ *
4610
+ * @param module - The module to register.
4611
+ * @returns The value to send.
4612
+ */
4613
+ declare const relayModuleObject: (module: object) => unknown;
4614
+ /** Which registry a relayed module comes from. */
4615
+ type ModuleKind = 'native' | 'js';
4616
+ declare const handlers: {
4617
+ accessibilityAnnounce: (content: string) => Promise<void>;
4618
+ addFont: (fontFamily: string, src: string) => Promise<void>;
4619
+ setObserverFrameRate: (options?: ObserverFrameRateOptions) => void;
4620
+ stopExposure: (options?: {
4621
+ sendEvent: boolean;
4622
+ }) => void;
4623
+ resumeExposure: () => void;
4624
+ /**
4625
+ * Subscribes on the background thread and sends each change to the main
4626
+ * thread, where subscribeSessionStorageFromMainThread() delivers it.
4627
+ */
4628
+ subscribeSessionStorage: (key: string, relayId: number) => void;
4629
+ unsubscribeSessionStorage: (relayId: number) => void;
4630
+ requestResourcePrefetch: (data: unknown) => Promise<unknown>;
4631
+ cancelResourcePrefetch: (data: unknown) => Promise<unknown>;
4632
+ /**
4633
+ * Calls the host's bridge method and resolves with the first value it
4634
+ * passes back. Without a bridge, such as in the web preview, it resolves
4635
+ * `undefined`, as LynxNativeModule.call() always has.
4636
+ */
4637
+ nativeBridgeCall: (name: string, params: unknown) => Promise<unknown>;
4638
+ nativeBridgeOn: (name: string, callback: unknown) => void;
4639
+ /**
4640
+ * Calls a method of a native module or a JS module. The main thread's
4641
+ * module proxies (relayedModule() below) send their calls here.
4642
+ */
4643
+ callModule: (kind: ModuleKind, name: string, method: string, args: unknown[]) => unknown;
4644
+ registerJSModule: (name: string, module: unknown) => void;
4645
+ /** The main thread's `fetch` (network/fetch.ts) sends its requests here. */
4646
+ fetch: (id: number, request: RelayedRequest) => Promise<RelayedResponse>;
4647
+ abortFetch: (id: number) => void;
4648
+ };
4649
+ type Handlers = typeof handlers;
4650
+ type HandlerName = keyof Handlers;
4651
+ /**
4652
+ * Runs a background-only Lynx API, directly on the background thread or relayed
4653
+ * from the main thread.
4654
+ */
4655
+ declare const callOnBackground: <N extends HandlerName>(name: N, ...args: Parameters<Handlers[N]>) => Promise<Awaited<ReturnType<Handlers[N]>>>;
4656
+ /**
4657
+ * Main thread: a stand-in for a native module or JS module, which only the
4658
+ * background thread can reach. Each method call runs there and returns a
4659
+ * promise of its result, and function arguments are called back here. Reading
4660
+ * `then` gives `undefined`, so the proxy isn't mistaken for a promise.
4661
+ *
4662
+ * @param kind - `'native'` for `NativeModules`, `'js'` for `lynx.getJSModule`.
4663
+ * @param name - The module's name.
4664
+ * @returns The proxy.
4665
+ */
4666
+ declare const relayedModule: (kind: ModuleKind, name: string) => object;
4667
+ /**
4668
+ * Main thread only. Subscribes to a session storage key through the background
4669
+ * thread, the only thread that can, and returns the ID to unsubscribe with.
4670
+ */
4671
+ declare const subscribeSessionStorageFromMainThread: (key: string, listener: (value: unknown) => void) => number;
4672
+ declare const unsubscribeSessionStorageFromMainThread: (relayId: number) => void;
4673
+ /**
4674
+ * Starts the background thread. The build calls it from the background
4675
+ * thread's entry, a module it generates in place of the app's `main.ts`
4676
+ * (background-entry.ts in the build plugin): Angular runs on the main thread
4677
+ * only, so the background thread loads just this runtime and the modules that
4678
+ * define a background function or a `MainThreadRef`.
4679
+ *
4680
+ * Loading the runtime installs the background half of each bridge (the imports
4681
+ * above). This installs `lynx.loadLazyBundle`, for an `import()` in a
4682
+ * background function. Importing it is also what keeps the runtime in the
4683
+ * background bundle: the package is marked `"sideEffects": false`, so a bare
4684
+ * `import '@blotch/angular-lynx'` would be dropped.
4685
+ */
4686
+ export declare const ɵstartBackgroundThread: () => void;
4687
+ /**
4688
+ * Bootstrap Angular application on the Lynx runtime. Waits for the main thread to
4689
+ * signal it's ready before initializing the framework, then registers global
4690
+ * callbacks for page updates and worklet invocations.
4691
+ *
4692
+ * Angular runs on the main thread only. The background thread starts from an
4693
+ * entry the build generates instead of `main.ts` (see
4694
+ * {@link ɵstartBackgroundThread}), so it doesn't reach this function, unless a
4695
+ * module it loads also bootstraps, such as a `main.ts` that defines a
4696
+ * `backgroundFn()` itself. Then it gets no app: the returned promise never
4697
+ * settles on that thread. Booting a second copy there ran every constructor,
4698
+ * `ngOnInit` and `effect()` twice, and its views went nowhere (issue #81).
4699
+ */
4700
+ export declare const bootstrapApplication: (rootComponent: Type<unknown>, options?: ApplicationConfig) => Promise<ApplicationRef>;
4701
+ declare global {
4702
+ /**
4703
+ * Determines if code should be placed in the background thread, used as a compile-time define macro
4704
+ */
4705
+ var __BACKGROUND__: boolean;
4706
+ /**
4707
+ * Determines if code should be placed in the main thread, used as a compile-time define macro
4708
+ */
4709
+ var __MAIN_THREAD__: boolean;
4710
+ /**
4711
+ * Whether this bundle targets the web runtime (`@lynx-js/web-core`) rather
4712
+ * than native Lynx. Compile-time define injected by the rsbuild plugin
4713
+ * (`environment.name === 'web'`). Used to branch on web-only behavior that
4714
+ * must be dead-code-eliminated from native bundles — e.g. web-core has no
4715
+ * implicit post-`renderPage` flush, so the runtime forces the first
4716
+ * `__FlushElementTree` itself (see `bootstrapApplication` in runtime.ts).
4717
+ */
4718
+ var __WEB__: boolean;
4719
+ /**
4720
+ * Determines if running in dev mode
4721
+ */
4722
+ var __DEV__: boolean;
4723
+ /**
4724
+ * Determines if running in profile mode
4725
+ */
4726
+ var __PROFILE__: boolean;
4727
+ /**
4728
+ * Whether SSR (Instant First-Frame Rendering) is enabled. When true, the
4729
+ * runtime registers `ssrEncode` and `ssrHydrate` global callbacks that
4730
+ * the Lynx engine calls to snapshot and restore the element tree.
4731
+ */
4732
+ var __ENABLE_SSR__: boolean;
4733
+ /**
4734
+ * Full URL of the dev log server (e.g. http://192.168.1.91:3001/__dev_logs).
4735
+ * Injected by the rsbuild plugin's DefinePlugin in dev builds only.
4736
+ */
4737
+ var __DEV_LOG_URL__: string;
4738
+ /**
4739
+ * The source locale from angular.json i18n config (e.g. 'en-US', 'fr').
4740
+ * Injected by the rsbuild plugin's DefinePlugin. Used by LynxLocale
4741
+ * as a fallback when lynx.__globalProps.appLocale is not set.
4742
+ */
4743
+ var __LYNX_SOURCE_LOCALE__: string;
4744
+ interface Window {
4745
+ registerWorklet: (type: string, id: string, fn: Function) => void;
4746
+ __workletRefMap: Record<number | string, {
4747
+ current: unknown;
4748
+ }>;
4749
+ __lynxRunMainThreadWorklet: (wkltId: string, args: unknown[]) => unknown;
4750
+ }
4751
+ var registerWorklet: (type: string, id: string, fn: Function) => void;
4752
+ var __workletRefMap: Record<number | string, {
4753
+ current: unknown;
4754
+ }>;
4755
+ var __lynxRunMainThreadWorklet: (wkltId: string, args: unknown[]) => unknown;
4756
+ function runOnBackground(handle: {
4757
+ _wkltId: string;
4758
+ }, ...args: unknown[]): Promise<unknown>;
4759
+ }
4760
+ declare global {
4761
+ interface HTMLElementEventMap {
4762
+ bindtap: TouchEvent;
4763
+ catchtap: TouchEvent;
4764
+ 'capture-bindtap': TouchEvent;
4765
+ 'capture-catchtap': TouchEvent;
4766
+ 'global-bindtap': TouchEvent;
4767
+ bindtouchstart: TouchEvent;
4768
+ bindtouchend: TouchEvent;
4769
+ bindtouchmove: TouchEvent;
4770
+ bindtouchcancel: TouchEvent;
4771
+ bindlongpress: TouchEvent;
4772
+ catchtouchstart: TouchEvent;
4773
+ catchtouchend: TouchEvent;
4774
+ catchtouchmove: TouchEvent;
4775
+ catchtouchcancel: TouchEvent;
4776
+ catchlongpress: TouchEvent;
4777
+ bindmousedown: MouseEvent;
4778
+ bindmouseup: MouseEvent;
4779
+ bindmousemove: MouseEvent;
4780
+ bindmouseenter: MouseEvent;
4781
+ bindmouseleave: MouseEvent;
4782
+ catchmousedown: MouseEvent;
4783
+ catchmouseup: MouseEvent;
4784
+ catchmousemove: MouseEvent;
4785
+ catchmouseenter: MouseEvent;
4786
+ catchmouseleave: MouseEvent;
4787
+ }
4788
+ }
4789
+ export type { BackgroundFnHandle, BaseLynxAnimation, DataProcessorDefinition, DevToolsStats, ExposureEventDetail, FlingGestureEvent, GestureCallback, GestureCallbackWithState, GestureEvent, GlobalData, GlobalExposureEvent, InitData, InitDataRaw, LongPressGestureEvent, LynxAnimationOptions, LynxFontEntry, LynxFontFaceConfig, LynxFontStatus, LynxTraceOptions, MainThread, MainThreadFnHandle, NativeModuleMap, NativeModuleProxy, ObserverFrameRateOptions, PanGestureEvent, PinchGestureEvent, PortalConfig, PrefetchCacheTarget, PrefetchPriority, PrefetchRequest, PrefetchResultDetail, ResourcePrefetchData, ResourcePrefetchResult, RotationGestureEvent, SessionStorageSubscription, TapGestureEvent };