@blotch/angular-lynx 22.2.2 → 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.
@@ -1,11 +1,13 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ApplicationConfig, ApplicationRef, ComponentRef, EmbeddedViewRef, EnvironmentInjector, EnvironmentProviders, ErrorDetails, ErrorHandler, Injector, OnChanges, OnDestroy, SimpleChanges, TemplateRef, Type, ViewContainerRef, signal } from "@angular/core";
3
- import { Animation, AnimationEvent, AnimationOptions, Element, KeyEvent, LayoutChangeEvent, MouseEvent, TouchEvent, TransitionEvent, UIAppearanceEvent, WheelEvent } from "@lynx-js/types/main-thread";
3
+ import { Animation, AnimationOptions, Element as Element$1 } from "@lynx-js/types/main-thread";
4
4
  import { AnyObject } from "@lynx-js/types/common";
5
5
  import { ControlValueAccessor } from "@angular/forms";
6
- import { PlatformType, ResourcePrefetchData, ResourcePrefetchResult, TextInfo, TextMetrics, TouchEvent as TouchEvent$1 } from "@lynx-js/types";
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";
7
8
  import { LocationChangeListener, LocationStrategy, PlatformLocation } from "@angular/common";
8
9
  import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy, RouterFeatures, Routes } from "@angular/router";
10
+ import { Subject } from "rxjs";
9
11
  /**
10
12
  * Programmatic accessibility control for screen readers on Lynx.
11
13
  *
@@ -32,7 +34,9 @@ export declare class LynxAccessibility {
32
34
  * operation results that aren't reflected by focus movement alone
33
35
  * (e.g. toast messages, background task completion, live counters).
34
36
  *
35
- * Wraps `lynx.accessibilityAnnounce()`.
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).
36
40
  */
37
41
  announce(content: string): Promise<void>;
38
42
  /**
@@ -43,6 +47,9 @@ export declare class LynxAccessibility {
43
47
  * Only ID selectors are reliably supported (e.g. `'#myElement'`).
44
48
  *
45
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.
46
53
  */
47
54
  requestFocus(selector: string): Promise<void>;
48
55
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxAccessibility, never>;
@@ -247,19 +254,17 @@ type LynxAnimationOptions = AnimationOptions & {
247
254
  timingFunction?: string;
248
255
  };
249
256
  /**
250
- * Shared interface for all animation implementations (real and no-op).
251
- * Used by `BaseLynxElement.animate()` return type so both `LynxAnimation`
252
- * (main thread) and `NoopLynxAnimation` (background thread) are valid.
253
- * Required because LynxAnimation uses ES private fields (#element, #count)
254
- * which brand the class — TypeScript's structural typing won't accept
255
- * NoopLynxAnimation as assignable to LynxAnimation. This shared Pick type
256
- * extracts only the public API both implementations satisfy.
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.
257
261
  */
258
262
  type BaseLynxAnimation = Pick<Animation, 'id' | 'cancel' | 'pause' | 'play'>;
259
263
  /**
260
264
  * Represents a running animation on a Lynx element.
261
265
  * Created by calling `element.animate()` on a LynxElement.
262
- * Mirrors the Animation class from React Lynx's worklet-runtime.
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).
263
268
  */
264
269
  export declare class LynxAnimation implements Pick<Animation, 'id' | 'cancel' | 'pause' | 'play'> {
265
270
  #private;
@@ -269,21 +274,49 @@ export declare class LynxAnimation implements Pick<Animation, 'id' | 'cancel' |
269
274
  pause(): void;
270
275
  cancel(): void;
271
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
+ };
272
299
  /**
273
300
  * Wraps Lynx's native performance tracing APIs (`lynx.performance`).
274
301
  *
275
302
  * All methods are no-ops when `lynx.performance` is unavailable (e.g. in tests
276
303
  * or non-Lynx environments) or when profiling is not actively recording.
277
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
+ *
278
311
  * @usageNotes
279
312
  * ```typescript
280
313
  * const perf = inject(LynxPerformance);
281
314
  *
282
- * perf.profileStart('MyComponent::render', { itemCount: 42 });
315
+ * perf.profileStart('MyComponent::render', { args: { itemCount: '42' } });
283
316
  * // ... do work ...
284
317
  * perf.profileEnd();
285
318
  *
286
- * perf.profileMark('dataLoaded', { source: 'cache' });
319
+ * perf.profileMark('dataLoaded', { args: { source: 'cache' } });
287
320
  * ```
288
321
  */
