react-native-gtkx 0.2.0-alpha.2 → 0.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/aliases/index.d.ts +84 -0
- package/dist/aliases/index.js +208 -0
- package/dist/aliases/index.js.map +1 -0
- package/dist/animated/index.d.ts +2 -0
- package/dist/animated/index.js +5 -0
- package/dist/animated/index.js.map +1 -1
- package/dist/animated/types.d.ts +1 -0
- package/dist/animated/types.js.map +1 -1
- package/dist/animated/value-animation.js +17 -4
- package/dist/animated/value-animation.js.map +1 -1
- package/dist/apis/host.gtkx.js +9 -12
- package/dist/apis/host.gtkx.js.map +1 -1
- package/dist/apis/index.d.ts +4 -2
- package/dist/apis/index.js +2 -0
- package/dist/apis/index.js.map +1 -1
- package/dist/apis/keyboard.d.ts +60 -0
- package/dist/apis/keyboard.js +63 -0
- package/dist/apis/keyboard.js.map +1 -0
- package/dist/apis/log-box.d.ts +15 -0
- package/dist/apis/log-box.js +46 -0
- package/dist/apis/log-box.js.map +1 -0
- package/dist/apis/platform.d.ts +18 -1
- package/dist/apis/platform.js.map +1 -1
- package/dist/common/index.d.ts +0 -1
- package/dist/common/index.js +24 -1
- package/dist/common/index.js.map +1 -1
- package/dist/components/animated.d.ts +70 -6
- package/dist/components/animated.js +559 -46
- package/dist/components/animated.js.map +1 -1
- package/dist/components/driven-size.d.ts +27 -0
- package/dist/components/driven-size.js +85 -0
- package/dist/components/driven-size.js.map +1 -0
- package/dist/components/find-node-handle.d.ts +11 -0
- package/dist/components/find-node-handle.js +53 -0
- package/dist/components/find-node-handle.js.map +1 -0
- package/dist/components/flat-list.d.ts +3 -2
- package/dist/components/flat-list.js.map +1 -1
- package/dist/components/frame-scheduler.d.ts +16 -0
- package/dist/components/frame-scheduler.js +37 -0
- package/dist/components/frame-scheduler.js.map +1 -0
- package/dist/components/image.d.ts +6 -1
- package/dist/components/image.js +15 -4
- package/dist/components/image.js.map +1 -1
- package/dist/components/index.d.ts +7 -5
- package/dist/components/index.js +5 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/measure.d.ts +51 -1
- package/dist/components/measure.js +101 -2
- package/dist/components/measure.js.map +1 -1
- package/dist/components/pressable.d.ts +61 -1
- package/dist/components/pressable.js +151 -4
- package/dist/components/pressable.js.map +1 -1
- package/dist/components/rect-store.d.ts +58 -0
- package/dist/components/rect-store.js +124 -3
- package/dist/components/rect-store.js.map +1 -1
- package/dist/components/root.js +6 -1
- package/dist/components/root.js.map +1 -1
- package/dist/components/scroll-phase.d.ts +35 -0
- package/dist/components/scroll-phase.js +26 -0
- package/dist/components/scroll-phase.js.map +1 -0
- package/dist/components/scroll-view.d.ts +39 -3
- package/dist/components/scroll-view.js +378 -43
- package/dist/components/scroll-view.js.map +1 -1
- package/dist/components/text-input.js +9 -25
- package/dist/components/text-input.js.map +1 -1
- package/dist/components/text.d.ts +6 -2
- package/dist/components/text.js +43 -8
- package/dist/components/text.js.map +1 -1
- package/dist/components/use-focus.d.ts +27 -0
- package/dist/components/use-focus.js +116 -0
- package/dist/components/use-focus.js.map +1 -0
- package/dist/components/use-layout-child.d.ts +13 -1
- package/dist/components/use-layout-child.js +188 -5
- package/dist/components/use-layout-child.js.map +1 -1
- package/dist/components/view.d.ts +5 -2
- package/dist/components/view.js +18 -13
- package/dist/components/view.js.map +1 -1
- package/dist/components/virtualized-list.d.ts +45 -5
- package/dist/components/virtualized-list.js +90 -24
- package/dist/components/virtualized-list.js.map +1 -1
- package/dist/components/wheel-scroll-session.d.ts +7 -0
- package/dist/components/wheel-scroll-session.js +53 -0
- package/dist/components/wheel-scroll-session.js.map +1 -0
- package/dist/components/widget-retention.d.ts +35 -0
- package/dist/components/widget-retention.js +169 -0
- package/dist/components/widget-retention.js.map +1 -0
- package/dist/contracts.d.ts +4 -0
- package/dist/contracts.js.map +1 -1
- package/dist/dnd/context.d.ts +69 -0
- package/dist/dnd/context.js +149 -0
- package/dist/dnd/context.js.map +1 -0
- package/dist/dnd/draggable.d.ts +59 -0
- package/dist/dnd/draggable.js +149 -0
- package/dist/dnd/draggable.js.map +1 -0
- package/dist/dnd/droppable.d.ts +24 -0
- package/dist/dnd/droppable.js +74 -0
- package/dist/dnd/droppable.js.map +1 -0
- package/dist/dnd/gtk-controllers.d.ts +39 -0
- package/dist/dnd/gtk-controllers.js +110 -0
- package/dist/dnd/gtk-controllers.js.map +1 -0
- package/dist/dnd/index.d.ts +6 -0
- package/dist/dnd/index.js +31 -0
- package/dist/dnd/index.js.map +1 -0
- package/dist/dnd/order.d.ts +7 -0
- package/dist/dnd/order.js +20 -0
- package/dist/dnd/order.js.map +1 -0
- package/dist/dnd/payload.d.ts +14 -0
- package/dist/dnd/payload.js +41 -0
- package/dist/dnd/payload.js.map +1 -0
- package/dist/dnd/sortable.d.ts +49 -0
- package/dist/dnd/sortable.js +307 -0
- package/dist/dnd/sortable.js.map +1 -0
- package/dist/dnd/types.d.ts +290 -0
- package/dist/dnd/types.js +25 -0
- package/dist/dnd/types.js.map +1 -0
- package/dist/gesture-handler-compat/builder.d.ts +251 -0
- package/dist/gesture-handler-compat/builder.js +513 -0
- package/dist/gesture-handler-compat/builder.js.map +1 -0
- package/dist/gesture-handler-compat/composition.d.ts +23 -0
- package/dist/gesture-handler-compat/composition.js +111 -0
- package/dist/gesture-handler-compat/composition.js.map +1 -0
- package/dist/gesture-handler-compat/deciders.d.ts +3 -0
- package/dist/gesture-handler-compat/deciders.js +47 -0
- package/dist/gesture-handler-compat/deciders.js.map +1 -0
- package/dist/gesture-handler-compat/detector-runtime.d.ts +44 -0
- package/dist/gesture-handler-compat/detector-runtime.js +374 -0
- package/dist/gesture-handler-compat/detector-runtime.js.map +1 -0
- package/dist/gesture-handler-compat/detector.d.ts +22 -0
- package/dist/gesture-handler-compat/detector.js +104 -0
- package/dist/gesture-handler-compat/detector.js.map +1 -0
- package/dist/gesture-handler-compat/fling.d.ts +24 -0
- package/dist/gesture-handler-compat/fling.js +123 -0
- package/dist/gesture-handler-compat/fling.js.map +1 -0
- package/dist/gesture-handler-compat/force-touch.d.ts +13 -0
- package/dist/gesture-handler-compat/force-touch.js +40 -0
- package/dist/gesture-handler-compat/force-touch.js.map +1 -0
- package/dist/gesture-handler-compat/hooks.d.ts +157 -0
- package/dist/gesture-handler-compat/hooks.js +268 -0
- package/dist/gesture-handler-compat/hooks.js.map +1 -0
- package/dist/gesture-handler-compat/hover.d.ts +2 -0
- package/dist/gesture-handler-compat/hover.js +22 -0
- package/dist/gesture-handler-compat/hover.js.map +1 -0
- package/dist/gesture-handler-compat/index.d.ts +98 -0
- package/dist/gesture-handler-compat/index.js +255 -0
- package/dist/gesture-handler-compat/index.js.map +1 -0
- package/dist/gesture-handler-compat/long-press.d.ts +6 -0
- package/dist/gesture-handler-compat/long-press.js +21 -0
- package/dist/gesture-handler-compat/long-press.js.map +1 -0
- package/dist/gesture-handler-compat/manual.d.ts +2 -0
- package/dist/gesture-handler-compat/manual.js +18 -0
- package/dist/gesture-handler-compat/manual.js.map +1 -0
- package/dist/gesture-handler-compat/native.d.ts +7 -0
- package/dist/gesture-handler-compat/native.js +34 -0
- package/dist/gesture-handler-compat/native.js.map +1 -0
- package/dist/gesture-handler-compat/orchestrator.d.ts +77 -0
- package/dist/gesture-handler-compat/orchestrator.js +284 -0
- package/dist/gesture-handler-compat/orchestrator.js.map +1 -0
- package/dist/gesture-handler-compat/pan.d.ts +23 -0
- package/dist/gesture-handler-compat/pan.js +116 -0
- package/dist/gesture-handler-compat/pan.js.map +1 -0
- package/dist/gesture-handler-compat/recognizer.d.ts +268 -0
- package/dist/gesture-handler-compat/recognizer.js +1056 -0
- package/dist/gesture-handler-compat/recognizer.js.map +1 -0
- package/dist/gesture-handler-compat/relations.d.ts +43 -0
- package/dist/gesture-handler-compat/relations.js +128 -0
- package/dist/gesture-handler-compat/relations.js.map +1 -0
- package/dist/gesture-handler-compat/tap.d.ts +6 -0
- package/dist/gesture-handler-compat/tap.js +29 -0
- package/dist/gesture-handler-compat/tap.js.map +1 -0
- package/dist/gesture-handler-compat/touchpad.d.ts +41 -0
- package/dist/gesture-handler-compat/touchpad.js +64 -0
- package/dist/gesture-handler-compat/touchpad.js.map +1 -0
- package/dist/gesture-handler-compat/types.d.ts +441 -0
- package/dist/gesture-handler-compat/types.js +167 -0
- package/dist/gesture-handler-compat/types.js.map +1 -0
- package/dist/gtk/controllers.d.ts +39 -0
- package/dist/gtk/controllers.js +92 -0
- package/dist/gtk/controllers.js.map +1 -0
- package/dist/gtk/index.d.ts +2 -1
- package/dist/gtk/index.js +7 -1
- package/dist/gtk/index.js.map +1 -1
- package/dist/gtkx/bridge/geometry.js +6 -4
- package/dist/gtkx/bridge/geometry.js.map +1 -1
- package/dist/gtkx/bridge/index.d.ts +5 -3
- package/dist/gtkx/bridge/index.js +6 -3
- package/dist/gtkx/bridge/index.js.map +1 -1
- package/dist/gtkx/bridge/slot-portal.js.map +1 -1
- package/dist/gtkx/bridge/use-signal.js +1 -1
- package/dist/gtkx/bridge/use-signal.js.map +1 -1
- package/dist/gtkx/bridge/view-box.d.ts +56 -0
- package/dist/gtkx/bridge/view-box.js +394 -9
- package/dist/gtkx/bridge/view-box.js.map +1 -1
- package/dist/gtkx/bridge/widget-css.d.ts +17 -0
- package/dist/gtkx/bridge/widget-css.js +72 -0
- package/dist/gtkx/bridge/widget-css.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/driven-size.d.ts +12 -0
- package/dist/layout/driven-size.js +70 -0
- package/dist/layout/driven-size.js.map +1 -0
- package/dist/layout/engine.d.ts +17 -1
- package/dist/layout/engine.js +3 -20
- package/dist/layout/engine.js.map +1 -1
- package/dist/layout/node.d.ts +13 -0
- package/dist/layout/node.js +14 -0
- package/dist/layout/node.js.map +1 -1
- package/dist/layout/yoga.d.ts +3 -2
- package/dist/layout/yoga.js +5 -2
- package/dist/layout/yoga.js.map +1 -1
- package/dist/mcp/data/generated.d.ts +257 -60
- package/dist/mcp/data/generated.js +306 -62
- package/dist/mcp/data/generated.js.map +1 -1
- package/dist/metro/index.d.ts +10 -0
- package/dist/metro/index.js +21 -12
- package/dist/metro/index.js.map +1 -1
- package/dist/navigation/sidebar.d.ts +16 -0
- package/dist/navigation/sidebar.js +65 -1
- package/dist/navigation/sidebar.js.map +1 -1
- package/dist/reanimated-compat/animated-ref.d.ts +32 -0
- package/dist/reanimated-compat/animated-ref.js +57 -0
- package/dist/reanimated-compat/animated-ref.js.map +1 -0
- package/dist/reanimated-compat/animation.d.ts +177 -0
- package/dist/reanimated-compat/animation.js +540 -0
- package/dist/reanimated-compat/animation.js.map +1 -0
- package/dist/reanimated-compat/color.d.ts +28 -0
- package/dist/reanimated-compat/color.js +249 -0
- package/dist/reanimated-compat/color.js.map +1 -0
- package/dist/reanimated-compat/decay.d.ts +39 -0
- package/dist/reanimated-compat/decay.js +96 -0
- package/dist/reanimated-compat/decay.js.map +1 -0
- package/dist/reanimated-compat/easing.d.ts +30 -0
- package/dist/reanimated-compat/easing.js +76 -0
- package/dist/reanimated-compat/easing.js.map +1 -0
- package/dist/reanimated-compat/hooks.d.ts +14 -0
- package/dist/reanimated-compat/hooks.js +217 -0
- package/dist/reanimated-compat/hooks.js.map +1 -0
- package/dist/reanimated-compat/index.d.ts +258 -0
- package/dist/reanimated-compat/index.js +464 -0
- package/dist/reanimated-compat/index.js.map +1 -0
- package/dist/reanimated-compat/interpolation.d.ts +18 -0
- package/dist/reanimated-compat/interpolation.js +122 -0
- package/dist/reanimated-compat/interpolation.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-config.d.ts +43 -0
- package/dist/reanimated-compat/layout-animation-config.js +78 -0
- package/dist/reanimated-compat/layout-animation-config.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-presets.d.ts +117 -0
- package/dist/reanimated-compat/layout-animation-presets.js +498 -0
- package/dist/reanimated-compat/layout-animation-presets.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-runtime.d.ts +21 -0
- package/dist/reanimated-compat/layout-animation-runtime.js +311 -0
- package/dist/reanimated-compat/layout-animation-runtime.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-view.d.ts +27 -0
- package/dist/reanimated-compat/layout-animation-view.js +266 -0
- package/dist/reanimated-compat/layout-animation-view.js.map +1 -0
- package/dist/reanimated-compat/layout-animation.d.ts +171 -0
- package/dist/reanimated-compat/layout-animation.js +469 -0
- package/dist/reanimated-compat/layout-animation.js.map +1 -0
- package/dist/reanimated-compat/layout-transitions.d.ts +83 -0
- package/dist/reanimated-compat/layout-transitions.js +350 -0
- package/dist/reanimated-compat/layout-transitions.js.map +1 -0
- package/dist/reanimated-compat/mutable.d.ts +29 -0
- package/dist/reanimated-compat/mutable.js +139 -0
- package/dist/reanimated-compat/mutable.js.map +1 -0
- package/dist/reanimated-compat/props.d.ts +18 -0
- package/dist/reanimated-compat/props.js +111 -0
- package/dist/reanimated-compat/props.js.map +1 -0
- package/dist/reanimated-compat/scroll-handler.d.ts +119 -0
- package/dist/reanimated-compat/scroll-handler.js +274 -0
- package/dist/reanimated-compat/scroll-handler.js.map +1 -0
- package/dist/reanimated-compat/scroll-offset.d.ts +12 -0
- package/dist/reanimated-compat/scroll-offset.js +104 -0
- package/dist/reanimated-compat/scroll-offset.js.map +1 -0
- package/dist/reanimated-compat/style.d.ts +90 -0
- package/dist/reanimated-compat/style.js +452 -0
- package/dist/reanimated-compat/style.js.map +1 -0
- package/dist/reanimated-compat/test-timers.d.ts +28 -0
- package/dist/reanimated-compat/test-timers.js +136 -0
- package/dist/reanimated-compat/test-timers.js.map +1 -0
- package/dist/reanimated-compat/threads.d.ts +13 -0
- package/dist/reanimated-compat/threads.js +41 -0
- package/dist/reanimated-compat/threads.js.map +1 -0
- package/dist/reanimated-compat/tracking.d.ts +41 -0
- package/dist/reanimated-compat/tracking.js +106 -0
- package/dist/reanimated-compat/tracking.js.map +1 -0
- package/dist/reanimated-compat/updater-animations.d.ts +36 -0
- package/dist/reanimated-compat/updater-animations.js +273 -0
- package/dist/reanimated-compat/updater-animations.js.map +1 -0
- package/dist/responder/system.d.ts +80 -7
- package/dist/responder/system.js +143 -23
- package/dist/responder/system.js.map +1 -1
- package/dist/responder/use-responder.d.ts +11 -0
- package/dist/responder/use-responder.js +225 -6
- package/dist/responder/use-responder.js.map +1 -1
- package/dist/runner/host-dev.js +1 -1
- package/dist/runner/host-dev.js.map +1 -1
- package/dist/runner/host.js +1 -1
- package/dist/runner/host.js.map +1 -1
- package/dist/runner/index.js +3 -3
- package/dist/runner/index.js.map +1 -1
- package/dist/sea/gtkx-config-module.js +1 -1
- package/dist/sea/gtkx-config-module.js.map +1 -1
- package/dist/style/absolute-insets.d.ts +26 -0
- package/dist/style/absolute-insets.js +113 -0
- package/dist/style/absolute-insets.js.map +1 -0
- package/dist/style/animated-size.d.ts +25 -0
- package/dist/style/animated-size.js +225 -0
- package/dist/style/animated-size.js.map +1 -0
- package/dist/style/colors.d.ts +17 -0
- package/dist/style/colors.js +25 -6
- package/dist/style/colors.js.map +1 -1
- package/dist/style/imperative-css.d.ts +21 -0
- package/dist/style/imperative-css.js +63 -0
- package/dist/style/imperative-css.js.map +1 -0
- package/dist/style/index.d.ts +2 -1
- package/dist/style/index.js +2 -1
- package/dist/style/index.js.map +1 -1
- package/dist/style/split-style.js +5 -0
- package/dist/style/split-style.js.map +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/unsupported-export.d.ts +8 -0
- package/dist/unsupported-export.js +66 -0
- package/dist/unsupported-export.js.map +1 -0
- package/dist/vite/index.d.ts +21 -8
- package/dist/vite/index.js +127 -82
- package/dist/vite/index.js.map +1 -1
- package/dist/vitest/index.d.ts +2 -2
- package/dist/vitest/index.js.map +1 -1
- package/dist/worklets-compat/index.d.ts +4 -0
- package/dist/worklets-compat/index.js +28 -0
- package/dist/worklets-compat/index.js.map +1 -0
- package/dist/worklets-compat/surface.d.ts +110 -0
- package/dist/worklets-compat/surface.js +153 -0
- package/dist/worklets-compat/surface.js.map +1 -0
- package/package.json +25 -9
- package/types.d.ts +9 -0
- package/dist/common/list.d.ts +0 -82
- package/dist/common/list.js +0 -166
- package/dist/common/list.js.map +0 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ And the portability proof — `examples/profile` renders ONE source file with bo
|
|
|
31
31
|
|
|
32
32
|
- [x] Yoga + GtkFixed spike — **GO** (0 px accuracy, 500-node reflow in 0.17 ms, 60 fps — `docs/research/yoga-gtk-spike.md`)
|
|
33
33
|
- [x] Dev environment (UTM VM with a native GNOME session, headless sway for tests) and dev workflow
|
|
34
|
-
- [x] gtkx bridge (isolation from the RC API; [workaround catalog](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/gtkx-
|
|
34
|
+
- [x] gtkx bridge (isolation from the RC API; [workaround catalog](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/gtkx-rc4-notes.md))
|
|
35
35
|
- [x] Layout engine (Yoga shadow tree, measure via Pango, batching, diffing, onLayout)
|
|
36
36
|
- [x] StyleSheet: layout/visual split, CSS Color 4 colors, PlatformColor → Adwaita
|
|
37
37
|
- [x] View / Text / Image / AppRegistry — first RN render in GTK
|
|
@@ -44,7 +44,7 @@ And the portability proof — `examples/profile` renders ONE source file with bo
|
|
|
44
44
|
- [x] **Fast Refresh on both toolchains**: `run-linux --dev` (Metro dev server + HMR in the GTK host, state preserved) and `gtkx dev` (vite)
|
|
45
45
|
- [x] **Navigation on real Adwaita widgets**: react-navigation navigators backed by `Adw.NavigationView` and `Adw.NavigationSplitView` — see below
|
|
46
46
|
|
|
47
|
-
Verified live: `examples/hn-app` (a Hacker News reader on the Metro path), `examples/gallery` (the whole surface
|
|
47
|
+
Verified live: `examples/hn-app` (a Hacker News reader on the Metro path), `examples/gallery` (the whole surface, 32 sections), and `examples/tasks-app` (a full GNOME task manager — a port of the [gtkx tutorial](https://gtkx.dev/tutorial/)'s Tasks app, and the platform's most demanding app so far) — 1,647 tests (unit + component tests under headless Wayland).
|
|
48
48
|
|
|
49
49
|
## Navigation is native, not redrawn
|
|
50
50
|
|
|
@@ -112,6 +112,9 @@ number that had compared two different window sizes
|
|
|
112
112
|
- [Getting Started](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/getting-started.md) — a new project in a minute, and adding Linux to an existing RN app;
|
|
113
113
|
- [API v1](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/api.md) — the full surface and differences from RN;
|
|
114
114
|
- [The platform layer](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/platform-layer.md) — `react-native-gtkx/gtk` and `react-native-gtkx/adw`: Adwaita and GTK widgets as React components, driven by React Native style, usable with your own router or none at all;
|
|
115
|
+
- [Gestures](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/gestures.md) — the responder system and `PanResponder` on GTK: which layer to reach for, how the negotiation works, every difference from React Native, and what to do about `react-native-gesture-handler`;
|
|
116
|
+
- [Drag and drop](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/api.md#drag-and-drop-react-native-gtkxdnd) — `react-native-gtkx/dnd`: `react-native-reanimated-dnd`'s API on GTK's own drag-and-drop, aliased by both bundler presets (along with `GestureHandlerRootView`) so an app that already has drag-and-drop adds a Linux build without touching its source. That claim is tested by running **upstream's own example app** here: [`examples/reanimated-dnd`](examples/reanimated-dnd/README.md), whose README lists every line the port had to change;
|
|
117
|
+
- [Reanimated](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/api.md#react-native-reanimated-react-native-gtkxreanimated) — `react-native-gtkx/reanimated`: shared values, `useAnimatedStyle` and the `with*` animations reimplemented on one runtime and aliased onto the package name, plus the honest boundary of what a widget can be told without a React render;
|
|
115
118
|
- [Navigation research](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/research/navigation-extensibility.md) — the two layers, how an existing react-navigation app ports, and why the other desktop RN platforms never got native navigation;
|
|
116
119
|
- [What we need from gtkx](https://github.com/itsmepetrov/react-native-gtkx/blob/main/docs/upstream-gtkx.md) — the standing upstream agenda (bugs with repros, API asks, workarounds we want to delete);
|
|
117
120
|
- [CONTRIBUTING](https://github.com/itsmepetrov/react-native-gtkx/blob/main/CONTRIBUTING.md) — developing the library (from macOS — via the UTM VM).
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A rewrite rule in its general form: a pattern matched against the whole
|
|
3
|
+
* specifier and the replacement it produces (`$1`… back-references allowed).
|
|
4
|
+
* Only needed when a package's subpath layout differs from its target's — the
|
|
5
|
+
* string form covers "exact name or subpath, tail transplanted".
|
|
6
|
+
*/
|
|
7
|
+
export type AliasPattern = {
|
|
8
|
+
pattern: RegExp;
|
|
9
|
+
replace: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* What an `aliases` entry may say about one package name:
|
|
13
|
+
* - a string target — exact name or subpath, tail transplanted;
|
|
14
|
+
* - a `{ pattern, replace }` rule for a differing subpath layout;
|
|
15
|
+
* - `false` — drop an alias this preset installs, so the real package loads.
|
|
16
|
+
*/
|
|
17
|
+
export type AliasOverride = string | AliasPattern | false;
|
|
18
|
+
/** The `aliases` option, keyed by package name. */
|
|
19
|
+
export type AliasOverrides = Readonly<Record<string, AliasOverride>>;
|
|
20
|
+
/** A validated rule, tagged with the package name it was declared under. */
|
|
21
|
+
export type CompiledAlias = {
|
|
22
|
+
/** The package name this rule belongs to. */
|
|
23
|
+
name: string;
|
|
24
|
+
pattern: RegExp;
|
|
25
|
+
replace: string;
|
|
26
|
+
};
|
|
27
|
+
/** The result of validating an `aliases` option against the defaults. */
|
|
28
|
+
export type AliasTable = {
|
|
29
|
+
/**
|
|
30
|
+
* Rules to try, most specific package name first. Order is a tie-breaker
|
|
31
|
+
* only: overlapping rules are rejected, so at most one can ever match.
|
|
32
|
+
*/
|
|
33
|
+
rules: readonly CompiledAlias[];
|
|
34
|
+
/**
|
|
35
|
+
* Every package name the table knows about, INCLUDING the ones turned off
|
|
36
|
+
* with `false`. The vite preset keeps all of them inside its own pipeline:
|
|
37
|
+
* a package whose alias was dropped still imports `react-native` at module
|
|
38
|
+
* scope, and that import only reaches the alias if Node never sees the
|
|
39
|
+
* package first.
|
|
40
|
+
*/
|
|
41
|
+
names: readonly string[];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* `react-native` is not a package substitution and is not configurable. It is
|
|
45
|
+
* the platform: "the react-native API rendered as GTK widgets" is what this
|
|
46
|
+
* package IS, so a preset that stopped aliasing it would not be this preset.
|
|
47
|
+
*/
|
|
48
|
+
export declare const PLATFORM_ALIAS = "react-native";
|
|
49
|
+
/**
|
|
50
|
+
* The aliases both presets install, package name → target. See docs/api.md
|
|
51
|
+
* for the full story on each, and for which one is a real choice.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_ALIASES: Readonly<Record<string, string>>;
|
|
54
|
+
/** The default aliases an app may retarget or drop — everything but the platform. */
|
|
55
|
+
export declare const CONFIGURABLE_ALIASES: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* The string form, compiled. The guard is exact-match-or-slash-prefix, never a
|
|
58
|
+
* bare prefix: `react-native-reanimated-dnd` is a lookalike of
|
|
59
|
+
* `react-native-reanimated`, and `react-native-worklets-core` is a REAL and
|
|
60
|
+
* unrelated package (the VisionCamera one) that looks like
|
|
61
|
+
* `react-native-worklets`. A loose prefix would rewrite either onto a
|
|
62
|
+
* `react-native-gtkx/*` subpath that does not exist. The lookahead keeps the
|
|
63
|
+
* tail out of the match so `String.replace` transplants it onto the target.
|
|
64
|
+
*/
|
|
65
|
+
export declare const aliasPattern: (name: string, target: string) => AliasPattern;
|
|
66
|
+
/**
|
|
67
|
+
* Merges an app's `aliases` deltas over the defaults and validates the result.
|
|
68
|
+
* Throws — at config load, where the mistake is — with a message that names
|
|
69
|
+
* the valid keys.
|
|
70
|
+
*
|
|
71
|
+
* Deltas rather than a replacement list because a replacement list can
|
|
72
|
+
* silently lose an entry, which is #90 all over again: an app that re-listed
|
|
73
|
+
* five of the six names would get the sixth handed to Node before the alias
|
|
74
|
+
* ran, and the failure surfaces as an unrelated crash deep inside a library.
|
|
75
|
+
*/
|
|
76
|
+
export declare const compileAliases: (overrides?: AliasOverrides) => AliasTable;
|
|
77
|
+
/**
|
|
78
|
+
* Applies a compiled table to one specifier. Returns the rewritten specifier,
|
|
79
|
+
* or null when nothing claims it — including for `react-native-gtkx` itself
|
|
80
|
+
* and for every package the app turned off with `false`.
|
|
81
|
+
*/
|
|
82
|
+
export declare const applyAliases: (table: AliasTable, specifier: string) => string | null;
|
|
83
|
+
/** The table with no app overrides — what both presets install by default. */
|
|
84
|
+
export declare const DEFAULT_ALIAS_TABLE: AliasTable;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// The package alias table, and the one place either preset learns about it.
|
|
2
|
+
//
|
|
3
|
+
// Six package names are rewritten onto this platform's own implementations.
|
|
4
|
+
// Until now `src/metro/index.ts` and `src/vite/index.ts` each hand-rolled the
|
|
5
|
+
// same six rules, and they drifted: the vite preset's `ssr.noExternal` listed
|
|
6
|
+
// three of the six names, so vite handed the other three to Node before any
|
|
7
|
+
// `resolveId` hook could run and the REAL `react-native-gesture-handler`
|
|
8
|
+
// loaded into a linux app (#90). Deriving both the resolver rules and the
|
|
9
|
+
// externalization list from one object makes that class of bug inexpressible.
|
|
10
|
+
//
|
|
11
|
+
// This module is imported with an explicit `.js` extension by both presets,
|
|
12
|
+
// because bare Node loads them (metro.config.ts, vite.config.ts) and its ESM
|
|
13
|
+
// resolver does not guess extensions — see scripts/check-package.ts.
|
|
14
|
+
//
|
|
15
|
+
// The rules are DATA rather than functions on purpose. Data can be validated:
|
|
16
|
+
// a typo'd key can be named, a pattern that also matches a separately declared
|
|
17
|
+
// package can be reported at config time, and the string form can be anchored
|
|
18
|
+
// by construction. All three are failure modes this repo has actually had.
|
|
19
|
+
/**
|
|
20
|
+
* `react-native` is not a package substitution and is not configurable. It is
|
|
21
|
+
* the platform: "the react-native API rendered as GTK widgets" is what this
|
|
22
|
+
* package IS, so a preset that stopped aliasing it would not be this preset.
|
|
23
|
+
*/
|
|
24
|
+
export const PLATFORM_ALIAS = "react-native";
|
|
25
|
+
/**
|
|
26
|
+
* The aliases both presets install, package name → target. See docs/api.md
|
|
27
|
+
* for the full story on each, and for which one is a real choice.
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_ALIASES = {
|
|
30
|
+
// The platform. Not configurable: the out-of-tree npmPackageName
|
|
31
|
+
// declaration alone does not alias imports for a Metro `bundle`, and the
|
|
32
|
+
// vite path has no such declaration at all — the resolver has to.
|
|
33
|
+
"react-native": "react-native-gtkx",
|
|
34
|
+
// The SVG surface, in the shape of the react-native-svg package (see
|
|
35
|
+
// src/svg-compat/index.ts). The real package is a native module.
|
|
36
|
+
"react-native-svg": "react-native-gtkx/svg",
|
|
37
|
+
// Drag and drop, on GtkDragSource/GtkDropTarget (see src/dnd/index.ts).
|
|
38
|
+
// The ONE alias that is a genuine choice: the real 2.0.0 does run here on
|
|
39
|
+
// top of the compat surfaces below, so an app may want it. Everything else
|
|
40
|
+
// in this table substitutes an implementation that cannot run at all.
|
|
41
|
+
"react-native-reanimated-dnd": "react-native-gtkx/dnd",
|
|
42
|
+
// Reanimated, on GTK's frame clock (see src/reanimated-compat/index.tsx).
|
|
43
|
+
// The real package needs a worklet runtime and a Babel plugin.
|
|
44
|
+
"react-native-reanimated": "react-native-gtkx/reanimated",
|
|
45
|
+
// Where Reanimated 4 moved the worklet surface (see
|
|
46
|
+
// src/worklets-compat/index.ts). Libraries pull scheduleOnRN/scheduleOnUI
|
|
47
|
+
// out of it at module scope with no try/require guard, so an unaliased
|
|
48
|
+
// name fails at IMPORT rather than at use.
|
|
49
|
+
"react-native-worklets": "react-native-gtkx/worklets",
|
|
50
|
+
// Not a port of RNGH (docs/research/gestures.md): the shim supplies
|
|
51
|
+
// GestureHandlerRootView, the one symbol apps that use none of the rest
|
|
52
|
+
// still have at the root of their tree, and makes every other export throw
|
|
53
|
+
// where it is used instead of arriving as undefined.
|
|
54
|
+
"react-native-gesture-handler": "react-native-gtkx/gesture-handler",
|
|
55
|
+
};
|
|
56
|
+
/** The default aliases an app may retarget or drop — everything but the platform. */
|
|
57
|
+
export const CONFIGURABLE_ALIASES = Object.keys(DEFAULT_ALIASES).filter((name) => name !== PLATFORM_ALIAS);
|
|
58
|
+
const fail = (message) => {
|
|
59
|
+
throw new Error(`react-native-gtkx: ${message}`);
|
|
60
|
+
};
|
|
61
|
+
const quoted = (names) => names.map((name) => `"${name}"`).join(", ");
|
|
62
|
+
const escapeRegExp = (literal) => literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
63
|
+
/**
|
|
64
|
+
* The string form, compiled. The guard is exact-match-or-slash-prefix, never a
|
|
65
|
+
* bare prefix: `react-native-reanimated-dnd` is a lookalike of
|
|
66
|
+
* `react-native-reanimated`, and `react-native-worklets-core` is a REAL and
|
|
67
|
+
* unrelated package (the VisionCamera one) that looks like
|
|
68
|
+
* `react-native-worklets`. A loose prefix would rewrite either onto a
|
|
69
|
+
* `react-native-gtkx/*` subpath that does not exist. The lookahead keeps the
|
|
70
|
+
* tail out of the match so `String.replace` transplants it onto the target.
|
|
71
|
+
*/
|
|
72
|
+
export const aliasPattern = (name, target) => ({
|
|
73
|
+
pattern: new RegExp(`^${escapeRegExp(name)}(?=$|/)`),
|
|
74
|
+
replace: target,
|
|
75
|
+
});
|
|
76
|
+
const isAliasPattern = (value) => typeof value === "object" &&
|
|
77
|
+
value !== null &&
|
|
78
|
+
"pattern" in value &&
|
|
79
|
+
"replace" in value;
|
|
80
|
+
const checkTarget = (name, target) => {
|
|
81
|
+
if (target.trim() !== target || target === "") {
|
|
82
|
+
fail(`aliases["${name}"] must be a package specifier, got ${JSON.stringify(target)}.`);
|
|
83
|
+
}
|
|
84
|
+
if (target.startsWith(".") || target.startsWith("/")) {
|
|
85
|
+
fail(`aliases["${name}"] is ${JSON.stringify(target)}, a path. Alias targets are module ` +
|
|
86
|
+
"specifiers resolved from the importing file — name a package or one of its " +
|
|
87
|
+
"subpaths instead.");
|
|
88
|
+
}
|
|
89
|
+
if (target.endsWith("/")) {
|
|
90
|
+
fail(`aliases["${name}"] is ${JSON.stringify(target)}; a target ends at the subpath, ` +
|
|
91
|
+
"not at a slash — the matched tail is appended to it.");
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const compileOverride = (name, value) => {
|
|
95
|
+
if (typeof value === "string") {
|
|
96
|
+
checkTarget(name, value);
|
|
97
|
+
return { name, ...aliasPattern(name, value) };
|
|
98
|
+
}
|
|
99
|
+
if (!isAliasPattern(value)) {
|
|
100
|
+
fail(`aliases["${name}"] must be a target string, a { pattern, replace } rule, or false.`);
|
|
101
|
+
}
|
|
102
|
+
const { pattern, replace } = value;
|
|
103
|
+
if (!(pattern instanceof RegExp)) {
|
|
104
|
+
fail(`aliases["${name}"].pattern must be a RegExp.`);
|
|
105
|
+
}
|
|
106
|
+
if (typeof replace !== "string") {
|
|
107
|
+
fail(`aliases["${name}"].replace must be a string.`);
|
|
108
|
+
}
|
|
109
|
+
if (pattern.flags.includes("g") || pattern.flags.includes("y")) {
|
|
110
|
+
fail(`aliases["${name}"].pattern must not use the g or y flag: a stateful lastIndex ` +
|
|
111
|
+
"makes the same specifier match or not depending on what was resolved before it.");
|
|
112
|
+
}
|
|
113
|
+
if (!pattern.source.startsWith("^")) {
|
|
114
|
+
fail(`aliases["${name}"].pattern must be anchored with ^: an unanchored pattern matches ` +
|
|
115
|
+
`inside a longer specifier, so ${pattern} would also rewrite packages that merely ` +
|
|
116
|
+
"contain that text.");
|
|
117
|
+
}
|
|
118
|
+
return { name, pattern, replace };
|
|
119
|
+
};
|
|
120
|
+
// Probes stand in for "this package, and something inside it". Any rule that
|
|
121
|
+
// matches one of them owns that package name.
|
|
122
|
+
const probesFor = (name) => [name, `${name}/__subpath__`];
|
|
123
|
+
/**
|
|
124
|
+
* Rejects two rules that can both claim the same specifier. Only possible with
|
|
125
|
+
* the `{ pattern }` form — the string form is anchored to its own package name
|
|
126
|
+
* and cannot reach another one — and it is exactly the trap the presets carry
|
|
127
|
+
* a comment about: an anchored replace on a loose prefix turns
|
|
128
|
+
* `react-native-reanimated-dnd` into `react-native-gtkx/reanimated-dnd`, which
|
|
129
|
+
* does not exist. With every rule declared as data, the preset can see it.
|
|
130
|
+
*/
|
|
131
|
+
const checkOverlaps = (rules) => {
|
|
132
|
+
for (const rule of rules) {
|
|
133
|
+
for (const other of rules) {
|
|
134
|
+
if (other.name === rule.name) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const hit = probesFor(other.name).find((probe) => rule.pattern.test(probe));
|
|
138
|
+
if (hit !== undefined) {
|
|
139
|
+
fail(`aliases["${rule.name}"].pattern (${rule.pattern}) also matches "${hit}", which is ` +
|
|
140
|
+
`declared separately as "${other.name}". Two rules claiming one specifier make ` +
|
|
141
|
+
"resolution order-dependent — narrow the pattern, or use the string form, which " +
|
|
142
|
+
"is anchored to its own package name and cannot overlap.");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const checkKey = (name, value) => {
|
|
148
|
+
if (name === PLATFORM_ALIAS) {
|
|
149
|
+
fail(value === false
|
|
150
|
+
? `aliases["${PLATFORM_ALIAS}"] cannot be false. "${PLATFORM_ALIAS}" is not a package ` +
|
|
151
|
+
"substitution here, it is the platform: rendering the react-native API as GTK " +
|
|
152
|
+
"widgets is what this preset does, and dropping the alias would leave the app " +
|
|
153
|
+
`importing a package with no linux implementation. Removable: ${quoted(CONFIGURABLE_ALIASES)}.`
|
|
154
|
+
: `aliases["${PLATFORM_ALIAS}"] cannot be retargeted. "${PLATFORM_ALIAS}" is the ` +
|
|
155
|
+
"platform, not one of the substituted packages — it always resolves to " +
|
|
156
|
+
`react-native-gtkx. Configurable: ${quoted(CONFIGURABLE_ALIASES)}.`);
|
|
157
|
+
}
|
|
158
|
+
if (value === false && !(name in DEFAULT_ALIASES)) {
|
|
159
|
+
fail(`aliases["${name}"] is false, but "${name}" is not an alias this preset installs, so ` +
|
|
160
|
+
`there is nothing to drop. Aliases that can be dropped: ${quoted(CONFIGURABLE_ALIASES)}. ` +
|
|
161
|
+
`(To ADD an alias for "${name}", give it a target instead of false.)`);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Merges an app's `aliases` deltas over the defaults and validates the result.
|
|
166
|
+
* Throws — at config load, where the mistake is — with a message that names
|
|
167
|
+
* the valid keys.
|
|
168
|
+
*
|
|
169
|
+
* Deltas rather than a replacement list because a replacement list can
|
|
170
|
+
* silently lose an entry, which is #90 all over again: an app that re-listed
|
|
171
|
+
* five of the six names would get the sixth handed to Node before the alias
|
|
172
|
+
* ran, and the failure surfaces as an unrelated crash deep inside a library.
|
|
173
|
+
*/
|
|
174
|
+
export const compileAliases = (overrides = {}) => {
|
|
175
|
+
const targets = new Map(Object.entries(DEFAULT_ALIASES));
|
|
176
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
177
|
+
checkKey(name, value);
|
|
178
|
+
targets.set(name, value);
|
|
179
|
+
}
|
|
180
|
+
const rules = [];
|
|
181
|
+
for (const [name, value] of targets) {
|
|
182
|
+
if (value !== false) {
|
|
183
|
+
rules.push(compileOverride(name, value));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
checkOverlaps(rules);
|
|
187
|
+
// Longest package name first. Overlaps are rejected above, so this only
|
|
188
|
+
// fixes an order rather than choosing between candidates — but a stable,
|
|
189
|
+
// most-specific-first order is what a reader expects when they scan it.
|
|
190
|
+
rules.sort((a, b) => b.name.length - a.name.length || a.name.localeCompare(b.name));
|
|
191
|
+
return { rules, names: [...targets.keys()] };
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Applies a compiled table to one specifier. Returns the rewritten specifier,
|
|
195
|
+
* or null when nothing claims it — including for `react-native-gtkx` itself
|
|
196
|
+
* and for every package the app turned off with `false`.
|
|
197
|
+
*/
|
|
198
|
+
export const applyAliases = (table, specifier) => {
|
|
199
|
+
for (const rule of table.rules) {
|
|
200
|
+
if (rule.pattern.test(specifier)) {
|
|
201
|
+
return specifier.replace(rule.pattern, rule.replace);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
};
|
|
206
|
+
/** The table with no app overrides — what both presets install by default. */
|
|
207
|
+
export const DEFAULT_ALIAS_TABLE = compileAliases();
|
|
208
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/aliases/index.ts"],"names":[],"mappings":"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","sourcesContent":["// The package alias table, and the one place either preset learns about it.\n//\n// Six package names are rewritten onto this platform's own implementations.\n// Until now `src/metro/index.ts` and `src/vite/index.ts` each hand-rolled the\n// same six rules, and they drifted: the vite preset's `ssr.noExternal` listed\n// three of the six names, so vite handed the other three to Node before any\n// `resolveId` hook could run and the REAL `react-native-gesture-handler`\n// loaded into a linux app (#90). Deriving both the resolver rules and the\n// externalization list from one object makes that class of bug inexpressible.\n//\n// This module is imported with an explicit `.js` extension by both presets,\n// because bare Node loads them (metro.config.ts, vite.config.ts) and its ESM\n// resolver does not guess extensions — see scripts/check-package.ts.\n//\n// The rules are DATA rather than functions on purpose. Data can be validated:\n// a typo'd key can be named, a pattern that also matches a separately declared\n// package can be reported at config time, and the string form can be anchored\n// by construction. All three are failure modes this repo has actually had.\n\n/**\n * A rewrite rule in its general form: a pattern matched against the whole\n * specifier and the replacement it produces (`$1`… back-references allowed).\n * Only needed when a package's subpath layout differs from its target's — the\n * string form covers \"exact name or subpath, tail transplanted\".\n */\nexport type AliasPattern = {\n pattern: RegExp\n replace: string\n}\n\n/**\n * What an `aliases` entry may say about one package name:\n * - a string target — exact name or subpath, tail transplanted;\n * - a `{ pattern, replace }` rule for a differing subpath layout;\n * - `false` — drop an alias this preset installs, so the real package loads.\n */\nexport type AliasOverride = string | AliasPattern | false\n\n/** The `aliases` option, keyed by package name. */\nexport type AliasOverrides = Readonly<Record<string, AliasOverride>>\n\n/** A validated rule, tagged with the package name it was declared under. */\nexport type CompiledAlias = {\n /** The package name this rule belongs to. */\n name: string\n pattern: RegExp\n replace: string\n}\n\n/** The result of validating an `aliases` option against the defaults. */\nexport type AliasTable = {\n /**\n * Rules to try, most specific package name first. Order is a tie-breaker\n * only: overlapping rules are rejected, so at most one can ever match.\n */\n rules: readonly CompiledAlias[]\n /**\n * Every package name the table knows about, INCLUDING the ones turned off\n * with `false`. The vite preset keeps all of them inside its own pipeline:\n * a package whose alias was dropped still imports `react-native` at module\n * scope, and that import only reaches the alias if Node never sees the\n * package first.\n */\n names: readonly string[]\n}\n\n/**\n * `react-native` is not a package substitution and is not configurable. It is\n * the platform: \"the react-native API rendered as GTK widgets\" is what this\n * package IS, so a preset that stopped aliasing it would not be this preset.\n */\nexport const PLATFORM_ALIAS = \"react-native\"\n\n/**\n * The aliases both presets install, package name → target. See docs/api.md\n * for the full story on each, and for which one is a real choice.\n */\nexport const DEFAULT_ALIASES: Readonly<Record<string, string>> = {\n // The platform. Not configurable: the out-of-tree npmPackageName\n // declaration alone does not alias imports for a Metro `bundle`, and the\n // vite path has no such declaration at all — the resolver has to.\n \"react-native\": \"react-native-gtkx\",\n // The SVG surface, in the shape of the react-native-svg package (see\n // src/svg-compat/index.ts). The real package is a native module.\n \"react-native-svg\": \"react-native-gtkx/svg\",\n // Drag and drop, on GtkDragSource/GtkDropTarget (see src/dnd/index.ts).\n // The ONE alias that is a genuine choice: the real 2.0.0 does run here on\n // top of the compat surfaces below, so an app may want it. Everything else\n // in this table substitutes an implementation that cannot run at all.\n \"react-native-reanimated-dnd\": \"react-native-gtkx/dnd\",\n // Reanimated, on GTK's frame clock (see src/reanimated-compat/index.tsx).\n // The real package needs a worklet runtime and a Babel plugin.\n \"react-native-reanimated\": \"react-native-gtkx/reanimated\",\n // Where Reanimated 4 moved the worklet surface (see\n // src/worklets-compat/index.ts). Libraries pull scheduleOnRN/scheduleOnUI\n // out of it at module scope with no try/require guard, so an unaliased\n // name fails at IMPORT rather than at use.\n \"react-native-worklets\": \"react-native-gtkx/worklets\",\n // Not a port of RNGH (docs/research/gestures.md): the shim supplies\n // GestureHandlerRootView, the one symbol apps that use none of the rest\n // still have at the root of their tree, and makes every other export throw\n // where it is used instead of arriving as undefined.\n \"react-native-gesture-handler\": \"react-native-gtkx/gesture-handler\",\n}\n\n/** The default aliases an app may retarget or drop — everything but the platform. */\nexport const CONFIGURABLE_ALIASES: readonly string[] = Object.keys(\n DEFAULT_ALIASES,\n).filter((name) => name !== PLATFORM_ALIAS)\n\nconst fail = (message: string): never => {\n throw new Error(`react-native-gtkx: ${message}`)\n}\n\nconst quoted = (names: readonly string[]): string =>\n names.map((name) => `\"${name}\"`).join(\", \")\n\nconst escapeRegExp = (literal: string): string =>\n literal.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\n/**\n * The string form, compiled. The guard is exact-match-or-slash-prefix, never a\n * bare prefix: `react-native-reanimated-dnd` is a lookalike of\n * `react-native-reanimated`, and `react-native-worklets-core` is a REAL and\n * unrelated package (the VisionCamera one) that looks like\n * `react-native-worklets`. A loose prefix would rewrite either onto a\n * `react-native-gtkx/*` subpath that does not exist. The lookahead keeps the\n * tail out of the match so `String.replace` transplants it onto the target.\n */\nexport const aliasPattern = (name: string, target: string): AliasPattern => ({\n pattern: new RegExp(`^${escapeRegExp(name)}(?=$|/)`),\n replace: target,\n})\n\nconst isAliasPattern = (value: unknown): value is AliasPattern =>\n typeof value === \"object\" &&\n value !== null &&\n \"pattern\" in value &&\n \"replace\" in value\n\nconst checkTarget = (name: string, target: string): void => {\n if (target.trim() !== target || target === \"\") {\n fail(\n `aliases[\"${name}\"] must be a package specifier, got ${JSON.stringify(target)}.`,\n )\n }\n if (target.startsWith(\".\") || target.startsWith(\"/\")) {\n fail(\n `aliases[\"${name}\"] is ${JSON.stringify(target)}, a path. Alias targets are module ` +\n \"specifiers resolved from the importing file — name a package or one of its \" +\n \"subpaths instead.\",\n )\n }\n if (target.endsWith(\"/\")) {\n fail(\n `aliases[\"${name}\"] is ${JSON.stringify(target)}; a target ends at the subpath, ` +\n \"not at a slash — the matched tail is appended to it.\",\n )\n }\n}\n\nconst compileOverride = (name: string, value: AliasOverride): CompiledAlias => {\n if (typeof value === \"string\") {\n checkTarget(name, value)\n return { name, ...aliasPattern(name, value) }\n }\n if (!isAliasPattern(value)) {\n fail(\n `aliases[\"${name}\"] must be a target string, a { pattern, replace } rule, or false.`,\n )\n }\n const { pattern, replace } = value as AliasPattern\n if (!(pattern instanceof RegExp)) {\n fail(`aliases[\"${name}\"].pattern must be a RegExp.`)\n }\n if (typeof replace !== \"string\") {\n fail(`aliases[\"${name}\"].replace must be a string.`)\n }\n if (pattern.flags.includes(\"g\") || pattern.flags.includes(\"y\")) {\n fail(\n `aliases[\"${name}\"].pattern must not use the g or y flag: a stateful lastIndex ` +\n \"makes the same specifier match or not depending on what was resolved before it.\",\n )\n }\n if (!pattern.source.startsWith(\"^\")) {\n fail(\n `aliases[\"${name}\"].pattern must be anchored with ^: an unanchored pattern matches ` +\n `inside a longer specifier, so ${pattern} would also rewrite packages that merely ` +\n \"contain that text.\",\n )\n }\n return { name, pattern, replace }\n}\n\n// Probes stand in for \"this package, and something inside it\". Any rule that\n// matches one of them owns that package name.\nconst probesFor = (name: string): string[] => [name, `${name}/__subpath__`]\n\n/**\n * Rejects two rules that can both claim the same specifier. Only possible with\n * the `{ pattern }` form — the string form is anchored to its own package name\n * and cannot reach another one — and it is exactly the trap the presets carry\n * a comment about: an anchored replace on a loose prefix turns\n * `react-native-reanimated-dnd` into `react-native-gtkx/reanimated-dnd`, which\n * does not exist. With every rule declared as data, the preset can see it.\n */\nconst checkOverlaps = (rules: readonly CompiledAlias[]): void => {\n for (const rule of rules) {\n for (const other of rules) {\n if (other.name === rule.name) {\n continue\n }\n const hit = probesFor(other.name).find((probe) =>\n rule.pattern.test(probe),\n )\n if (hit !== undefined) {\n fail(\n `aliases[\"${rule.name}\"].pattern (${rule.pattern}) also matches \"${hit}\", which is ` +\n `declared separately as \"${other.name}\". Two rules claiming one specifier make ` +\n \"resolution order-dependent — narrow the pattern, or use the string form, which \" +\n \"is anchored to its own package name and cannot overlap.\",\n )\n }\n }\n }\n}\n\nconst checkKey = (name: string, value: AliasOverride): void => {\n if (name === PLATFORM_ALIAS) {\n fail(\n value === false\n ? `aliases[\"${PLATFORM_ALIAS}\"] cannot be false. \"${PLATFORM_ALIAS}\" is not a package ` +\n \"substitution here, it is the platform: rendering the react-native API as GTK \" +\n \"widgets is what this preset does, and dropping the alias would leave the app \" +\n `importing a package with no linux implementation. Removable: ${quoted(CONFIGURABLE_ALIASES)}.`\n : `aliases[\"${PLATFORM_ALIAS}\"] cannot be retargeted. \"${PLATFORM_ALIAS}\" is the ` +\n \"platform, not one of the substituted packages — it always resolves to \" +\n `react-native-gtkx. Configurable: ${quoted(CONFIGURABLE_ALIASES)}.`,\n )\n }\n if (value === false && !(name in DEFAULT_ALIASES)) {\n fail(\n `aliases[\"${name}\"] is false, but \"${name}\" is not an alias this preset installs, so ` +\n `there is nothing to drop. Aliases that can be dropped: ${quoted(CONFIGURABLE_ALIASES)}. ` +\n `(To ADD an alias for \"${name}\", give it a target instead of false.)`,\n )\n }\n}\n\n/**\n * Merges an app's `aliases` deltas over the defaults and validates the result.\n * Throws — at config load, where the mistake is — with a message that names\n * the valid keys.\n *\n * Deltas rather than a replacement list because a replacement list can\n * silently lose an entry, which is #90 all over again: an app that re-listed\n * five of the six names would get the sixth handed to Node before the alias\n * ran, and the failure surfaces as an unrelated crash deep inside a library.\n */\nexport const compileAliases = (overrides: AliasOverrides = {}): AliasTable => {\n const targets = new Map<string, AliasOverride>(\n Object.entries(DEFAULT_ALIASES),\n )\n for (const [name, value] of Object.entries(overrides)) {\n checkKey(name, value)\n targets.set(name, value)\n }\n const rules: CompiledAlias[] = []\n for (const [name, value] of targets) {\n if (value !== false) {\n rules.push(compileOverride(name, value))\n }\n }\n checkOverlaps(rules)\n // Longest package name first. Overlaps are rejected above, so this only\n // fixes an order rather than choosing between candidates — but a stable,\n // most-specific-first order is what a reader expects when they scan it.\n rules.sort(\n (a, b) => b.name.length - a.name.length || a.name.localeCompare(b.name),\n )\n return { rules, names: [...targets.keys()] }\n}\n\n/**\n * Applies a compiled table to one specifier. Returns the rewritten specifier,\n * or null when nothing claims it — including for `react-native-gtkx` itself\n * and for every package the app turned off with `false`.\n */\nexport const applyAliases = (\n table: AliasTable,\n specifier: string,\n): string | null => {\n for (const rule of table.rules) {\n if (rule.pattern.test(specifier)) {\n return specifier.replace(rule.pattern, rule.replace)\n }\n }\n return null\n}\n\n/** The table with no app overrides — what both presets install by default. */\nexport const DEFAULT_ALIAS_TABLE: AliasTable = compileAliases()\n"]}
|
package/dist/animated/index.d.ts
CHANGED
|
@@ -4,5 +4,7 @@ export type { EasingFunction } from "./easing";
|
|
|
4
4
|
export { Easing } from "./easing";
|
|
5
5
|
export type { CompositeAnimation, EndCallback, EndResult, ExtrapolateType, FrameScheduler, InterpolationConfig, InterpolationListener, LoopConfig, ParallelConfig, SpringConfig, TimingConfig, ValueListener, } from "./types";
|
|
6
6
|
export { AnimatedInterpolation, AnimatedValue } from "./value";
|
|
7
|
+
export { createValueAnimation } from "./value-animation";
|
|
8
|
+
export type { MakeStep, StepFn, StepResult } from "./value-animation";
|
|
7
9
|
export { AnimatedValueXY } from "./value-xy";
|
|
8
10
|
export type { ValueXYListener, ValueXYLiteral } from "./value-xy";
|
package/dist/animated/index.js
CHANGED
|
@@ -4,5 +4,10 @@
|
|
|
4
4
|
export { createAnimated } from "./create-animated";
|
|
5
5
|
export { Easing } from "./easing";
|
|
6
6
|
export { AnimatedInterpolation, AnimatedValue } from "./value";
|
|
7
|
+
// The frame-driven lifecycle every single-value animation shares. Not part of
|
|
8
|
+
// `AnimatedApi` — RN's `Animated` has no such method and this object is spread
|
|
9
|
+
// into the public one — but exported because a layer built ON this engine may
|
|
10
|
+
// need a per-frame step RN itself does not have: `withDecay` is the first.
|
|
11
|
+
export { createValueAnimation } from "./value-animation";
|
|
7
12
|
export { AnimatedValueXY } from "./value-xy";
|
|
8
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/animated/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,uEAAuE;AACvE,mCAAmC;AAGnC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAejC,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA","sourcesContent":["// Animated module entry point. Pure by contract: everything is driven by an\n// injected FrameScheduler — the GTK frame clock is connected where the\n// Animated.* components are built.\n\nexport type { AnimatedApi } from \"./create-animated\"\nexport { createAnimated } from \"./create-animated\"\nexport type { EasingFunction } from \"./easing\"\nexport { Easing } from \"./easing\"\nexport type {\n CompositeAnimation,\n EndCallback,\n EndResult,\n ExtrapolateType,\n FrameScheduler,\n InterpolationConfig,\n InterpolationListener,\n LoopConfig,\n ParallelConfig,\n SpringConfig,\n TimingConfig,\n ValueListener,\n} from \"./types\"\nexport { AnimatedInterpolation, AnimatedValue } from \"./value\"\nexport { AnimatedValueXY } from \"./value-xy\"\nexport type { ValueXYListener, ValueXYLiteral } from \"./value-xy\"\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/animated/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,uEAAuE;AACvE,mCAAmC;AAGnC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAejC,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC9D,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA","sourcesContent":["// Animated module entry point. Pure by contract: everything is driven by an\n// injected FrameScheduler — the GTK frame clock is connected where the\n// Animated.* components are built.\n\nexport type { AnimatedApi } from \"./create-animated\"\nexport { createAnimated } from \"./create-animated\"\nexport type { EasingFunction } from \"./easing\"\nexport { Easing } from \"./easing\"\nexport type {\n CompositeAnimation,\n EndCallback,\n EndResult,\n ExtrapolateType,\n FrameScheduler,\n InterpolationConfig,\n InterpolationListener,\n LoopConfig,\n ParallelConfig,\n SpringConfig,\n TimingConfig,\n ValueListener,\n} from \"./types\"\nexport { AnimatedInterpolation, AnimatedValue } from \"./value\"\n// The frame-driven lifecycle every single-value animation shares. Not part of\n// `AnimatedApi` — RN's `Animated` has no such method and this object is spread\n// into the public one — but exported because a layer built ON this engine may\n// need a per-frame step RN itself does not have: `withDecay` is the first.\nexport { createValueAnimation } from \"./value-animation\"\nexport type { MakeStep, StepFn, StepResult } from \"./value-animation\"\nexport { AnimatedValueXY } from \"./value-xy\"\nexport type { ValueXYListener, ValueXYLiteral } from \"./value-xy\"\n"]}
|
package/dist/animated/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/animated/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,mCAAmC","sourcesContent":["// Public contracts of the Animated module. The module is pure: no bridge or\n// gtkx imports, no timers, no Date — time only ever arrives through the\n// injected FrameScheduler, so the GTK frame clock (production) and a manual\n// test driver are interchangeable.\n\nimport type { EasingFunction } from \"./easing\"\n\n// Frame driver injected by the host (GTK frame clock in production, a manual\n// scheduler in tests). schedule() books a one-shot callback for the next\n// frame — re-book from inside the callback to keep ticking — and returns an\n// unsubscribe that cancels the pending callback.\nexport type FrameScheduler = {\n schedule(cb: (timeMs: number) => void): () => void\n}\n\nexport type EndResult = { finished: boolean }\n\nexport type EndCallback = (result: EndResult) => void\n\n// RN CompositeAnimation subset, plus reset() which loop() relies on to snap\n// values back before each iteration (RN has it too).\nexport type CompositeAnimation = {\n start(callback?: EndCallback): void\n stop(): void\n reset(): void\n}\n\nexport type ValueListener = (event: { value: number }) => void\n\nexport type InterpolationListener = (event: { value: number | string }) => void\n\nexport type ExtrapolateType = \"extend\" | \"clamp\" | \"identity\"\n\nexport type InterpolationConfig = {\n inputRange: number[]\n outputRange: number[] | string[]\n // Applied to both sides of the input range (RN's extrapolateLeft/Right are\n // not split out in this subset). Default: \"extend\".\n extrapolate?: ExtrapolateType\n}\n\nexport type TimingConfig = {\n toValue: number\n duration?: number\n delay?: number\n easing?: EasingFunction\n // Accepted for RN source compatibility; the GTK backend has no native\n // driver (everything already runs on the direct frame-clock path), so the\n // flag is ignored with a single dev warning per session.\n useNativeDriver?: boolean\n}\n\nexport type SpringConfig = {\n toValue: number\n stiffness?: number\n damping?: number\n mass?: number\n initialVelocity?: number\n overshootClamping?: boolean\n restDisplacementThreshold?: number\n restSpeedThreshold?: number\n delay?: number\n useNativeDriver?: boolean\n}\n\nexport type ParallelConfig = {\n // Like RN: when one child ends unfinished, stop the remaining ones too.\n // Default: true.\n stopTogether?: boolean\n}\n\nexport type LoopConfig = {\n // -1 (default) loops forever.\n iterations?: number\n // Snap the child animation back to its starting value before every\n // iteration (RN default: true).\n resetBeforeIteration?: boolean\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/animated/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,mCAAmC","sourcesContent":["// Public contracts of the Animated module. The module is pure: no bridge or\n// gtkx imports, no timers, no Date — time only ever arrives through the\n// injected FrameScheduler, so the GTK frame clock (production) and a manual\n// test driver are interchangeable.\n\nimport type { EasingFunction } from \"./easing\"\n\n// Frame driver injected by the host (GTK frame clock in production, a manual\n// scheduler in tests). schedule() books a one-shot callback for the next\n// frame — re-book from inside the callback to keep ticking — and returns an\n// unsubscribe that cancels the pending callback.\n//\n// `now()` reads the SAME clock the frame callback is stamped with, off-frame.\n// It is what lets an animation anchor t = 0 to the moment it was started\n// rather than to the first frame that happens to arrive — see\n// value-animation.ts, which explains why that distinction is worth a method.\n// Optional so a driver that only has frame stamps still satisfies the type.\nexport type FrameScheduler = {\n schedule(cb: (timeMs: number) => void): () => void\n now?(): number\n}\n\nexport type EndResult = { finished: boolean }\n\nexport type EndCallback = (result: EndResult) => void\n\n// RN CompositeAnimation subset, plus reset() which loop() relies on to snap\n// values back before each iteration (RN has it too).\nexport type CompositeAnimation = {\n start(callback?: EndCallback): void\n stop(): void\n reset(): void\n}\n\nexport type ValueListener = (event: { value: number }) => void\n\nexport type InterpolationListener = (event: { value: number | string }) => void\n\nexport type ExtrapolateType = \"extend\" | \"clamp\" | \"identity\"\n\nexport type InterpolationConfig = {\n inputRange: number[]\n outputRange: number[] | string[]\n // Applied to both sides of the input range (RN's extrapolateLeft/Right are\n // not split out in this subset). Default: \"extend\".\n extrapolate?: ExtrapolateType\n}\n\nexport type TimingConfig = {\n toValue: number\n duration?: number\n delay?: number\n easing?: EasingFunction\n // Accepted for RN source compatibility; the GTK backend has no native\n // driver (everything already runs on the direct frame-clock path), so the\n // flag is ignored with a single dev warning per session.\n useNativeDriver?: boolean\n}\n\nexport type SpringConfig = {\n toValue: number\n stiffness?: number\n damping?: number\n mass?: number\n initialVelocity?: number\n overshootClamping?: boolean\n restDisplacementThreshold?: number\n restSpeedThreshold?: number\n delay?: number\n useNativeDriver?: boolean\n}\n\nexport type ParallelConfig = {\n // Like RN: when one child ends unfinished, stop the remaining ones too.\n // Default: true.\n stopTogether?: boolean\n}\n\nexport type LoopConfig = {\n // -1 (default) loops forever.\n iterations?: number\n // Snap the child animation back to its starting value before every\n // iteration (RN default: true).\n resetBeforeIteration?: boolean\n}\n"]}
|
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
// spring). Implements the RN semantics: a value runs at most one animation —
|
|
3
3
|
// a newer start() preempts the previous one with { finished: false }; natural
|
|
4
4
|
// completion reports { finished: true }; a finished or stopped run drops its
|
|
5
|
-
// frame subscription immediately (no idle ticks).
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// frame subscription immediately (no idle ticks).
|
|
6
|
+
//
|
|
7
|
+
// t = 0 IS THE MOMENT start() WAS CALLED, read off the scheduler's own clock.
|
|
8
|
+
// It used to be the first frame that arrived, which cost every animation on
|
|
9
|
+
// this platform a frame it never used: the first callback lands ~16 ms after
|
|
10
|
+
// start(), evaluates step(0) — the start value by definition — and writes it
|
|
11
|
+
// back unchanged, so nothing MOVES until the second frame, ~32 ms in. A 300 ms
|
|
12
|
+
// fade also RAN for 316 ms rather than 300. Anchoring at start() is what RN's
|
|
13
|
+
// own TimingAnimation (`_startTime = Date.now()` inside start()) and
|
|
14
|
+
// Reanimated both do, and it is time-based in the way a stalled main loop
|
|
15
|
+
// demands: a late frame resumes the curve where the clock says, instead of
|
|
16
|
+
// stretching the animation by the length of the stall.
|
|
17
|
+
//
|
|
18
|
+
// There is still no wall clock in this module — `scheduler.now()` reads the
|
|
19
|
+
// same clock the frame stamps come from, so `timeMs - startTime` stays
|
|
20
|
+
// coherent. A scheduler that offers no clock keeps the first-frame anchoring.
|
|
8
21
|
import { createFrameLoop } from "./frame-loop";
|
|
9
22
|
export const createValueAnimation = (scheduler, value, makeStep) => {
|
|
10
23
|
let stopActiveRun = null;
|
|
11
24
|
const start = (callback) => {
|
|
12
25
|
const step = makeStep(value.__getValue());
|
|
13
|
-
let startTime = null;
|
|
26
|
+
let startTime = scheduler.now?.() ?? null;
|
|
14
27
|
let ended = false;
|
|
15
28
|
const loop = createFrameLoop(scheduler, (timeMs) => {
|
|
16
29
|
if (ended) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-animation.js","sourceRoot":"","sources":["../../src/animated/value-animation.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"value-animation.js","sourceRoot":"","sources":["../../src/animated/value-animation.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,kDAAkD;AAClD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,qEAAqE;AACrE,0EAA0E;AAC1E,2EAA2E;AAC3E,uDAAuD;AACvD,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,8EAA8E;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAa9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,SAAyB,EACzB,KAAoB,EACpB,QAAkB,EACE,EAAE;IACtB,IAAI,aAAa,GAAwB,IAAI,CAAA;IAE7C,MAAM,KAAK,GAAG,CAAC,QAAsB,EAAQ,EAAE;QAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;QACzC,IAAI,SAAS,GAAkB,SAAS,CAAC,GAAG,EAAE,EAAE,IAAI,IAAI,CAAA;QACxD,IAAI,KAAK,GAAG,KAAK,CAAA;QAEjB,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACjD,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAA;YACd,CAAC;YACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,SAAS,GAAG,MAAM,CAAA;YACpB,CAAC;YACD,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;YACnD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC/B,CAAC;YACD,IAAI,IAAI,EAAE,CAAC;gBACT,GAAG,CAAC,IAAI,CAAC,CAAA;gBACT,OAAO,KAAK,CAAA;YACd,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,GAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAA;QAE/C,MAAM,GAAG,GAAG,CAAC,QAAiB,EAAQ,EAAE;YACtC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAM;YACR,CAAC;YACD,KAAK,GAAG,IAAI,CAAA;YACZ,IAAI,CAAC,IAAI,EAAE,CAAA;YACX,IAAI,aAAa,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;gBAClC,aAAa,GAAG,IAAI,CAAA;YACtB,CAAC;YACD,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;YAC5B,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC1B,CAAC,CAAA;QAED,aAAa,GAAG,MAAM,CAAC,IAAI,CAAA;QAC3B,yEAAyE;QACzE,2EAA2E;QAC3E,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,KAAK;QACL,IAAI,EAAE,GAAG,EAAE;YACT,aAAa,EAAE,EAAE,CAAA;QACnB,CAAC;QACD,uEAAuE;QACvE,0EAA0E;QAC1E,KAAK,EAAE,GAAG,EAAE;YACV,KAAK,CAAC,cAAc,EAAE,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC,CAAA","sourcesContent":["// Shared lifecycle for animations that drive a single AnimatedValue (timing,\n// spring). Implements the RN semantics: a value runs at most one animation —\n// a newer start() preempts the previous one with { finished: false }; natural\n// completion reports { finished: true }; a finished or stopped run drops its\n// frame subscription immediately (no idle ticks).\n//\n// t = 0 IS THE MOMENT start() WAS CALLED, read off the scheduler's own clock.\n// It used to be the first frame that arrived, which cost every animation on\n// this platform a frame it never used: the first callback lands ~16 ms after\n// start(), evaluates step(0) — the start value by definition — and writes it\n// back unchanged, so nothing MOVES until the second frame, ~32 ms in. A 300 ms\n// fade also RAN for 316 ms rather than 300. Anchoring at start() is what RN's\n// own TimingAnimation (`_startTime = Date.now()` inside start()) and\n// Reanimated both do, and it is time-based in the way a stalled main loop\n// demands: a late frame resumes the curve where the clock says, instead of\n// stretching the animation by the length of the stall.\n//\n// There is still no wall clock in this module — `scheduler.now()` reads the\n// same clock the frame stamps come from, so `timeMs - startTime` stays\n// coherent. A scheduler that offers no clock keeps the first-frame anchoring.\n\nimport { createFrameLoop } from \"./frame-loop\"\nimport type { CompositeAnimation, EndCallback, FrameScheduler } from \"./types\"\nimport type { AnimatedValue } from \"./value\"\n\n// Per-frame step: elapsed ms since the first frame of this run → the next\n// position (null while waiting out a delay: the value is not touched) and\n// whether the run is done. makeStep is invoked on every start() with the\n// value captured at that moment, so restarts pick up from wherever the value\n// currently is.\nexport type StepResult = { position: number | null; done: boolean }\nexport type StepFn = (elapsedMs: number) => StepResult\nexport type MakeStep = (startValue: number) => StepFn\n\nexport const createValueAnimation = (\n scheduler: FrameScheduler,\n value: AnimatedValue,\n makeStep: MakeStep,\n): CompositeAnimation => {\n let stopActiveRun: (() => void) | null = null\n\n const start = (callback?: EndCallback): void => {\n const step = makeStep(value.__getValue())\n let startTime: number | null = scheduler.now?.() ?? null\n let ended = false\n\n const loop = createFrameLoop(scheduler, (timeMs) => {\n if (ended) {\n return false\n }\n if (startTime === null) {\n startTime = timeMs\n }\n const { position, done } = step(timeMs - startTime)\n if (position !== null) {\n value.__updateValue(position)\n }\n if (done) {\n end(true)\n return false\n }\n return true\n })\n\n const handle = { stop: (): void => end(false) }\n\n const end = (finished: boolean): void => {\n if (ended) {\n return\n }\n ended = true\n loop.stop()\n if (stopActiveRun === handle.stop) {\n stopActiveRun = null\n }\n value.__endAnimation(handle)\n callback?.({ finished })\n }\n\n stopActiveRun = handle.stop\n // Attaching preempts whatever ran on this value before (this animation's\n // own previous run included) — the preempted run ends { finished: false }.\n value.__startAnimation(handle)\n if (!ended) {\n loop.start()\n }\n }\n\n return {\n start,\n stop: () => {\n stopActiveRun?.()\n },\n // RN parity: composite reset stops the run and snaps the value back to\n // its construction-time value (loop() relies on this between iterations).\n reset: () => {\n value.resetAnimation()\n },\n }\n}\n"]}
|
package/dist/apis/host.gtkx.js
CHANGED
|
@@ -214,6 +214,15 @@ const SURFACE_SIZE_SIGNALS = [
|
|
|
214
214
|
];
|
|
215
215
|
const WINDOW_ACTIVE_SIGNALS = ["notify::is-active"];
|
|
216
216
|
const gtkVersion = () => `${toNumber(Gtk.getMajorVersion())}.${toNumber(Gtk.getMinorVersion())}.${toNumber(Gtk.getMicroVersion())}`;
|
|
217
|
+
// AdwStyleManager is the only thing that decides the palette here, and it is
|
|
218
|
+
// enough on its own — appearance.test.tsx asserts that a real widget's
|
|
219
|
+
// computed foreground flips with it. This used to also write the classic
|
|
220
|
+
// GtkSettings:gtk-application-prefer-dark-theme, guarding against Adwaita
|
|
221
|
+
// not restyling a GtkApplication (we do not use AdwApplication). Under
|
|
222
|
+
// libadwaita that write is inert: adw_init() takes the color scheme over,
|
|
223
|
+
// answers the setting with "unsupported ... use AdwStyleManager:color-scheme
|
|
224
|
+
// instead" and keeps its own value, so all the duplicate ever produced was a
|
|
225
|
+
// warning per call — seven per test run.
|
|
217
226
|
const setColorScheme = (scheme) => {
|
|
218
227
|
const manager = styleManager();
|
|
219
228
|
if (scheme === "dark") {
|
|
@@ -225,18 +234,6 @@ const setColorScheme = (scheme) => {
|
|
|
225
234
|
else {
|
|
226
235
|
manager.setColorScheme(Adw.ColorScheme.DEFAULT);
|
|
227
236
|
}
|
|
228
|
-
// Our apps are GtkApplication (not AdwApplication), so Adwaita may not
|
|
229
|
-
// restyle widgets: duplicate the request through the classic GTK setting,
|
|
230
|
-
// which the theme always honors.
|
|
231
|
-
const settings = Gtk.Settings.getDefault();
|
|
232
|
-
if (settings) {
|
|
233
|
-
if (scheme === null) {
|
|
234
|
-
settings.resetProperty("gtk-application-prefer-dark-theme");
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
settings.gtkApplicationPreferDarkTheme = scheme === "dark";
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
237
|
};
|
|
241
238
|
const onColorSchemeChange = (notify) => {
|
|
242
239
|
const manager = styleManager();
|