289
322
  export declare class LynxPerformance {
@@ -297,10 +330,7 @@ export declare class LynxPerformance {
297
330
  * Begin a named trace. Must be paired with `profileEnd()`.
298
331
  * Traces nest — multiple `profileStart` calls create a stack.
299
332
  */
300
- profileStart(name: string, options?: {
301
- flowId?: number;
302
- args?: Record<string, unknown>;
303
- }): void;
333
+ profileStart(name: string, options?: LynxTraceOptions): void;
304
334
  /**
305
335
  * End the current trace (top of the trace stack).
306
336
  */
@@ -308,9 +338,7 @@ export declare class LynxPerformance {
308
338
  /**
309
339
  * Emit a discrete mark event in the trace timeline.
310
340
  */
311
- profileMark(name: string, options?: {
312
- args?: Record<string, unknown>;
313
- }): void;
341
+ profileMark(name: string, options?: LynxTraceOptions): void;
314
342
  /**
315
343
  * Generate a unique flow ID for correlating multi-threaded traces.
316
344
  */
@@ -318,24 +346,13 @@ export declare class LynxPerformance {
318
346
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxPerformance, never>;
319
347
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
320
348
  }
321
- /**
322
- * Profiling counters collected by the renderer during a session.
323
- * Only populated when the app is built with `__PROFILE__` enabled —
324
- * in production, instrumentation is dead-code-eliminated and all values stay 0.
325
- */
326
- type DevToolsStats = {
327
- cdCycles: number;
328
- elementCreated: number;
329
- elementRemoved: number;
330
- flushCount: number;
331
- lastCdDurationMs: number;
332
- };
333
349
  /**
334
350
  * High-level DevTools service exposing performance stats as Angular signals.
335
351
  *
336
- * Stats are only meaningful when the app is built with `__PROFILE__` enabled.
337
- * In production builds, counters are never incremented (the instrumentation
338
- * code is dead-code-eliminated), so all values remain zero.
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.
339
356
  *
340
357
  * @usageNotes
341
358
  * ```typescript
@@ -382,10 +399,24 @@ export declare class LynxDevTools {
382
399
  declare const devStats: DevToolsStats & {
383
400
  reset(): void;
384
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;
385
412
  /**
386
413
  * Extend this interface to type the raw data passed from native before processing.
387
414
  *
388
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
+ *
389
420
  * declare module '@blotch/angular-lynx' {
390
421
  * interface InitDataRaw { userId: string; }
391
422
  * }
@@ -395,6 +426,10 @@ interface InitDataRaw extends Record<string, unknown> {}
395
426
  * Extend this interface to type the processed init data used throughout the app.
396
427
  *
397
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
+ *
398
433
  * declare module '@blotch/angular-lynx' {
399
434
  * interface InitData { userId: string; }
400
435
  * }
@@ -404,6 +439,10 @@ interface InitData extends Record<string, unknown> {}
404
439
  * Extend this interface to type the global data passed from the native host.
405
440
  *
406
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
+ *
407
446
  * declare module '@blotch/angular-lynx' {
408
447
  * interface GlobalData { theme: 'light' | 'dark'; }
409
448
  * }
@@ -423,8 +462,9 @@ type DataProcessorDefinition = {
423
462
  * Register data processor functions that the native Lynx runtime calls before
424
463
  * delivering init data to the app. Maps to the global `processData` callback.
425
464
  *
426
- * Call this before bootstrapApplication so that native data is transformed
427
- * before LynxInitData receives the first onDataChanged event.
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.
428
468
  *
429
469
  * @example
430
470
  * registerDataProcessors({
@@ -487,7 +527,11 @@ type ExposureEventDetail = {
487
527
  'exposure-scene': string;
488
528
  exposureID: string;
489
529
  exposureScene: string;
490
- 'unique-id': number;
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;
491
535
  };
492
536
  /**
493
537
  * The Lynx engine batches element visibility changes at ~20fps and dispatches
@@ -499,6 +543,7 @@ type ObserverFrameRateOptions = {
499
543
  forExposureCheck?: number;
500
544
  };
501
545
  export declare class LynxGlobalExposure {
546
+ #private;
502
547
  readonly exposures: import("@angular/core").WritableSignal<GlobalExposureEvent>;
503
548
  readonly disexposures: import("@angular/core").WritableSignal<GlobalExposureEvent>;
504
549
  readonly active: import("@angular/core").WritableSignal<boolean>;
@@ -512,7 +557,13 @@ export declare class LynxGlobalExposure {
512
557
  sendEvent: boolean;
513
558
  }): void;
514
559
  resumeExposure(): void;
515
- setObserverFrameRate(options?: ObserverFrameRateOptions): 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>;
516
567
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxGlobalExposure, never>;
517
568
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
518
569
  }
@@ -535,6 +586,9 @@ type LynxFontEntry = {
535
586
  };
536
587
  /**
537
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).
538
592
  *
539
593
  * Use CSS `@font-face` in stylesheets for fonts known at build time (the
540
594
  * standard Angular approach). Use this service only for fonts that must be
@@ -569,6 +623,55 @@ export declare class LynxFont {
569
623
  * built with `experimental_isLazyBundle: true` in the rsbuild plugin.
570
624
  */
571
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;
572
675
  /**
573
676
  * Reads `lynx.__globalProps.appLocale` directly, without Angular DI.
574
677
  *
@@ -622,6 +725,12 @@ export declare class LynxLocale {
622
725
  * Angular's locale-aware features (pipes, i18n) with the locale from
623
726
  * `lynx.__globalProps.appLocale`.
624
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
+ *
625
734
  * @usageNotes
626
735
  * ```typescript
627
736
  * bootstrapApplication(App, {
@@ -755,6 +864,12 @@ export declare abstract class BaseGesture<TEvent extends GestureEvent = GestureE
755
864
  _callbacks: Record<string, GestureCallback<any>>;
756
865
  /**
757
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).
758
873
  */
759
874
  _config: Record<string, unknown>;
760
875
  /**
@@ -769,6 +884,15 @@ export declare abstract class BaseGesture<TEvent extends GestureEvent = GestureE
769
884
  * @internal
770
885
  */
771
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
+ */
772
896
  onBegin(cb: GestureCallbackWithState<TEvent>): TSelf;
773
897
  /**
774
898
  * Fires when the gesture is RECOGNIZED (transitions to active). For a tap this
@@ -805,6 +929,12 @@ export declare abstract class BaseGesture<TEvent extends GestureEvent = GestureE
805
929
  * Useful for chaining: e.g. a long-press followed by a drag.
806
930
  */
807
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
+ */
808
938
  enabled(value: boolean): TSelf;
809
939
  }
810
940
  /**
@@ -825,16 +955,31 @@ export declare const Gesture: {
825
955
  Exclusive(...gestures: AnyGesture$1[]): ComposedGesture;
826
956
  Race(...gestures: AnyGesture$1[]): ComposedGesture;
827
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
+ */
828
967
  export declare class FlingGesture extends ContinuousGesture<FlingGestureEvent, FlingGesture> {
829
968
  readonly type = GestureType.FLING;
830
969
  /**
831
970
  * FlingDirection is a bitmask — combine values with | for multi-direction:
832
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.
833
976
  */
834
977
  direction(dir: FlingDirection): this;
835
978
  /**
836
979
  * The gesture only recognizes when exactly `count` fingers are involved.
837
980
  * Defaults to 1 if not set.
981
+ *
982
+ * ⚠️ Not read by Lynx's native fling handlers yet (see `direction`).
838
983
  */
839
984
  numberOfPointers(count: number): this;
840
985
  }
@@ -856,6 +1001,7 @@ type GestureInput = AnyGesture | AnyGesture[] | ComposedGesture;
856
1001
  export declare class LynxGestureDetector implements OnChanges, OnDestroy {
857
1002
  #private;
858
1003
  lynxGesture: GestureInput;
1004
+ constructor();
859
1005
  /**
860
1006
  * Full teardown + re-register on every input change. This is safe because
861
1007
  * gesture IDs are stable (assigned once in BaseGesture constructor), so
@@ -906,6 +1052,11 @@ export declare class PanGesture extends ContinuousGesture<PanGestureEvent, PanGe
906
1052
  * threshold. A number means "any direction" (symmetrical); a tuple [min, max]
907
1053
  * means the offset must be within that range. Example: activeOffsetX(20)
908
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.
909
1060
  */
910
1061
  activeOffsetX(offset: number | [number, number]): this;
911
1062
  activeOffsetY(offset: number | [number, number]): this;
@@ -914,6 +1065,9 @@ export declare class PanGesture extends ContinuousGesture<PanGestureEvent, PanGe
914
1065
  * direction, the gesture fails (ceding to a competing gesture). Example:
915
1066
  * failOffsetY(10) on a horizontal pan: if the user moves >10px vertically
916
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.
917
1071
  */
918
1072
  failOffsetX(offset: number | [number, number]): this;
919
1073
  failOffsetY(offset: number | [number, number]): this;
@@ -958,6 +1112,11 @@ export declare class TapGesture extends BaseGesture<TapGestureEvent, TapGesture>
958
1112
  */
959
1113
  maxDistance(px: number): this;
960
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`;
961
1120
  /**
962
1121
  * @Directive() is required so that ng-packagr's Angular partial compiler
963
1122
  * recognizes this base class as an Angular artifact. The selector is left
@@ -1002,9 +1161,14 @@ declare class LynxElementBase implements OnChanges {
1002
1161
  * Text read aloud by screen readers.
1003
1162
  */
1004
1163
  'accessibility-label'?: string;
1005
- 'accessibility-trait'?: 'none' | 'button' | 'image' | 'text';
1006
1164
  /**
1007
- * Comma-separated list of child element names that are accessibility nodes.
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.
1008
1172
  */
1009
1173
  'accessibility-elements'?: string;
1010
1174
  'accessibility-elements-hidden'?: boolean;
@@ -1044,6 +1208,32 @@ declare class LynxElementBase implements OnChanges {
1044
1208
  * Allow simultaneous touch recognition (iOS).
1045
1209
  */
1046
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;
1047
1237
  /**
1048
1238
  * Unique ID used for impression/exposure analytics.
1049
1239
  */
@@ -1053,41 +1243,52 @@ declare class LynxElementBase implements OnChanges {
1053
1243
  */
1054
1244
  'exposure-scene'?: string;
1055
1245
  /**
1056
- * Percentage of the element that must be visible (0–100) to trigger exposure.
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).
1057
1252
  */
1058
- 'exposure-area'?: number;
1253
+ 'exposure-screen-margin-top'?: ExposureMargin;
1059
1254
  /**
1060
- * Extends/shrinks the viewport detection zone (top edge, in px).
1255
+ * Extends/shrinks the viewport detection zone (bottom edge).
1061
1256
  */
1062
- 'exposure-screen-margin-top'?: number | string;
1257
+ 'exposure-screen-margin-bottom'?: ExposureMargin;
1063
1258
  /**
1064
- * Extends/shrinks the viewport detection zone (bottom edge, in px).
1259
+ * Extends/shrinks the viewport detection zone (left edge).
1065
1260
  */
1066
- 'exposure-screen-margin-bottom'?: number | string;
1261
+ 'exposure-screen-margin-left'?: ExposureMargin;
1067
1262
  /**
1068
- * Extends/shrinks the viewport detection zone (left edge, in px).
1263
+ * Extends/shrinks the viewport detection zone (right edge).
1069
1264
  */
1070
- 'exposure-screen-margin-left'?: number | string;
1265
+ 'exposure-screen-margin-right'?: ExposureMargin;
1071
1266
  /**
1072
- * Extends/shrinks the viewport detection zone (right edge, in px).
1267
+ * Adjusts the element's own bounding rect for exposure detection (top).
1268
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1073
1269
  */
1074
- 'exposure-screen-margin-right'?: number | string;
1270
+ 'exposure-ui-margin-top'?: ExposureMargin;
1075
1271
  /**
1076
- * Adjusts the element's own bounding rect for exposure detection (top, in px).
1272
+ * Adjusts the element's own bounding rect for exposure detection (bottom).
1273
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1077
1274
  */
1078
- 'exposure-ui-margin-top'?: number | string;
1275
+ 'exposure-ui-margin-bottom'?: ExposureMargin;
1079
1276
  /**
1080
- * Adjusts the element's own bounding rect for exposure detection (bottom, in px).
1277
+ * Adjusts the element's own bounding rect for exposure detection (left).
1278
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1081
1279
  */
1082
- 'exposure-ui-margin-bottom'?: number | string;
1280
+ 'exposure-ui-margin-left'?: ExposureMargin;
1083
1281
  /**
1084
- * Adjusts the element's own bounding rect for exposure detection (left, in px).
1282
+ * Adjusts the element's own bounding rect for exposure detection (right).
1283
+ * iOS and Android apply it only with `enable-exposure-ui-margin`.
1085
1284
  */
1086
- 'exposure-ui-margin-left'?: number | string;
1285
+ 'exposure-ui-margin-right'?: ExposureMargin;
1087
1286
  /**
1088
- * Adjusts the element's own bounding rect for exposure detection (right, in px).
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
1089
1290
  */
1090
- 'exposure-ui-margin-right'?: number | string;
1291
+ 'enable-exposure-ui-margin'?: boolean;
1091
1292
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxElementBase, never>;
1092
1293
  static ɵdir: i0.ɵɵDirectiveDeclaration<LynxElementBase, never, never, {
1093
1294
  "id": {
@@ -1106,8 +1307,16 @@ declare class LynxElementBase implements OnChanges {
1106
1307
  "alias": "accessibility-label";
1107
1308
  "required": false;
1108
1309
  };
1109
- "accessibility-trait": {
1110
- "alias": "accessibility-trait";
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";
1111
1320
  "required": false;
1112
1321
  };
1113
1322
  "accessibility-elements": {
@@ -1154,6 +1363,26 @@ declare class LynxElementBase implements OnChanges {
1154
1363
  "alias": "ios-enable-simultaneous-touch";
1155
1364
  "required": false;
1156
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
+ };
1157
1386
  "exposure-id": {
1158
1387
  "alias": "exposure-id";
1159
1388
  "required": false;
@@ -1198,12 +1427,36 @@ declare class LynxElementBase implements OnChanges {
1198
1427
  "alias": "exposure-ui-margin-right";
1199
1428
  "required": false;
1200
1429
  };
1430
+ "enable-exposure-ui-margin": {
1431
+ "alias": "enable-exposure-ui-margin";
1432
+ "required": false;
1433
+ };
1201
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;
1202
1449
  }
1203
1450
  /**
1204
1451
  * Backdrop blur: blurs the content rendered behind the element, like CSS
1205
1452
  * `backdrop-filter: blur()`. On iOS, `blur-effect="glass"` renders the
1206
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.
1207
1460
  */
1208
1461
  export declare class LynxBlurView extends LynxElementBase {
1209
1462
  /**
@@ -1219,7 +1472,10 @@ export declare class LynxBlurView extends LynxElementBase {
1219
1472
  */
1220
1473
  'enable-auto-blur'?: boolean;
1221
1474
  /**
1222
- * Raw id of the view to capture and blur; it must have `flatten="false"` (Android).
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.
1223
1479
  */
1224
1480
  'android-capture-target'?: string;
1225
1481
  /**
@@ -1228,7 +1484,8 @@ export declare class LynxBlurView extends LynxElementBase {
1228
1484
  'experimental-update-blur-radius'?: boolean;
1229
1485
  /**
1230
1486
  * Blur material (iOS). `glass` renders Liquid Glass; `glass-container`
1231
- * merges nested glass `<blur-view>`s into one combined effect. @default 'light'
1487
+ * merges nested glass `<blur-view>`s into one combined effect. Android
1488
+ * gets a tint that approximates it. @default 'light'
1232
1489
  */
1233
1490
  'blur-effect'?: 'light' | 'extra-light' | 'dark' | 'glass' | 'glass-container';
1234
1491
  /**
@@ -1240,11 +1497,11 @@ export declare class LynxBlurView extends LynxElementBase {
1240
1497
  */
1241
1498
  'glass-interactive'?: boolean;
1242
1499
  /**
1243
- * Tint color applied to the glass (iOS). @default 'transparent'
1500
+ * Tint color applied to the glass (iOS; approximated on Android). @default 'transparent'
1244
1501
  */
1245
1502
  'glass-tint-color'?: string;
1246
1503
  /**
1247
- * Glass variant (iOS). @default 'regular'
1504
+ * Glass variant (iOS; approximated on Android). @default 'regular'
1248
1505
  */
1249
1506
  'glass-style'?: 'regular' | 'clear';
1250
1507
  /**
@@ -1758,6 +2015,10 @@ export declare class LynxTextarea extends LynxElementBase {
1758
2015
  }
1759
2016
  /**
1760
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]`).
1761
2022
  */
1762
2023
  export declare class LynxList extends LynxElementBase {
1763
2024
  /**
@@ -1823,14 +2084,6 @@ export declare class LynxList extends LynxElementBase {
1823
2084
  * Insert/remove animation style.
1824
2085
  */
1825
2086
  'update-animation'?: 'default' | 'none';
1826
- /**
1827
- * Gap between items on the main axis (CSS length).
1828
- */
1829
- 'list-main-axis-gap'?: string;
1830
- /**
1831
- * Gap between columns/rows on the cross axis (CSS length).
1832
- */
1833
- 'list-cross-axis-gap'?: string;
1834
2087
  /**
1835
2088
  * Required by Lynx's native list UI whenever the app uses the standard
1836
2089
  * dual-thread engine strategy (always true for AngularLynx) — without it
@@ -1929,14 +2182,6 @@ export declare class LynxList extends LynxElementBase {
1929
2182
  "alias": "update-animation";
1930
2183
  "required": false;
1931
2184
  };
1932
- "list-main-axis-gap": {
1933
- "alias": "list-main-axis-gap";
1934
- "required": false;
1935
- };
1936
- "list-cross-axis-gap": {
1937
- "alias": "list-cross-axis-gap";
1938
- "required": false;
1939
- };
1940
2185
  "enable-async-list": {
1941
2186
  "alias": "enable-async-list";
1942
2187
  "required": false;
@@ -1988,13 +2233,6 @@ export declare class LynxListItem extends LynxElementBase {
1988
2233
  * Estimated item size in px for layout pre-calculation.
1989
2234
  */
1990
2235
  'estimated-main-axis-size-px'?: number;
1991
- /**
1992
- * Deferred rendering. Pass `true` to defer, or an object to control
1993
- * whether the item unmounts when recycled.
1994
- */
1995
- defer?: boolean | {
1996
- unmountRecycled?: boolean;
1997
- };
1998
2236
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxListItem, never>;
1999
2237
  static ɵdir: i0.ɵɵDirectiveDeclaration<LynxListItem, "list-item", never, {
2000
2238
  "item-key": {
@@ -2025,10 +2263,6 @@ export declare class LynxListItem extends LynxElementBase {
2025
2263
  "alias": "estimated-main-axis-size-px";
2026
2264
  "required": false;
2027
2265
  };
2028
- "defer": {
2029
- "alias": "defer";
2030
- "required": false;
2031
- };
2032
2266
  }, {}, never, never, true, never>;
2033
2267
  }
2034
2268
  /**
@@ -2063,8 +2297,9 @@ export declare class LynxOverlay extends LynxElementBase {
2063
2297
  */
2064
2298
  visible?: boolean;
2065
2299
  /**
2066
- * Z-order layer (higher = above other overlays).
2067
- * 1 = default, 2 = status bar level, 3 = keyboard level, 4 = top.
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
2068
2303
  */
2069
2304
  level?: 1 | 2 | 3 | 4;
2070
2305
  /**
@@ -2386,7 +2621,10 @@ export declare class LynxSvg extends LynxElementBase {
2386
2621
  */
2387
2622
  export declare class LynxText extends LynxElementBase {
2388
2623
  /**
2389
- * Maximum number of lines before truncation with ellipsis.
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.
2390
2628
  */
2391
2629
  'text-maxline'?: number;
2392
2630
  /**
@@ -2558,45 +2796,13 @@ export declare class LynxVideo extends LynxElementBase {
2558
2796
  }, {}, never, never, true, never>;
2559
2797
  }
2560
2798
  /**
2561
- * General-purpose container element, equivalent to HTML `<div>`.
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}.
2562
2802
  */
2563
2803
  export declare class LynxView extends LynxElementBase {
2564
- /**
2565
- * Flatten the view into its parent's layer (Android only).
2566
- * Improves performance for non-interactive views.
2567
- */
2568
- flatten?: boolean;
2569
- /**
2570
- * Direction of pan-gesture interception.
2571
- * 0 = horizontal, 1 = vertical, 2 = none.
2572
- */
2573
- 'pan-intercept-direction'?: 0 | 1 | 2;
2574
- 'pan-intercept-scope'?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
2575
- 'consume-slide-event'?: [number, number][];
2576
- 'enable-touch-pseudo-propagation'?: boolean;
2577
2804
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxView, never>;
2578
- static ɵdir: i0.ɵɵDirectiveDeclaration<LynxView, "view", never, {
2579
- "flatten": {
2580
- "alias": "flatten";
2581
- "required": false;
2582
- };
2583
- "pan-intercept-direction": {
2584
- "alias": "pan-intercept-direction";
2585
- "required": false;
2586
- };
2587
- "pan-intercept-scope": {
2588
- "alias": "pan-intercept-scope";
2589
- "required": false;
2590
- };
2591
- "consume-slide-event": {
2592
- "alias": "consume-slide-event";
2593
- "required": false;
2594
- };
2595
- "enable-touch-pseudo-propagation": {
2596
- "alias": "enable-touch-pseudo-propagation";
2597
- "required": false;
2598
- };
2599
- }, {}, never, never, true, never>;
2805
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LynxView, "view", never, {}, {}, never, never, true, never>;
2600
2806
  }
2601
2807
  /**
2602
2808
  * Horizontally swipeable paging container.
@@ -2794,10 +3000,9 @@ export declare class LynxWebView extends LynxElementBase {
2794
3000
  * All Lynx native element directives as a single importable array.
2795
3001
  * Add to the `imports` of any component whose template uses Lynx elements.
2796
3002
  */
2797
- 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 import("@blotch/angular-lynx").LynxInputValueAccessor, typeof import("@blotch/angular-lynx").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];
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];
2798
3004
  export declare class LynxLogger {
2799
3005
  #private;
2800
- constructor();
2801
3006
  log(...args: unknown[]): void;
2802
3007
  warn(...args: unknown[]): void;
2803
3008
  error(...args: unknown[]): void;
@@ -2810,9 +3015,15 @@ export declare class LynxLogger {
2810
3015
  * Extensible map of custom native modules declared by the host app.
2811
3016
  *
2812
3017
  * App developers augment this interface to get type-safe access
2813
- * via {@link LynxNativeModule.getNativeModule}:
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}):
2814
3021
  *
2815
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
+ *
2816
3027
  * declare module '@blotch/angular-lynx' {
2817
3028
  * interface NativeModuleMap {
2818
3029
  * NativeLocalStorageModule: {
@@ -2824,7 +3035,17 @@ export declare class LynxLogger {
2824
3035
  * }
2825
3036
  * ```
2826
3037
  */
2827
- type NativeModuleMap = {};
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; };
2828
3049
  /**
2829
3050
  * Wraps the Lynx native module bridge and JS module registry as an Angular injectable.
2830
3051
  *
@@ -2836,6 +3057,12 @@ type NativeModuleMap = {};
2836
3057
  * values within a single LynxView. This is the same API used internally by
2837
3058
  * `LynxInitData` and `LynxGlobalData` (via `GlobalEventEmitter`).
2838
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
+ *
2839
3066
  * @usageNotes
2840
3067
  * ```typescript
2841
3068
  * const modules = inject(LynxNativeModule);
@@ -2863,13 +3090,14 @@ export declare class LynxNativeModule {
2863
3090
  * The native callback API is wrapped in a Promise for ergonomic
2864
3091
  * use with `async`/`await`.
2865
3092
  *
2866
- * Returns `undefined` when `NativeModules` is unavailable (web preview, tests).
3093
+ * Resolves `undefined` when there is no bridge (web preview, tests).
2867
3094
  */
2868
3095
  call<T = unknown>(name: string, params?: Record<string, unknown>): Promise<T | undefined>;
2869
3096
  /**
2870
- * Subscribes to a native event via `NativeModules.bridge.on()`.
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.
2871
3099
  *
2872
- * No-op when `NativeModules` is unavailable.
3100
+ * No-op when there is no bridge.
2873
3101
  */
2874
3102
  on(name: string, callback: (...args: unknown[]) => void): void;
2875
3103
  /**
@@ -2878,6 +3106,8 @@ export declare class LynxNativeModule {
2878
3106
  * Augment the {@link NativeModuleMap} interface for type-safe access:
2879
3107
  *
2880
3108
  * ```typescript
3109
+ * export {};
3110
+ *
2881
3111
  * declare module '@blotch/angular-lynx' {
2882
3112
  * interface NativeModuleMap {
2883
3113
  * NativeLocalStorageModule: { ... };
@@ -2887,25 +3117,35 @@ export declare class LynxNativeModule {
2887
3117
  * const storage = modules.getNativeModule('NativeLocalStorageModule');
2888
3118
  * ```
2889
3119
  *
2890
- * Returns `undefined` when `NativeModules` is unavailable or the module
2891
- * is not registered.
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.
2892
3129
  */
2893
- getNativeModule<K extends string>(name: K): K extends keyof NativeModuleMap ? NativeModuleMap[K] : unknown;
3130
+ getNativeModule<K extends string>(name: K): K extends keyof NativeModuleMap ? NativeModuleProxy<NativeModuleMap[K]> | undefined : unknown;
2894
3131
  /**
2895
3132
  * Retrieves a JS module registered within this LynxView.
2896
3133
  *
2897
3134
  * This wraps `lynx.getJSModule()` — the same API used internally
2898
- * for `GlobalEventEmitter`.
3135
+ * for `GlobalEventEmitter`. On the main thread it returns a proxy, as
3136
+ * getNativeModule() does.
2899
3137
  *
2900
- * Returns `undefined` when `lynx` is unavailable or the module
2901
- * is not registered.
3138
+ * Returns `undefined` when `lynx` is unavailable or, on the background
3139
+ * thread, when the module is not registered.
2902
3140
  */
2903
3141
  getJSModule<T = unknown>(name: string): T | undefined;
2904
3142
  /**
2905
3143
  * Registers a JS module for sharing within this LynxView.
2906
3144
  *
2907
3145
  * Other code (including native callbacks) can retrieve it via
2908
- * `getJSModule()` or `lynx.getJSModule()`.
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.
2909
3149
  *
2910
3150
  * No-op when `lynx` is unavailable.
2911
3151
  */
@@ -2913,40 +3153,9 @@ export declare class LynxNativeModule {
2913
3153
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxNativeModule, never>;
2914
3154
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
2915
3155
  }
2916
- /**
2917
- * A no-op animation returned when `animate()` is called on the background
2918
- * thread where `__ElementAnimate` is unavailable. Provides the same API
2919
- * surface as `LynxAnimation` so callers can call `.cancel()`, `.pause()`,
2920
- * `.play()` without crashing — the calls simply do nothing.
2921
- *
2922
- * Fixes: "Uncaught Error: animate() is only available on the main thread"
2923
- * in the Go web preview (and any background-thread context).
2924
- *
2925
- * Why needed: In the Lynx dual-thread model, Angular runs on the background
2926
- * thread where __ElementAnimate doesn't exist. Previously, calling
2927
- * element.animate() from a component (e.g. the animations example's "Tap to
2928
- * pulse" button) would throw, crashing the Go web preview on the docs site.
2929
- *
2930
- * Approach: Return a silent no-op instead of throwing. This matches how
2931
- * @lynx-js/web-core itself handles __ElementAnimate on the server — it's
2932
- * defined as `() => {}` (a no-op). We mirror that graceful degradation here.
2933
- * Alternatives considered:
2934
- * - Cross-thread bridge via lynx.getCoreContext().dispatchEvent() — correct
2935
- * long-term but complex; LynxBackgroundElement doesn't hold a native ref.
2936
- * - Removing animate() from the example — wrong because it's the primary
2937
- * demonstration of the JS animate API.
2938
- */
2939
- declare class NoopLynxAnimation implements Pick<Animation, 'id' | 'cancel' | 'pause' | 'play'> {
2940
- #private;
2941
- readonly id: string;
2942
- constructor();
2943
- play(): void;
2944
- pause(): void;
2945
- cancel(): void;
2946
- }
2947
3156
  type LynxEventType = 'bindEvent' | 'catchEvent' | 'capture-bindEvent' | 'capture-catchEvent' | 'global-bindEvent';
2948
3157
  declare const EVENT_PREFIXES: [string, LynxEventType][];
2949
- type BaseLynxElement = Pick<Element, 'setAttribute'> & {
3158
+ type BaseLynxElement = Pick<Element$1, 'setAttribute'> & {
2950
3159
  tagName: string;
2951
3160
  setProperty(name: string, value: any): void;
2952
3161
  getAttribute(name: string): string | null;
@@ -2957,6 +3166,11 @@ type BaseLynxElement = Pick<Element, 'setAttribute'> & {
2957
3166
  insertBefore(newChild: BaseLynxElement, refChild: BaseLynxElement | null): void;
2958
3167
  appendChild(newChild: BaseLynxElement): void;
2959
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;
2960
3174
  removeClass(name: string): void;
2961
3175
  remove(): void;
2962
3176
  parentNode(): BaseLynxElement | null;
@@ -2967,58 +3181,10 @@ type BaseLynxElement = Pick<Element, 'setAttribute'> & {
2967
3181
  animate(keyframes: Record<string, string | number>[], options?: number | LynxAnimationOptions): BaseLynxAnimation;
2968
3182
  /**
2969
3183
  * Invokes a native UI method on this element (e.g. setValue, scrollTo).
2970
- *
2971
- * Marked optional because it only exists on the main thread: LynxElement
2972
- * implements it via __InvokeUIMethod, while LynxBackgroundElement (used in
2973
- * tests and the background-thread context) does not — UIMethod calls have no
2974
- * meaning outside the native render thread. Callers should use invoke?.() so
2975
- * they become no-ops in test/background environments rather than crashing.
3184
+ * LynxElement implements it via __InvokeUIMethod.
2976
3185
  */
2977
- invoke?(methodName: string, params?: Record<string, unknown>): void;
3186
+ invoke(methodName: string, params?: Record<string, unknown>): void;
2978
3187
  };
2979
- /**
2980
- * Virtual element for the background thread where no native PAPI functions exist.
2981
- * Maintains an in-memory linked-list tree (parent/child/sibling pointers) that
2982
- * mirrors what LynxDocument builds on the main thread. Used by:
2983
- * - Angular's change detection (reads parentNode/nextSibling for view insertion)
2984
- * - querySelector/querySelectorAll (for testing and background-thread lookups)
2985
- * - LynxBackgroundDocument (creates these instead of native elements)
2986
- *
2987
- * Props, styles, classes, and events are stored in Maps/Sets but never sent to
2988
- * native — they exist so component code can read back what it set without
2989
- * crashing, and so the testing library can inspect element state.
2990
- */
2991
- declare class LynxBackgroundElement implements BaseLynxElement {
2992
- #private;
2993
- isRootPageElement: boolean;
2994
- tagName: string;
2995
- setProperty(name: string, value: any): void;
2996
- setAttribute(name: string, value: any): void;
2997
- getAttribute(name: string): string | null;
2998
- removeAttribute(name: string): void;
2999
- setStyle(key: string, value: unknown): void;
3000
- removeStyle(key: string): void;
3001
- setInlineStyles(inlineStyle: string): void;
3002
- insertBefore(newChild: LynxBackgroundElement, refChild: LynxBackgroundElement | null): void;
3003
- appendChild(newChild: LynxBackgroundElement): void;
3004
- addClass(name: string): void;
3005
- removeClass(name: string): void;
3006
- remove(): void;
3007
- parentNode(): BaseLynxElement | null;
3008
- nextSibling(): BaseLynxElement | null;
3009
- querySelector(selector: string): BaseLynxElement | null;
3010
- querySelectorAll(selector: string): BaseLynxElement[];
3011
- /**
3012
- * Previously threw: `throw new Error('animate() is only available on the
3013
- * main thread')`. This crashed the Go web preview on the docs site because
3014
- * the animations example's (bindtap) handler calls el.nativeElement.animate()
3015
- * which lands here on the background thread. Returning a no-op is safe —
3016
- * the animation won't visually play, but the caller's code (including
3017
- * .cancel() / .pause() / .play() chains) continues without error.
3018
- */
3019
- animate(_keyframes: Record<string, string | number>[], _options?: number | LynxAnimationOptions): NoopLynxAnimation;
3020
- addEventListener(name: string, cb: (event: any) => any): () => void;
3021
- }
3022
3188
  declare class LynxElement implements BaseLynxElement {
3023
3189
  #private;
3024
3190
  get element(): ElementRef;
@@ -3056,6 +3222,12 @@ declare class LynxElement implements BaseLynxElement {
3056
3222
  */
3057
3223
  setInitialText(text: string): void;
3058
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;
3059
3231
  getAttribute(name: string): string;
3060
3232
  removeAttribute(name: string): void;
3061
3233
  setStyle(key: string, value: unknown): void;
@@ -3064,6 +3236,7 @@ declare class LynxElement implements BaseLynxElement {
3064
3236
  insertBefore(newChild: LynxElement, refChild: LynxElement | null): void;
3065
3237
  appendChild(newChild: LynxElement): void;
3066
3238
  addClass(name: string): void;
3239
+ addScopeClass(name: string): void;
3067
3240
  /**
3068
3241
  * Lynx has no __RemoveClass PAPI — we must get current classes, filter,
3069
3242
  * and set back. This is O(n) per class removal but class lists on Lynx
@@ -3169,9 +3342,9 @@ declare const processPendingTextNormalization: () => void;
3169
3342
  * flush.) This mirrors the `<list>` path's own guard for the exact same case —
3170
3343
  * see `LynxListElement.#scheduleUpdate`.
3171
3344
  *
3172
- * Called from `LynxDocument`'s element creators — which only ever run on the
3173
- * main thread (the background thread uses LynxBackgroundDocument, which does not
3174
- * touch the native tree), so no thread guard is needed here. It schedules ONE
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
3175
3348
  * coalesced microtask (matching the list guard's `queueMicrotask`, not
3176
3349
  * `setTimeout` — flushing from a macrotask crashes the native engine), and is a
3177
3350
  * no-op while:
@@ -3263,9 +3436,10 @@ declare class LynxListElement extends LynxElement {
3263
3436
  */
3264
3437
  type PortalConfig = {
3265
3438
  /**
3266
- * Overlay z-level (1–4). Higher levels render above lower ones.
3439
+ * The overlay's layer, from 1 (the top) to 4 (the lowest), as on
3440
+ * `<overlay>`. Lynx's default is 1.
3267
3441
  */
3268
- level?: number;
3442
+ level?: 1 | 2 | 3 | 4;
3269
3443
  /**
3270
3444
  * Custom injector for the component's dependency injection context.
3271
3445
  */
@@ -3363,10 +3537,6 @@ type MainThreadFnHandle<TArgs extends unknown[] = unknown[], TReturn = unknown>
3363
3537
  readonly __return?: TReturn;
3364
3538
  };
3365
3539
  export declare const mainThreadFn: <TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn) => MainThreadFnHandle<TArgs, TReturn>;
3366
- /**
3367
- * Reset counter on HMR — called from runtime.ts before modules re-evaluate.
3368
- */
3369
- declare const __resetWorkletCounter: () => void;
3370
3540
  /**
3371
3541
  * Type definition for background function handles used by {@link backgroundFn}.
3372
3542
  */
@@ -3377,32 +3547,78 @@ type BackgroundFnHandle<TArgs extends unknown[] = unknown[], TReturn = unknown>
3377
3547
  readonly __args?: TArgs;
3378
3548
  readonly __return?: TReturn;
3379
3549
  };
3380
- export declare const backgroundFn: <TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn) => BackgroundFnHandle<TArgs, TReturn>;
3381
3550
  /**
3382
- * Reset counter on HMR.
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.
3383
3558
  */
3384
- declare const __resetBgWorkletCounter: () => void;
3559
+ export declare const backgroundFn: <TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn, id?: string) => BackgroundFnHandle<TArgs, TReturn>;
3385
3560
  export declare class MainThreadRef<T> {
3386
3561
  #private;
3387
- readonly _wvid: number;
3388
- constructor(initValue: T);
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);
3389
3569
  get current(): T;
3390
3570
  set current(value: T);
3391
3571
  /**
3392
3572
  * Serialization hook for cross-thread transfer. JSON.stringify calls this
3393
3573
  * when the ref is passed as a param to dispatchEvent (MTS/background RPC).
3394
- * The receiving thread's transformParams() resolves { _wvid } back to the
3395
- * registered MainThreadRef instance.
3574
+ * The receiving thread resolves { _wvid } back to its own registered
3575
+ * MainThreadRef instance.
3396
3576
  */
3397
3577
  toJSON(): {
3398
- _wvid: number;
3578
+ _wvid: number | string;
3399
3579
  };
3400
3580
  }
3401
- export declare const createMainThreadRef: <T>(initValue: T) => MainThreadRef<T>;
3402
3581
  /**
3403
- * Reset counter on HMR.
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.
3404
3588
  */
3405
- declare const __resetRefCounter: () => void;
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
+ }
3406
3622
  /**
3407
3623
  * Wraps a native ElementRef (elementRefptr) with the @lynx-js/types
3408
3624
  * MainThread.Element API surface. Created by runWorklet's param transformation
@@ -3428,21 +3644,24 @@ export declare class MainThreadElement {
3428
3644
  invoke(methodName: string, params?: Record<string, unknown>): Promise<unknown>;
3429
3645
  animate(keyframes: Record<string, number | string>[], options?: number | LynxAnimationOptions): LynxAnimation;
3430
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
+ *
3431
3650
  * Not part of the official @lynx-js/types Element interface, but useful for
3432
- * touch-tracking calculations. Uses __GetComputedStyleByKey when available.
3433
- */
3434
- getBoundingClientRect(): {
3435
- left: number;
3436
- top: number;
3437
- right: number;
3438
- bottom: number;
3439
- width: number;
3440
- height: number;
3441
- };
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>;
3442
3659
  }
3443
3660
  /**
3444
- * Plain functions are also accepted because the worklet build plugin transforms
3445
- * them into MainThreadFnHandle objects at compile time.
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.
3446
3665
  */
3447
3666
  type MaybeHandle = MainThreadFnHandle | ((...args: any[]) => any) | undefined | null;
3448
3667
  /**
@@ -3450,14 +3669,16 @@ type MaybeHandle = MainThreadFnHandle | ((...args: any[]) => any) | undefined |
3450
3669
  * Lynx's main-thread (Lepus) event dispatch.
3451
3670
  *
3452
3671
  * Why a dedicated directive and not the renderer's listen() path:
3453
- * - Normal `(bindtap)` events are delivered to the background JS thread and
3454
- * incur a thread hop on every dispatch — fine for one-shot taps, but too
3455
- * slow for gesture-driven UI (scroll-tracking, drag, pinch) where the
3456
- * handler needs to mutate styles at native frame rate.
3457
- * - The `mainThreadBind*` / `mainThreadCatch*` family registers the handler
3458
- * as a *worklet* with `_workletType: 'main-thread'`, so Lynx invokes it
3459
- * directly on the Lepus thread where __AddInlineStyle / __SetAttribute are
3460
- * synchronous. There is no thread hop and no background JS involvement.
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.
3461
3682
  * - These inputs cannot be expressed as @Output() because Angular would route
3462
3683
  * them through its own event subscription system and the underlying
3463
3684
  * worklet handle would never be passed to __AddEvent.
@@ -3476,6 +3697,12 @@ export declare class LynxMainThreadEvent implements OnChanges, OnDestroy {
3476
3697
  mainThreadCatchtouchmove?: MaybeHandle;
3477
3698
  mainThreadBindtouchend?: MaybeHandle;
3478
3699
  mainThreadCatchtouchend?: MaybeHandle;
3700
+ mainThreadBindmousedown?: MaybeHandle;
3701
+ mainThreadCatchmousedown?: MaybeHandle;
3702
+ mainThreadBindmousemove?: MaybeHandle;
3703
+ mainThreadCatchmousemove?: MaybeHandle;
3704
+ mainThreadBindmouseup?: MaybeHandle;
3705
+ mainThreadCatchmouseup?: MaybeHandle;
3479
3706
  mainThreadBindlongpress?: MaybeHandle;
3480
3707
  mainThreadCatchlongpress?: MaybeHandle;
3481
3708
  mainThreadBindscroll?: MaybeHandle;
@@ -3487,7 +3714,7 @@ export declare class LynxMainThreadEvent implements OnChanges, OnDestroy {
3487
3714
  ngOnChanges(changes: SimpleChanges): void;
3488
3715
  ngOnDestroy(): void;
3489
3716
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxMainThreadEvent, never>;
3490
- static ɵdir: i0.ɵɵDirectiveDeclaration<LynxMainThreadEvent, "[mainThreadBindtap],[mainThreadCatchtap],[mainThreadBindtouchstart],[mainThreadCatchtouchstart],[mainThreadBindtouchmove],[mainThreadCatchtouchmove],[mainThreadBindtouchend],[mainThreadCatchtouchend],[mainThreadBindlongpress],[mainThreadCatchlongpress],[mainThreadBindscroll],[mainThreadCatchscroll],[mainThreadBindanimationstart],[mainThreadBindanimationend],[mainThreadBindtransitionend],[mainThreadBindlayoutchange]", 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, {
3491
3718
  "mainThreadBindtap": {
3492
3719
  "alias": "mainThreadBindtap";
3493
3720
  "required": false;
@@ -3520,6 +3747,30 @@ export declare class LynxMainThreadEvent implements OnChanges, OnDestroy {
3520
3747
  "alias": "mainThreadCatchtouchend";
3521
3748
  "required": false;
3522
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
+ };
3523
3774
  "mainThreadBindlongpress": {
3524
3775
  "alias": "mainThreadBindlongpress";
3525
3776
  "required": false;
@@ -3555,43 +3806,23 @@ export declare class LynxMainThreadEvent implements OnChanges, OnDestroy {
3555
3806
  }, {}, never, never, true, never>;
3556
3807
  }
3557
3808
  /**
3558
- * Injectable service for calling main-thread (Lepus) functions. From the
3559
- * background thread it uses Lynx's cross-thread RPC via JSContext events:
3809
+ * Injectable service for calling main-thread (Lepus) functions from Angular
3810
+ * code, and getting their return values.
3560
3811
  *
3561
- * background calls runOnMainThread(handle, ...args)
3562
- * → dispatches 'Lynx.Worklet.runWorkletCtx' with { worklet, params, resolveId }
3563
- * → main thread's listener (in runtime.ts) invokes the registered worklet fn
3564
- * → dispatches 'Lynx.Worklet.FunctionCallRet' with { resolveId, returnValue }
3565
- * → background thread's listener resolves the Promise
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.
3566
3816
  *
3567
- * This enables background-thread Angular code (services, effects) to trigger
3568
- * main-thread imperative operations (animate, measure, invoke UI methods)
3569
- * with proper async/await ergonomics.
3570
- *
3571
- * It is also safe to call from code already running on the main thread. The
3572
- * renderer registers Angular `(bind*)`/`(catch*)` event handlers as main-thread
3573
- * worklets, so a handler like `(bindtap)="flash()"` executes on the Lepus thread
3574
- * — and any runOnMainThread() call it makes originates there too. Rather than
3575
- * fail (there is no other thread to be "called from"), we detect that case and
3576
- * invoke the target worklet in-place, so the same call site works regardless of
3577
- * which thread reaches it.
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.
3578
3820
  */
3579
3821
  export declare class LynxMainThread {
3580
3822
  runOnMainThread<TArgs extends unknown[], TReturn>(handle: MainThreadFnHandle<TArgs, TReturn>, ...args: TArgs): Promise<TReturn>;
3581
3823
  static ɵfac: i0.ɵɵFactoryDeclaration<LynxMainThread, never>;
3582
3824
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3583
3825
  }
3584
- declare namespace MainThread {
3585
- type Element = Element;
3586
- type TouchEvent = TouchEvent;
3587
- type MouseEvent = MouseEvent;
3588
- type WheelEvent = WheelEvent;
3589
- type KeyEvent = KeyEvent;
3590
- type AnimationEvent = AnimationEvent;
3591
- type TransitionEvent = TransitionEvent;
3592
- type LayoutChangeEvent = LayoutChangeEvent;
3593
- type UIAppearanceEvent = UIAppearanceEvent;
3594
- }
3595
3826
  /**
3596
3827
  * Resource priority hint for the native prefetch engine.
3597
3828
  */
@@ -3645,8 +3876,9 @@ type PrefetchResultDetail = {
3645
3876
  * with a Promise-based API for preloading images and videos into the native
3646
3877
  * cache before they're needed for display.
3647
3878
  *
3648
- * Only available on the background thread — these APIs are not exposed on
3649
- * the main thread.
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).
3650
3882
  *
3651
3883
  * @usageNotes
3652
3884
  * ```typescript
@@ -3768,7 +4000,8 @@ type SessionStorageSubscription = {
3768
4000
  * subscribe/unsubscribe at all — and `getSessionStorageItem` is
3769
4001
  * *synchronous*, taking just the key and returning the value directly.
3770
4002
  * Calling it with a callback (the background-thread shape) throws a native
3771
- * "GetSessionStorageItem param size should be 1" fatal error.
4003
+ * "GetSessionStorageItem param size should be 1" fatal error. Subscriptions
4004
+ * made there go through the background thread (see background-call.ts).
3772
4005
  *
3773
4006
  * @usageNotes
3774
4007
  * ```typescript
@@ -3858,6 +4091,10 @@ export declare class LynxSessionStorage {
3858
4091
  * `SystemInfo` is populated once when the Lynx view initializes and
3859
4092
  * is read-only for the lifetime of the app — the values never change.
3860
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
+ *
3861
4098
  * @usageNotes
3862
4099
  * ```typescript
3863
4100
  * const systemInfo = inject(LynxSystemInfo);
@@ -4119,13 +4356,25 @@ export declare class LynxTransitionGroup<T> {
4119
4356
  /**
4120
4357
  * Central DI configuration for the Lynx renderer. Must be included in every
4121
4358
  * Lynx Angular app's providers (typically via app.config.ts). Sets up:
4122
- * 1. Thread-aware document (LynxDocument vs LynxBackgroundDocument)
4359
+ * 1. The document (LynxDocument, or LynxHydrateDocument for SSR)
4123
4360
  * 2. DOCUMENT stub (Angular requires this token but Lynx has no DOM Document)
4124
4361
  * 3. APP_BASE_HREF (prevents BrowserPlatformLocation from crashing)
4125
4362
  * 4. Renderer factory (creates LynxRenderer / EmulatedLynxRenderer)
4126
4363
  * 5. Error handler (routes to _ReportError + __lynxLastError)
4127
4364
  */
4128
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;
4129
4378
  /**
4130
4379
  * In-memory LocationStrategy for Lynx — equivalent to React Router's MemoryRouter.
4131
4380
  *
@@ -4141,6 +4390,13 @@ export declare const provideRenderer: () => EnvironmentProviders;
4141
4390
  */
4142
4391
  export declare class LynxLocationStrategy extends LocationStrategy {
4143
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>;
4144
4400
  path(): string;
4145
4401
  prepareExternalUrl(internal: string): string;
4146
4402
  getBaseHref(): string;
@@ -4193,25 +4449,32 @@ export declare class LynxPlatformLocation extends PlatformLocation {
4193
4449
  /**
4194
4450
  * Route reuse strategy that keeps component views alive across navigations.
4195
4451
  *
4196
- * ## Why this is required on Lynx
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
+ * ```
4197
4462
  *
4198
- * Lynx's native element APIs (`__CreateView`, `__CreateText`, etc.) allocate
4199
- * elements in a fixed-size native pool. `__RemoveElement` detaches an element
4200
- * from the tree but does NOT free its pool slot — there is no `__ReleaseElement`
4201
- * API in Lynx's public surface. Angular's default `RouteReuseStrategy` destroys
4202
- * components on every navigation, creating fresh native elements each time. Those
4203
- * freed elements accumulate in the pool until it overflows (~256 slots on device),
4204
- * causing a hard native crash on the 9th navigation in a back-and-forth pattern.
4463
+ * Nothing is ever evicted, and `ngOnDestroy()` doesn't run when you leave a
4464
+ * route.
4205
4465
  *
4206
- * ## What this strategy does
4466
+ * ## Why it exists
4207
4467
  *
4208
- * Instead of destroying a component when navigating away, Angular calls
4209
- * `ViewContainerRef.detach()`. The component's DOM elements are removed from the
4210
- * native tree (the slots are occupied but unused). When navigating back,
4211
- * `ViewContainerRef.insert()` re-adds those same native elements to the tree —
4212
- * reusing their existing pool slots with no new allocations. The pool stays bounded
4213
- * by (initial elements) + (max elements for any single route), regardless of how
4214
- * many times the user navigates.
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.
4215
4478
  */
4216
4479
  export declare class LynxRouteReuseStrategy implements RouteReuseStrategy {
4217
4480
  #private;
@@ -4252,10 +4515,187 @@ export declare const provideRouter: (routes: Routes, ...features: RouterFeatures
4252
4515
  * convention). No-op off-device where `_ReportError` is absent.
4253
4516
  */
4254
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;
4255
4687
  /**
4256
4688
  * Bootstrap Angular application on the Lynx runtime. Waits for the main thread to
4257
4689
  * signal it's ready before initializing the framework, then registers global
4258
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).
4259
4699
  */
4260
4700
  export declare const bootstrapApplication: (rootComponent: Type<unknown>, options?: ApplicationConfig) => Promise<ApplicationRef>;
4261
4701
  declare global {
@@ -4303,25 +4743,15 @@ declare global {
4303
4743
  var __LYNX_SOURCE_LOCALE__: string;
4304
4744
  interface Window {
4305
4745
  registerWorklet: (type: string, id: string, fn: Function) => void;
4306
- __workletRefMap: Record<number, {
4746
+ __workletRefMap: Record<number | string, {
4307
4747
  current: unknown;
4308
4748
  }>;
4309
- __lynxMtsPendingResolvers: Record<number, {
4310
- resolve: (v: unknown) => void;
4311
- reject: (e: unknown) => void;
4312
- }>;
4313
- __lynxMtsNextResolveId: () => number;
4314
4749
  __lynxRunMainThreadWorklet: (wkltId: string, args: unknown[]) => unknown;
4315
4750
  }
4316
4751
  var registerWorklet: (type: string, id: string, fn: Function) => void;
4317
- var __workletRefMap: Record<number, {
4752
+ var __workletRefMap: Record<number | string, {
4318
4753
  current: unknown;
4319
4754
  }>;
4320
- var __lynxMtsPendingResolvers: Record<number, {
4321
- resolve: (v: unknown) => void;
4322
- reject: (e: unknown) => void;
4323
- }>;
4324
- var __lynxMtsNextResolveId: () => number;
4325
4755
  var __lynxRunMainThreadWorklet: (wkltId: string, args: unknown[]) => unknown;
4326
4756
  function runOnBackground(handle: {
4327
4757
  _wkltId: string;
@@ -4329,21 +4759,31 @@ declare global {
4329
4759
  }
4330
4760
  declare global {
4331
4761
  interface HTMLElementEventMap {
4332
- bindtap: TouchEvent$1;
4333
- catchtap: TouchEvent$1;
4334
- 'capture-bindtap': TouchEvent$1;
4335
- 'capture-catchtap': TouchEvent$1;
4336
- 'global-bindtap': TouchEvent$1;
4337
- bindtouchstart: TouchEvent$1;
4338
- bindtouchend: TouchEvent$1;
4339
- bindtouchmove: TouchEvent$1;
4340
- bindtouchcancel: TouchEvent$1;
4341
- bindlongpress: TouchEvent$1;
4342
- catchtouchstart: TouchEvent$1;
4343
- catchtouchend: TouchEvent$1;
4344
- catchtouchmove: TouchEvent$1;
4345
- catchtouchcancel: TouchEvent$1;
4346
- catchlongpress: TouchEvent$1;
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;
4347
4787
  }
4348
4788
  }
4349
- export type { BackgroundFnHandle, BaseLynxAnimation, DataProcessorDefinition, DevToolsStats, ExposureEventDetail, FlingGestureEvent, GestureCallback, GestureCallbackWithState, GestureEvent, GlobalData, GlobalExposureEvent, InitData, InitDataRaw, LongPressGestureEvent, LynxAnimationOptions, LynxFontEntry, LynxFontFaceConfig, LynxFontStatus, MainThread, MainThreadFnHandle, NativeModuleMap, ObserverFrameRateOptions, PanGestureEvent, PinchGestureEvent, PortalConfig, PrefetchCacheTarget, PrefetchPriority, PrefetchRequest, PrefetchResultDetail, RotationGestureEvent, SessionStorageSubscription, TapGestureEvent };
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 };