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.
Files changed (340) hide show
  1. package/README.md +5 -2
  2. package/dist/aliases/index.d.ts +84 -0
  3. package/dist/aliases/index.js +208 -0
  4. package/dist/aliases/index.js.map +1 -0
  5. package/dist/animated/index.d.ts +2 -0
  6. package/dist/animated/index.js +5 -0
  7. package/dist/animated/index.js.map +1 -1
  8. package/dist/animated/types.d.ts +1 -0
  9. package/dist/animated/types.js.map +1 -1
  10. package/dist/animated/value-animation.js +17 -4
  11. package/dist/animated/value-animation.js.map +1 -1
  12. package/dist/apis/host.gtkx.js +9 -12
  13. package/dist/apis/host.gtkx.js.map +1 -1
  14. package/dist/apis/index.d.ts +4 -2
  15. package/dist/apis/index.js +2 -0
  16. package/dist/apis/index.js.map +1 -1
  17. package/dist/apis/keyboard.d.ts +60 -0
  18. package/dist/apis/keyboard.js +63 -0
  19. package/dist/apis/keyboard.js.map +1 -0
  20. package/dist/apis/log-box.d.ts +15 -0
  21. package/dist/apis/log-box.js +46 -0
  22. package/dist/apis/log-box.js.map +1 -0
  23. package/dist/apis/platform.d.ts +18 -1
  24. package/dist/apis/platform.js.map +1 -1
  25. package/dist/common/index.d.ts +0 -1
  26. package/dist/common/index.js +24 -1
  27. package/dist/common/index.js.map +1 -1
  28. package/dist/components/animated.d.ts +70 -6
  29. package/dist/components/animated.js +559 -46
  30. package/dist/components/animated.js.map +1 -1
  31. package/dist/components/driven-size.d.ts +27 -0
  32. package/dist/components/driven-size.js +85 -0
  33. package/dist/components/driven-size.js.map +1 -0
  34. package/dist/components/find-node-handle.d.ts +11 -0
  35. package/dist/components/find-node-handle.js +53 -0
  36. package/dist/components/find-node-handle.js.map +1 -0
  37. package/dist/components/flat-list.d.ts +3 -2
  38. package/dist/components/flat-list.js.map +1 -1
  39. package/dist/components/frame-scheduler.d.ts +16 -0
  40. package/dist/components/frame-scheduler.js +37 -0
  41. package/dist/components/frame-scheduler.js.map +1 -0
  42. package/dist/components/image.d.ts +6 -1
  43. package/dist/components/image.js +15 -4
  44. package/dist/components/image.js.map +1 -1
  45. package/dist/components/index.d.ts +7 -5
  46. package/dist/components/index.js +5 -3
  47. package/dist/components/index.js.map +1 -1
  48. package/dist/components/measure.d.ts +51 -1
  49. package/dist/components/measure.js +101 -2
  50. package/dist/components/measure.js.map +1 -1
  51. package/dist/components/pressable.d.ts +61 -1
  52. package/dist/components/pressable.js +151 -4
  53. package/dist/components/pressable.js.map +1 -1
  54. package/dist/components/rect-store.d.ts +58 -0
  55. package/dist/components/rect-store.js +124 -3
  56. package/dist/components/rect-store.js.map +1 -1
  57. package/dist/components/root.js +6 -1
  58. package/dist/components/root.js.map +1 -1
  59. package/dist/components/scroll-phase.d.ts +35 -0
  60. package/dist/components/scroll-phase.js +26 -0
  61. package/dist/components/scroll-phase.js.map +1 -0
  62. package/dist/components/scroll-view.d.ts +39 -3
  63. package/dist/components/scroll-view.js +378 -43
  64. package/dist/components/scroll-view.js.map +1 -1
  65. package/dist/components/text-input.js +9 -25
  66. package/dist/components/text-input.js.map +1 -1
  67. package/dist/components/text.d.ts +6 -2
  68. package/dist/components/text.js +43 -8
  69. package/dist/components/text.js.map +1 -1
  70. package/dist/components/use-focus.d.ts +27 -0
  71. package/dist/components/use-focus.js +116 -0
  72. package/dist/components/use-focus.js.map +1 -0
  73. package/dist/components/use-layout-child.d.ts +13 -1
  74. package/dist/components/use-layout-child.js +188 -5
  75. package/dist/components/use-layout-child.js.map +1 -1
  76. package/dist/components/view.d.ts +5 -2
  77. package/dist/components/view.js +18 -13
  78. package/dist/components/view.js.map +1 -1
  79. package/dist/components/virtualized-list.d.ts +45 -5
  80. package/dist/components/virtualized-list.js +90 -24
  81. package/dist/components/virtualized-list.js.map +1 -1
  82. package/dist/components/wheel-scroll-session.d.ts +7 -0
  83. package/dist/components/wheel-scroll-session.js +53 -0
  84. package/dist/components/wheel-scroll-session.js.map +1 -0
  85. package/dist/components/widget-retention.d.ts +35 -0
  86. package/dist/components/widget-retention.js +169 -0
  87. package/dist/components/widget-retention.js.map +1 -0
  88. package/dist/contracts.d.ts +4 -0
  89. package/dist/contracts.js.map +1 -1
  90. package/dist/dnd/context.d.ts +69 -0
  91. package/dist/dnd/context.js +149 -0
  92. package/dist/dnd/context.js.map +1 -0
  93. package/dist/dnd/draggable.d.ts +59 -0
  94. package/dist/dnd/draggable.js +149 -0
  95. package/dist/dnd/draggable.js.map +1 -0
  96. package/dist/dnd/droppable.d.ts +24 -0
  97. package/dist/dnd/droppable.js +74 -0
  98. package/dist/dnd/droppable.js.map +1 -0
  99. package/dist/dnd/gtk-controllers.d.ts +39 -0
  100. package/dist/dnd/gtk-controllers.js +110 -0
  101. package/dist/dnd/gtk-controllers.js.map +1 -0
  102. package/dist/dnd/index.d.ts +6 -0
  103. package/dist/dnd/index.js +31 -0
  104. package/dist/dnd/index.js.map +1 -0
  105. package/dist/dnd/order.d.ts +7 -0
  106. package/dist/dnd/order.js +20 -0
  107. package/dist/dnd/order.js.map +1 -0
  108. package/dist/dnd/payload.d.ts +14 -0
  109. package/dist/dnd/payload.js +41 -0
  110. package/dist/dnd/payload.js.map +1 -0
  111. package/dist/dnd/sortable.d.ts +49 -0
  112. package/dist/dnd/sortable.js +307 -0
  113. package/dist/dnd/sortable.js.map +1 -0
  114. package/dist/dnd/types.d.ts +290 -0
  115. package/dist/dnd/types.js +25 -0
  116. package/dist/dnd/types.js.map +1 -0
  117. package/dist/gesture-handler-compat/builder.d.ts +251 -0
  118. package/dist/gesture-handler-compat/builder.js +513 -0
  119. package/dist/gesture-handler-compat/builder.js.map +1 -0
  120. package/dist/gesture-handler-compat/composition.d.ts +23 -0
  121. package/dist/gesture-handler-compat/composition.js +111 -0
  122. package/dist/gesture-handler-compat/composition.js.map +1 -0
  123. package/dist/gesture-handler-compat/deciders.d.ts +3 -0
  124. package/dist/gesture-handler-compat/deciders.js +47 -0
  125. package/dist/gesture-handler-compat/deciders.js.map +1 -0
  126. package/dist/gesture-handler-compat/detector-runtime.d.ts +44 -0
  127. package/dist/gesture-handler-compat/detector-runtime.js +374 -0
  128. package/dist/gesture-handler-compat/detector-runtime.js.map +1 -0
  129. package/dist/gesture-handler-compat/detector.d.ts +22 -0
  130. package/dist/gesture-handler-compat/detector.js +104 -0
  131. package/dist/gesture-handler-compat/detector.js.map +1 -0
  132. package/dist/gesture-handler-compat/fling.d.ts +24 -0
  133. package/dist/gesture-handler-compat/fling.js +123 -0
  134. package/dist/gesture-handler-compat/fling.js.map +1 -0
  135. package/dist/gesture-handler-compat/force-touch.d.ts +13 -0
  136. package/dist/gesture-handler-compat/force-touch.js +40 -0
  137. package/dist/gesture-handler-compat/force-touch.js.map +1 -0
  138. package/dist/gesture-handler-compat/hooks.d.ts +157 -0
  139. package/dist/gesture-handler-compat/hooks.js +268 -0
  140. package/dist/gesture-handler-compat/hooks.js.map +1 -0
  141. package/dist/gesture-handler-compat/hover.d.ts +2 -0
  142. package/dist/gesture-handler-compat/hover.js +22 -0
  143. package/dist/gesture-handler-compat/hover.js.map +1 -0
  144. package/dist/gesture-handler-compat/index.d.ts +98 -0
  145. package/dist/gesture-handler-compat/index.js +255 -0
  146. package/dist/gesture-handler-compat/index.js.map +1 -0
  147. package/dist/gesture-handler-compat/long-press.d.ts +6 -0
  148. package/dist/gesture-handler-compat/long-press.js +21 -0
  149. package/dist/gesture-handler-compat/long-press.js.map +1 -0
  150. package/dist/gesture-handler-compat/manual.d.ts +2 -0
  151. package/dist/gesture-handler-compat/manual.js +18 -0
  152. package/dist/gesture-handler-compat/manual.js.map +1 -0
  153. package/dist/gesture-handler-compat/native.d.ts +7 -0
  154. package/dist/gesture-handler-compat/native.js +34 -0
  155. package/dist/gesture-handler-compat/native.js.map +1 -0
  156. package/dist/gesture-handler-compat/orchestrator.d.ts +77 -0
  157. package/dist/gesture-handler-compat/orchestrator.js +284 -0
  158. package/dist/gesture-handler-compat/orchestrator.js.map +1 -0
  159. package/dist/gesture-handler-compat/pan.d.ts +23 -0
  160. package/dist/gesture-handler-compat/pan.js +116 -0
  161. package/dist/gesture-handler-compat/pan.js.map +1 -0
  162. package/dist/gesture-handler-compat/recognizer.d.ts +268 -0
  163. package/dist/gesture-handler-compat/recognizer.js +1056 -0
  164. package/dist/gesture-handler-compat/recognizer.js.map +1 -0
  165. package/dist/gesture-handler-compat/relations.d.ts +43 -0
  166. package/dist/gesture-handler-compat/relations.js +128 -0
  167. package/dist/gesture-handler-compat/relations.js.map +1 -0
  168. package/dist/gesture-handler-compat/tap.d.ts +6 -0
  169. package/dist/gesture-handler-compat/tap.js +29 -0
  170. package/dist/gesture-handler-compat/tap.js.map +1 -0
  171. package/dist/gesture-handler-compat/touchpad.d.ts +41 -0
  172. package/dist/gesture-handler-compat/touchpad.js +64 -0
  173. package/dist/gesture-handler-compat/touchpad.js.map +1 -0
  174. package/dist/gesture-handler-compat/types.d.ts +441 -0
  175. package/dist/gesture-handler-compat/types.js +167 -0
  176. package/dist/gesture-handler-compat/types.js.map +1 -0
  177. package/dist/gtk/controllers.d.ts +39 -0
  178. package/dist/gtk/controllers.js +92 -0
  179. package/dist/gtk/controllers.js.map +1 -0
  180. package/dist/gtk/index.d.ts +2 -1
  181. package/dist/gtk/index.js +7 -1
  182. package/dist/gtk/index.js.map +1 -1
  183. package/dist/gtkx/bridge/geometry.js +6 -4
  184. package/dist/gtkx/bridge/geometry.js.map +1 -1
  185. package/dist/gtkx/bridge/index.d.ts +5 -3
  186. package/dist/gtkx/bridge/index.js +6 -3
  187. package/dist/gtkx/bridge/index.js.map +1 -1
  188. package/dist/gtkx/bridge/slot-portal.js.map +1 -1
  189. package/dist/gtkx/bridge/use-signal.js +1 -1
  190. package/dist/gtkx/bridge/use-signal.js.map +1 -1
  191. package/dist/gtkx/bridge/view-box.d.ts +56 -0
  192. package/dist/gtkx/bridge/view-box.js +394 -9
  193. package/dist/gtkx/bridge/view-box.js.map +1 -1
  194. package/dist/gtkx/bridge/widget-css.d.ts +17 -0
  195. package/dist/gtkx/bridge/widget-css.js +72 -0
  196. package/dist/gtkx/bridge/widget-css.js.map +1 -0
  197. package/dist/index.d.ts +3 -3
  198. package/dist/index.js +2 -2
  199. package/dist/index.js.map +1 -1
  200. package/dist/layout/driven-size.d.ts +12 -0
  201. package/dist/layout/driven-size.js +70 -0
  202. package/dist/layout/driven-size.js.map +1 -0
  203. package/dist/layout/engine.d.ts +17 -1
  204. package/dist/layout/engine.js +3 -20
  205. package/dist/layout/engine.js.map +1 -1
  206. package/dist/layout/node.d.ts +13 -0
  207. package/dist/layout/node.js +14 -0
  208. package/dist/layout/node.js.map +1 -1
  209. package/dist/layout/yoga.d.ts +3 -2
  210. package/dist/layout/yoga.js +5 -2
  211. package/dist/layout/yoga.js.map +1 -1
  212. package/dist/mcp/data/generated.d.ts +257 -60
  213. package/dist/mcp/data/generated.js +306 -62
  214. package/dist/mcp/data/generated.js.map +1 -1
  215. package/dist/metro/index.d.ts +10 -0
  216. package/dist/metro/index.js +21 -12
  217. package/dist/metro/index.js.map +1 -1
  218. package/dist/navigation/sidebar.d.ts +16 -0
  219. package/dist/navigation/sidebar.js +65 -1
  220. package/dist/navigation/sidebar.js.map +1 -1
  221. package/dist/reanimated-compat/animated-ref.d.ts +32 -0
  222. package/dist/reanimated-compat/animated-ref.js +57 -0
  223. package/dist/reanimated-compat/animated-ref.js.map +1 -0
  224. package/dist/reanimated-compat/animation.d.ts +177 -0
  225. package/dist/reanimated-compat/animation.js +540 -0
  226. package/dist/reanimated-compat/animation.js.map +1 -0
  227. package/dist/reanimated-compat/color.d.ts +28 -0
  228. package/dist/reanimated-compat/color.js +249 -0
  229. package/dist/reanimated-compat/color.js.map +1 -0
  230. package/dist/reanimated-compat/decay.d.ts +39 -0
  231. package/dist/reanimated-compat/decay.js +96 -0
  232. package/dist/reanimated-compat/decay.js.map +1 -0
  233. package/dist/reanimated-compat/easing.d.ts +30 -0
  234. package/dist/reanimated-compat/easing.js +76 -0
  235. package/dist/reanimated-compat/easing.js.map +1 -0
  236. package/dist/reanimated-compat/hooks.d.ts +14 -0
  237. package/dist/reanimated-compat/hooks.js +217 -0
  238. package/dist/reanimated-compat/hooks.js.map +1 -0
  239. package/dist/reanimated-compat/index.d.ts +258 -0
  240. package/dist/reanimated-compat/index.js +464 -0
  241. package/dist/reanimated-compat/index.js.map +1 -0
  242. package/dist/reanimated-compat/interpolation.d.ts +18 -0
  243. package/dist/reanimated-compat/interpolation.js +122 -0
  244. package/dist/reanimated-compat/interpolation.js.map +1 -0
  245. package/dist/reanimated-compat/layout-animation-config.d.ts +43 -0
  246. package/dist/reanimated-compat/layout-animation-config.js +78 -0
  247. package/dist/reanimated-compat/layout-animation-config.js.map +1 -0
  248. package/dist/reanimated-compat/layout-animation-presets.d.ts +117 -0
  249. package/dist/reanimated-compat/layout-animation-presets.js +498 -0
  250. package/dist/reanimated-compat/layout-animation-presets.js.map +1 -0
  251. package/dist/reanimated-compat/layout-animation-runtime.d.ts +21 -0
  252. package/dist/reanimated-compat/layout-animation-runtime.js +311 -0
  253. package/dist/reanimated-compat/layout-animation-runtime.js.map +1 -0
  254. package/dist/reanimated-compat/layout-animation-view.d.ts +27 -0
  255. package/dist/reanimated-compat/layout-animation-view.js +266 -0
  256. package/dist/reanimated-compat/layout-animation-view.js.map +1 -0
  257. package/dist/reanimated-compat/layout-animation.d.ts +171 -0
  258. package/dist/reanimated-compat/layout-animation.js +469 -0
  259. package/dist/reanimated-compat/layout-animation.js.map +1 -0
  260. package/dist/reanimated-compat/layout-transitions.d.ts +83 -0
  261. package/dist/reanimated-compat/layout-transitions.js +350 -0
  262. package/dist/reanimated-compat/layout-transitions.js.map +1 -0
  263. package/dist/reanimated-compat/mutable.d.ts +29 -0
  264. package/dist/reanimated-compat/mutable.js +139 -0
  265. package/dist/reanimated-compat/mutable.js.map +1 -0
  266. package/dist/reanimated-compat/props.d.ts +18 -0
  267. package/dist/reanimated-compat/props.js +111 -0
  268. package/dist/reanimated-compat/props.js.map +1 -0
  269. package/dist/reanimated-compat/scroll-handler.d.ts +119 -0
  270. package/dist/reanimated-compat/scroll-handler.js +274 -0
  271. package/dist/reanimated-compat/scroll-handler.js.map +1 -0
  272. package/dist/reanimated-compat/scroll-offset.d.ts +12 -0
  273. package/dist/reanimated-compat/scroll-offset.js +104 -0
  274. package/dist/reanimated-compat/scroll-offset.js.map +1 -0
  275. package/dist/reanimated-compat/style.d.ts +90 -0
  276. package/dist/reanimated-compat/style.js +452 -0
  277. package/dist/reanimated-compat/style.js.map +1 -0
  278. package/dist/reanimated-compat/test-timers.d.ts +28 -0
  279. package/dist/reanimated-compat/test-timers.js +136 -0
  280. package/dist/reanimated-compat/test-timers.js.map +1 -0
  281. package/dist/reanimated-compat/threads.d.ts +13 -0
  282. package/dist/reanimated-compat/threads.js +41 -0
  283. package/dist/reanimated-compat/threads.js.map +1 -0
  284. package/dist/reanimated-compat/tracking.d.ts +41 -0
  285. package/dist/reanimated-compat/tracking.js +106 -0
  286. package/dist/reanimated-compat/tracking.js.map +1 -0
  287. package/dist/reanimated-compat/updater-animations.d.ts +36 -0
  288. package/dist/reanimated-compat/updater-animations.js +273 -0
  289. package/dist/reanimated-compat/updater-animations.js.map +1 -0
  290. package/dist/responder/system.d.ts +80 -7
  291. package/dist/responder/system.js +143 -23
  292. package/dist/responder/system.js.map +1 -1
  293. package/dist/responder/use-responder.d.ts +11 -0
  294. package/dist/responder/use-responder.js +225 -6
  295. package/dist/responder/use-responder.js.map +1 -1
  296. package/dist/runner/host-dev.js +1 -1
  297. package/dist/runner/host-dev.js.map +1 -1
  298. package/dist/runner/host.js +1 -1
  299. package/dist/runner/host.js.map +1 -1
  300. package/dist/runner/index.js +3 -3
  301. package/dist/runner/index.js.map +1 -1
  302. package/dist/sea/gtkx-config-module.js +1 -1
  303. package/dist/sea/gtkx-config-module.js.map +1 -1
  304. package/dist/style/absolute-insets.d.ts +26 -0
  305. package/dist/style/absolute-insets.js +113 -0
  306. package/dist/style/absolute-insets.js.map +1 -0
  307. package/dist/style/animated-size.d.ts +25 -0
  308. package/dist/style/animated-size.js +225 -0
  309. package/dist/style/animated-size.js.map +1 -0
  310. package/dist/style/colors.d.ts +17 -0
  311. package/dist/style/colors.js +25 -6
  312. package/dist/style/colors.js.map +1 -1
  313. package/dist/style/imperative-css.d.ts +21 -0
  314. package/dist/style/imperative-css.js +63 -0
  315. package/dist/style/imperative-css.js.map +1 -0
  316. package/dist/style/index.d.ts +2 -1
  317. package/dist/style/index.js +2 -1
  318. package/dist/style/index.js.map +1 -1
  319. package/dist/style/split-style.js +5 -0
  320. package/dist/style/split-style.js.map +1 -1
  321. package/dist/testing/index.js.map +1 -1
  322. package/dist/unsupported-export.d.ts +8 -0
  323. package/dist/unsupported-export.js +66 -0
  324. package/dist/unsupported-export.js.map +1 -0
  325. package/dist/vite/index.d.ts +21 -8
  326. package/dist/vite/index.js +127 -82
  327. package/dist/vite/index.js.map +1 -1
  328. package/dist/vitest/index.d.ts +2 -2
  329. package/dist/vitest/index.js.map +1 -1
  330. package/dist/worklets-compat/index.d.ts +4 -0
  331. package/dist/worklets-compat/index.js +28 -0
  332. package/dist/worklets-compat/index.js.map +1 -0
  333. package/dist/worklets-compat/surface.d.ts +110 -0
  334. package/dist/worklets-compat/surface.js +153 -0
  335. package/dist/worklets-compat/surface.js.map +1 -0
  336. package/package.json +25 -9
  337. package/types.d.ts +9 -0
  338. package/dist/common/list.d.ts +0 -82
  339. package/dist/common/list.js +0 -166
  340. package/dist/common/list.js.map +0 -1
@@ -103,6 +103,11 @@ const VISUAL_KEYS = {
103
103
  // contract and to View, and nothing forced anyone to classify it.
104
104
  const BEHAVIORAL_KEYS = {
105
105
  pointerEvents: true,
106
+ // `zIndex` joined it for the same reason: it is neither a Yoga input nor a
107
+ // CSS declaration, it is the container widget's paint and pick order
108
+ // (gtkx/bridge/view-box.ts), and useLayoutChild pushes it there from the
109
+ // flattened style.
110
+ zIndex: true,
106
111
  };
107
112
  /**
108
113
  * Splits a flattened style into { layout, visual }. Behavioral props
@@ -1 +1 @@
1
- {"version":3,"file":"split-style.js","sourceRoot":"","sources":["../../src/style/split-style.ts"],"names":[],"mappings":"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","sourcesContent":["// Classifies a flattened style into layout props (consumed by the Yoga\n// engine) and visual props (compiled into GTK CSS). Pure module.\n\nimport type {\n FlatStyle,\n LayoutStyle,\n SplitStyle,\n VisualStyle,\n} from \"../contracts\"\nimport { warnOnce } from \"./dev-warning\"\n\n// Exhaustive over the frozen contract: adding a key to LayoutStyle in\n// contracts.ts fails compilation here until the key is classified.\nconst LAYOUT_KEYS: Record<keyof LayoutStyle, true> = {\n alignContent: true,\n alignItems: true,\n alignSelf: true,\n aspectRatio: true,\n bottom: true,\n columnGap: true,\n direction: true,\n display: true,\n flex: true,\n flexBasis: true,\n flexDirection: true,\n flexGrow: true,\n flexShrink: true,\n flexWrap: true,\n gap: true,\n height: true,\n justifyContent: true,\n left: true,\n margin: true,\n marginBottom: true,\n marginHorizontal: true,\n marginLeft: true,\n marginRight: true,\n marginTop: true,\n marginVertical: true,\n maxHeight: true,\n maxWidth: true,\n minHeight: true,\n minWidth: true,\n overflow: true,\n padding: true,\n paddingBottom: true,\n paddingHorizontal: true,\n paddingLeft: true,\n paddingRight: true,\n paddingTop: true,\n paddingVertical: true,\n position: true,\n right: true,\n rowGap: true,\n top: true,\n width: true,\n}\n\n// Note: `textDecorationLine` and `textAlign` are visual by contract but never\n// reach CSS — Pango carries both, and the Text component applies them.\n// Note: `transform` is visual by contract — it is applied as the\n// GskTransform of the child's allocation, not through CSS, and is passed\n// through here untouched.\nconst VISUAL_KEYS: Record<keyof VisualStyle, true> = {\n backgroundColor: true,\n boxShadow: true,\n borderBottomColor: true,\n borderBottomLeftRadius: true,\n borderBottomRightRadius: true,\n borderBottomWidth: true,\n borderColor: true,\n borderLeftColor: true,\n borderLeftWidth: true,\n borderRadius: true,\n borderRightColor: true,\n borderRightWidth: true,\n borderStyle: true,\n borderTopColor: true,\n borderTopLeftRadius: true,\n borderTopRightRadius: true,\n borderTopWidth: true,\n borderWidth: true,\n color: true,\n fontFamily: true,\n fontSize: true,\n fontStyle: true,\n fontWeight: true,\n letterSpacing: true,\n lineHeight: true,\n opacity: true,\n outlineColor: true,\n outlineOffset: true,\n outlineStyle: true,\n outlineWidth: true,\n textAlign: true,\n textDecorationLine: true,\n transform: true,\n}\n\n// Behavioral props: supported, but by neither half of this pipeline. Since\n// RN 0.71 `pointerEvents` may be written in a style and not only as a prop,\n// and View reads it straight off the flattened style (components/view.tsx)\n// to drive GTK picking — it never reaches Yoga and it has no CSS\n// equivalent. So the splitter must CONSUME it silently: warning here told a\n// user that working code was being ignored, on the very line where\n// tests/gtk/components/pointer-events.gtk.test.tsx proves it is not.\n//\n// Exhaustive the same way the two buckets above are, but over what FlatStyle\n// adds ON TOP of LayoutStyle and VisualStyle — that Omit makes the three\n// records a partition of the contract, so a future fourth kind of style prop\n// cannot be added to FlatStyle without failing compilation right here. That\n// is exactly the drift this list suffered: `pointerEvents` was added to the\n// contract and to View, and nothing forced anyone to classify it.\nconst BEHAVIORAL_KEYS: Record<\n keyof Omit<FlatStyle, keyof LayoutStyle | keyof VisualStyle>,\n true\n> = {\n pointerEvents: true,\n}\n\n/**\n * Splits a flattened style into { layout, visual }. Behavioral props\n * (pointerEvents) belong to neither bucket and are consumed silently — the\n * component that owns the behavior reads them from the flattened style.\n * Unknown properties are ignored with a one-time dev warning per key;\n * undefined values are dropped.\n */\nexport const splitStyle = (flat: FlatStyle): SplitStyle => {\n const layout: LayoutStyle = {}\n const visual: VisualStyle = {}\n for (const [key, value] of Object.entries(flat)) {\n if (value === undefined) {\n continue\n }\n if (Object.hasOwn(LAYOUT_KEYS, key)) {\n ;(layout as Record<string, unknown>)[key] = value\n } else if (Object.hasOwn(VISUAL_KEYS, key)) {\n ;(visual as Record<string, unknown>)[key] = value\n } else if (!Object.hasOwn(BEHAVIORAL_KEYS, key)) {\n warnOnce(\n `unknown-style-prop:${key}`,\n `[react-native-gtkx] Unknown style property \"${key}\" is not supported and will be ignored`,\n )\n }\n }\n return { layout, visual }\n}\n"]}
1
+ {"version":3,"file":"split-style.js","sourceRoot":"","sources":["../../src/style/split-style.ts"],"names":[],"mappings":"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","sourcesContent":["// Classifies a flattened style into layout props (consumed by the Yoga\n// engine) and visual props (compiled into GTK CSS). Pure module.\n\nimport type {\n FlatStyle,\n LayoutStyle,\n SplitStyle,\n VisualStyle,\n} from \"../contracts\"\nimport { warnOnce } from \"./dev-warning\"\n\n// Exhaustive over the frozen contract: adding a key to LayoutStyle in\n// contracts.ts fails compilation here until the key is classified.\nconst LAYOUT_KEYS: Record<keyof LayoutStyle, true> = {\n alignContent: true,\n alignItems: true,\n alignSelf: true,\n aspectRatio: true,\n bottom: true,\n columnGap: true,\n direction: true,\n display: true,\n flex: true,\n flexBasis: true,\n flexDirection: true,\n flexGrow: true,\n flexShrink: true,\n flexWrap: true,\n gap: true,\n height: true,\n justifyContent: true,\n left: true,\n margin: true,\n marginBottom: true,\n marginHorizontal: true,\n marginLeft: true,\n marginRight: true,\n marginTop: true,\n marginVertical: true,\n maxHeight: true,\n maxWidth: true,\n minHeight: true,\n minWidth: true,\n overflow: true,\n padding: true,\n paddingBottom: true,\n paddingHorizontal: true,\n paddingLeft: true,\n paddingRight: true,\n paddingTop: true,\n paddingVertical: true,\n position: true,\n right: true,\n rowGap: true,\n top: true,\n width: true,\n}\n\n// Note: `textDecorationLine` and `textAlign` are visual by contract but never\n// reach CSS — Pango carries both, and the Text component applies them.\n// Note: `transform` is visual by contract — it is applied as the\n// GskTransform of the child's allocation, not through CSS, and is passed\n// through here untouched.\nconst VISUAL_KEYS: Record<keyof VisualStyle, true> = {\n backgroundColor: true,\n boxShadow: true,\n borderBottomColor: true,\n borderBottomLeftRadius: true,\n borderBottomRightRadius: true,\n borderBottomWidth: true,\n borderColor: true,\n borderLeftColor: true,\n borderLeftWidth: true,\n borderRadius: true,\n borderRightColor: true,\n borderRightWidth: true,\n borderStyle: true,\n borderTopColor: true,\n borderTopLeftRadius: true,\n borderTopRightRadius: true,\n borderTopWidth: true,\n borderWidth: true,\n color: true,\n fontFamily: true,\n fontSize: true,\n fontStyle: true,\n fontWeight: true,\n letterSpacing: true,\n lineHeight: true,\n opacity: true,\n outlineColor: true,\n outlineOffset: true,\n outlineStyle: true,\n outlineWidth: true,\n textAlign: true,\n textDecorationLine: true,\n transform: true,\n}\n\n// Behavioral props: supported, but by neither half of this pipeline. Since\n// RN 0.71 `pointerEvents` may be written in a style and not only as a prop,\n// and View reads it straight off the flattened style (components/view.tsx)\n// to drive GTK picking — it never reaches Yoga and it has no CSS\n// equivalent. So the splitter must CONSUME it silently: warning here told a\n// user that working code was being ignored, on the very line where\n// tests/gtk/components/pointer-events.gtk.test.tsx proves it is not.\n//\n// Exhaustive the same way the two buckets above are, but over what FlatStyle\n// adds ON TOP of LayoutStyle and VisualStyle — that Omit makes the three\n// records a partition of the contract, so a future fourth kind of style prop\n// cannot be added to FlatStyle without failing compilation right here. That\n// is exactly the drift this list suffered: `pointerEvents` was added to the\n// contract and to View, and nothing forced anyone to classify it.\nconst BEHAVIORAL_KEYS: Record<\n keyof Omit<FlatStyle, keyof LayoutStyle | keyof VisualStyle>,\n true\n> = {\n pointerEvents: true,\n // `zIndex` joined it for the same reason: it is neither a Yoga input nor a\n // CSS declaration, it is the container widget's paint and pick order\n // (gtkx/bridge/view-box.ts), and useLayoutChild pushes it there from the\n // flattened style.\n zIndex: true,\n}\n\n/**\n * Splits a flattened style into { layout, visual }. Behavioral props\n * (pointerEvents) belong to neither bucket and are consumed silently — the\n * component that owns the behavior reads them from the flattened style.\n * Unknown properties are ignored with a one-time dev warning per key;\n * undefined values are dropped.\n */\nexport const splitStyle = (flat: FlatStyle): SplitStyle => {\n const layout: LayoutStyle = {}\n const visual: VisualStyle = {}\n for (const [key, value] of Object.entries(flat)) {\n if (value === undefined) {\n continue\n }\n if (Object.hasOwn(LAYOUT_KEYS, key)) {\n ;(layout as Record<string, unknown>)[key] = value\n } else if (Object.hasOwn(VISUAL_KEYS, key)) {\n ;(visual as Record<string, unknown>)[key] = value\n } else if (!Object.hasOwn(BEHAVIORAL_KEYS, key)) {\n warnOnce(\n `unknown-style-prop:${key}`,\n `[react-native-gtkx] Unknown style property \"${key}\" is not supported and will be ignored`,\n )\n }\n }\n return { layout, visual }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAOlD,2EAA2E;AAC3E,0EAA0E;AAC1E,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,iDAAiD;AACjD,cAAc,eAAe,CAAA;AA2B7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAmC,EACnC,OAAkC;IAIlC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,QAAoC,EACpC,OAAmC,CACpC,CAAA;IACD,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5B,CAAC","sourcesContent":["import { render, renderHook } from \"@gtkx/testing\"\nimport type {\n RenderHookOptions,\n RenderHookResult,\n RenderResult,\n} from \"@gtkx/testing\"\n\n// react-native-gtkx/testing — @gtkx/testing's queries, render, renderHook,\n// fireEvent and userEvent already operate on the real GTK widget tree our\n// RN components render into, so `getByText` on a `Text` or `userEvent.click`\n// on a `Pressable` already work with no RN-flavoured wrapper: this subpath\n// re-exports that surface as-is, one import source for a consumer, plus the\n// one genuinely repeated workaround (see below).\nexport * from \"@gtkx/testing\"\n\n// RC3-WORKAROUND(renderhook-no-window): see docs/gtkx-rc3-notes.md\n// @gtkx/testing's renderHook() always mounts its test component into a bare\n// Gtk.Box, so a hook that reads the active toplevel (useWindowDimensions,\n// anything through Gtk.Window.getToplevels()) has nothing to read. render()\n// always creates and presents a harness window when no container is given,\n// regardless of what it renders — rendering null is enough to get one.\n\n/**\n * Like `renderHook`, but first creates and presents a harness window (via\n * `render(null)`), so window-dependent hooks have a toplevel to read.\n * Cleanup is automatic — @gtkx/testing tears down every active render\n * (including the harness window) after each test.\n */\nexport function renderHookWithWindow<Result>(\n callback: () => Result,\n options?: RenderHookOptions<undefined>,\n): Promise<\n RenderHookResult<Result, undefined> & { window: RenderResult[\"container\"] }\n>\nexport function renderHookWithWindow<Result, Props>(\n callback: (props: Props) => Result,\n options: RenderHookOptions<Props>,\n): Promise<\n RenderHookResult<Result, Props> & { window: RenderResult[\"container\"] }\n>\nexport async function renderHookWithWindow<Result, Props>(\n callback: (props?: Props) => Result,\n options?: RenderHookOptions<Props>,\n): Promise<\n RenderHookResult<Result, Props> & { window: RenderResult[\"container\"] }\n> {\n const { container: window } = await render(null)\n const hook = await renderHook(\n callback as (props: Props) => Result,\n options as RenderHookOptions<Props>,\n )\n return { ...hook, window }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAOlD,2EAA2E;AAC3E,0EAA0E;AAC1E,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,iDAAiD;AACjD,cAAc,eAAe,CAAA;AA2B7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAmC,EACnC,OAAkC;IAIlC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,QAAoC,EACpC,OAAmC,CACpC,CAAA;IACD,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5B,CAAC","sourcesContent":["import { render, renderHook } from \"@gtkx/testing\"\nimport type {\n RenderHookOptions,\n RenderHookResult,\n RenderResult,\n} from \"@gtkx/testing\"\n\n// react-native-gtkx/testing — @gtkx/testing's queries, render, renderHook,\n// fireEvent and userEvent already operate on the real GTK widget tree our\n// RN components render into, so `getByText` on a `Text` or `userEvent.click`\n// on a `Pressable` already work with no RN-flavoured wrapper: this subpath\n// re-exports that surface as-is, one import source for a consumer, plus the\n// one genuinely repeated workaround (see below).\nexport * from \"@gtkx/testing\"\n\n// RC4-WORKAROUND(renderhook-no-window): see docs/gtkx-rc4-notes.md\n// @gtkx/testing's renderHook() always mounts its test component into a bare\n// Gtk.Box, so a hook that reads the active toplevel (useWindowDimensions,\n// anything through Gtk.Window.getToplevels()) has nothing to read. render()\n// always creates and presents a harness window when no container is given,\n// regardless of what it renders — rendering null is enough to get one.\n\n/**\n * Like `renderHook`, but first creates and presents a harness window (via\n * `render(null)`), so window-dependent hooks have a toplevel to read.\n * Cleanup is automatic — @gtkx/testing tears down every active render\n * (including the harness window) after each test.\n */\nexport function renderHookWithWindow<Result>(\n callback: () => Result,\n options?: RenderHookOptions<undefined>,\n): Promise<\n RenderHookResult<Result, undefined> & { window: RenderResult[\"container\"] }\n>\nexport function renderHookWithWindow<Result, Props>(\n callback: (props: Props) => Result,\n options: RenderHookOptions<Props>,\n): Promise<\n RenderHookResult<Result, Props> & { window: RenderResult[\"container\"] }\n>\nexport async function renderHookWithWindow<Result, Props>(\n callback: (props?: Props) => Result,\n options?: RenderHookOptions<Props>,\n): Promise<\n RenderHookResult<Result, Props> & { window: RenderResult[\"container\"] }\n> {\n const { container: window } = await render(null)\n const hook = await renderHook(\n callback as (props: Props) => Result,\n options as RenderHookOptions<Props>,\n )\n return { ...hook, window }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Builds an `unsupported(name)` for one mirrored package.
3
+ *
4
+ * `explanation` is appended to every message and is where the surface says
5
+ * what IS implemented and what to reach for instead — a refusal that does not
6
+ * point somewhere is half an answer.
7
+ */
8
+ export declare const createUnsupportedFactory: (packageName: string, explanation: string) => ((name: string) => any);
@@ -0,0 +1,66 @@
1
+ // The stand-in for an export a compat surface deliberately does not
2
+ // implement.
3
+ //
4
+ // WHY it throws rather than no-ops. docs/research/gestures.md records the
5
+ // failure mode this repo most wants to avoid: `Animated.View` silently
6
+ // accepting the responder props and ignoring them compiled, ran, and did
7
+ // nothing — "the worst possible failure mode". A `PanGestureHandler` that
8
+ // renders its children without gestures, or a `FadeIn` that mounts without
9
+ // fading, is the same trap. An unsupported import must fail where it is
10
+ // used, naming itself and naming the replacement.
11
+ //
12
+ // Shared by every mirrored package (react-native-gesture-handler,
13
+ // react-native-reanimated) because the trap is the same one each time and the
14
+ // introspection allowlist below is the part that is easy to get subtly wrong.
15
+ /**
16
+ * Builds an `unsupported(name)` for one mirrored package.
17
+ *
18
+ * `explanation` is appended to every message and is where the surface says
19
+ * what IS implemented and what to reach for instead — a refusal that does not
20
+ * point somewhere is half an answer.
21
+ */
22
+ export const createUnsupportedFactory = (packageName, explanation) => {
23
+ // React, bundlers and `console.log` all introspect a value before using it.
24
+ // Throwing on `$$typeof` or `toString` would replace a precise message with
25
+ // a confusing one from inside React, so those reads answer normally; every
26
+ // read that could only come from real use throws.
27
+ const introspection = new Set([
28
+ "$$typeof",
29
+ "prototype",
30
+ "name",
31
+ "length",
32
+ "displayName",
33
+ "defaultProps",
34
+ "propTypes",
35
+ "contextTypes",
36
+ "childContextTypes",
37
+ "toString",
38
+ "toJSON",
39
+ "then",
40
+ "_owner",
41
+ "_store",
42
+ "render",
43
+ "constructor",
44
+ ]);
45
+ /**
46
+ * A FUNCTION wrapped in a Proxy, so the symbol throws however it is
47
+ * reached: called as a hook or factory (`usePanGesture()`), rendered as a
48
+ * component (React calls it), or read as a namespace (`Gesture.Pan()`,
49
+ * `State.ACTIVE`).
50
+ */
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ return (name) => {
53
+ const fail = () => {
54
+ throw new Error(`${packageName}: \`${name}\` is not supported on Linux ` +
55
+ `(react-native-gtkx). ${explanation}`);
56
+ };
57
+ return new Proxy(fail, {
58
+ get: (target, key, receiver) => typeof key === "symbol" || introspection.has(key)
59
+ ? Reflect.get(target, key, receiver)
60
+ : fail(),
61
+ apply: fail,
62
+ construct: fail,
63
+ });
64
+ };
65
+ };
66
+ //# sourceMappingURL=unsupported-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsupported-export.js","sourceRoot":"","sources":["../src/unsupported-export.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,aAAa;AACb,EAAE;AACF,0EAA0E;AAC1E,uEAAuE;AACvE,yEAAyE;AACzE,0EAA0E;AAC1E,2EAA2E;AAC3E,wEAAwE;AACxE,kDAAkD;AAClD,EAAE;AACF,kEAAkE;AAClE,8EAA8E;AAC9E,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,WAAmB,EACnB,WAAmB,EAEM,EAAE;IAC3B,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,kDAAkD;IAClD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;QAC5B,UAAU;QACV,WAAW;QACX,MAAM;QACN,QAAQ;QACR,aAAa;QACb,cAAc;QACd,WAAW;QACX,cAAc;QACd,mBAAmB;QACnB,UAAU;QACV,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,aAAa;KACd,CAAC,CAAA;IAEF;;;;;OAKG;IACH,8DAA8D;IAC9D,OAAO,CAAC,IAAY,EAAO,EAAE;QAC3B,MAAM,IAAI,GAAG,GAAU,EAAE;YACvB,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,OAAO,IAAI,+BAA+B;gBACtD,wBAAwB,WAAW,EAAE,CACxC,CAAA;QACH,CAAC,CAAA;QAED,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;YACrB,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,CAC7B,OAAO,GAAG,KAAK,QAAQ,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;gBAC/C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC;gBACpC,CAAC,CAAC,IAAI,EAAE;YACZ,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC,CAAA","sourcesContent":["// The stand-in for an export a compat surface deliberately does not\n// implement.\n//\n// WHY it throws rather than no-ops. docs/research/gestures.md records the\n// failure mode this repo most wants to avoid: `Animated.View` silently\n// accepting the responder props and ignoring them compiled, ran, and did\n// nothing — \"the worst possible failure mode\". A `PanGestureHandler` that\n// renders its children without gestures, or a `FadeIn` that mounts without\n// fading, is the same trap. An unsupported import must fail where it is\n// used, naming itself and naming the replacement.\n//\n// Shared by every mirrored package (react-native-gesture-handler,\n// react-native-reanimated) because the trap is the same one each time and the\n// introspection allowlist below is the part that is easy to get subtly wrong.\n\n/**\n * Builds an `unsupported(name)` for one mirrored package.\n *\n * `explanation` is appended to every message and is where the surface says\n * what IS implemented and what to reach for instead — a refusal that does not\n * point somewhere is half an answer.\n */\nexport const createUnsupportedFactory = (\n packageName: string,\n explanation: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ((name: string) => any) => {\n // React, bundlers and `console.log` all introspect a value before using it.\n // Throwing on `$$typeof` or `toString` would replace a precise message with\n // a confusing one from inside React, so those reads answer normally; every\n // read that could only come from real use throws.\n const introspection = new Set([\n \"$$typeof\",\n \"prototype\",\n \"name\",\n \"length\",\n \"displayName\",\n \"defaultProps\",\n \"propTypes\",\n \"contextTypes\",\n \"childContextTypes\",\n \"toString\",\n \"toJSON\",\n \"then\",\n \"_owner\",\n \"_store\",\n \"render\",\n \"constructor\",\n ])\n\n /**\n * A FUNCTION wrapped in a Proxy, so the symbol throws however it is\n * reached: called as a hook or factory (`usePanGesture()`), rendered as a\n * component (React calls it), or read as a namespace (`Gesture.Pan()`,\n * `State.ACTIVE`).\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (name: string): any => {\n const fail = (): never => {\n throw new Error(\n `${packageName}: \\`${name}\\` is not supported on Linux ` +\n `(react-native-gtkx). ${explanation}`,\n )\n }\n\n return new Proxy(fail, {\n get: (target, key, receiver) =>\n typeof key === \"symbol\" || introspection.has(key)\n ? Reflect.get(target, key, receiver)\n : fail(),\n apply: fail,\n construct: fail,\n })\n }\n}\n"]}
@@ -1,4 +1,7 @@
1
1
  import type { Plugin } from "vite";
2
+ import { type AliasOverrides } from "../aliases/index.js";
3
+ export { CONFIGURABLE_ALIASES, DEFAULT_ALIASES, PLATFORM_ALIAS, } from "../aliases/index.js";
4
+ export type { AliasOverride, AliasOverrides, AliasPattern, AliasTable, CompiledAlias, } from "../aliases/index.js";
2
5
  /** Options shared by the preset factory and the pure resolver helpers. */
3
6
  export type PlatformResolutionOptions = {
4
7
  /** Platform suffix priority, most specific first. Default: ["linux", "native"]. */
@@ -11,13 +14,14 @@ export type FileExists = (filePath: string) => boolean;
11
14
  export declare const DEFAULT_PLATFORMS: readonly string[];
12
15
  export declare const DEFAULT_EXTENSIONS: readonly string[];
13
16
  /**
14
- * Maps `react-native` (and its subpaths) to `react-native-gtkx`, and
15
- * `react-native-svg` (and its subpaths) to the `react-native-gtkx/svg`
16
- * compat subpath (see src/svg-compat/index.ts) same rationale, same exact-
17
- * match-or-slash-prefix guard so a lookalike package name (`react-native-
18
- * svg-icons`, the same shape of trap `react-native-web` is for the plain
19
- * `react-native` case below) is never aliased by accident. Returns null for
20
- * every other specifier, including `react-native-gtkx` itself.
17
+ * Applies the DEFAULT alias table (../aliases/index.ts) to one specifier:
18
+ * `react-native` and its subpaths onto `react-native-gtkx`, and the five
19
+ * package substitutions onto their compat subpaths. Returns null for every
20
+ * other specifier, including `react-native-gtkx` itself.
21
+ *
22
+ * Exported for tests and for apps driving vite by hand. The plugin does NOT
23
+ * call it the plugin resolves through the table its own `aliases` option
24
+ * produced, so an app's deltas apply.
21
25
  */
22
26
  export declare const rewriteReactNativeImport: (source: string) => string | null;
23
27
  /** Splits a vite specifier into its path part and its `?query` suffix. */
@@ -48,7 +52,16 @@ export declare const platformCandidates: (base: string, options?: PlatformResolu
48
52
  * import back to the default resolver.
49
53
  */
50
54
  export declare const resolvePlatformSpecifier: (source: string, importer: string | undefined, exists: FileExists, options?: PlatformResolutionOptions) => string | null;
51
- export type ReactNativeGtkxOptions = PlatformResolutionOptions;
55
+ export type ReactNativeGtkxOptions = PlatformResolutionOptions & {
56
+ /**
57
+ * Deltas over the preset's package aliases, keyed by package name — a
58
+ * string target, a `{ pattern, replace }` rule, or `false` to drop one of
59
+ * ours so the real package loads. Identical semantics to the Metro
60
+ * preset's option of the same name: both compile the same table.
61
+ * Invalid entries throw here, while the config is being read.
62
+ */
63
+ aliases?: AliasOverrides;
64
+ };
52
65
  /**
53
66
  * Vite plugin: aliases `react-native` (and subpaths) to `react-native-gtkx`
54
67
  * and resolves Metro-style platform extensions
@@ -4,42 +4,30 @@
4
4
  // from the root and merges it beneath the CLI config; this preset plugs in
5
5
  // there as a single plugin.
6
6
  //
7
- // Single self-contained file on purpose: vite loads the config's imported
8
- // packages with BARE Node, so this subpath (like ./metro and ./runner) must
9
- // not contain extensionless relative imports the pure resolution helpers
10
- // live here rather than in a sibling module.
7
+ // vite loads the config's imported packages with BARE Node, so this subpath
8
+ // (like ./metro and ./runner) must not contain EXTENSIONLESS relative imports
9
+ // the pure resolution helpers live here rather than in a sibling module,
10
+ // and the one import that does cross a file boundary spells out its `.js`.
11
11
  import { existsSync } from "node:fs";
12
12
  import { dirname, extname, isAbsolute, resolve } from "node:path";
13
+ import { applyAliases, compileAliases, DEFAULT_ALIAS_TABLE, } from "../aliases/index.js";
14
+ // Re-exported so an app configuring `aliases` never has to reach past the
15
+ // preset subpath it already imports.
16
+ export { CONFIGURABLE_ALIASES, DEFAULT_ALIASES, PLATFORM_ALIAS, } from "../aliases/index.js";
13
17
  export const DEFAULT_PLATFORMS = ["linux", "native"];
14
18
  export const DEFAULT_EXTENSIONS = ["tsx", "ts", "jsx", "js"];
15
- const REACT_NATIVE = "react-native";
16
19
  const REACT_NATIVE_GTKX = "react-native-gtkx";
17
- const REACT_NATIVE_SVG = "react-native-svg";
18
- const REACT_NATIVE_GTKX_SVG = "react-native-gtkx/svg";
19
20
  /**
20
- * Maps `react-native` (and its subpaths) to `react-native-gtkx`, and
21
- * `react-native-svg` (and its subpaths) to the `react-native-gtkx/svg`
22
- * compat subpath (see src/svg-compat/index.ts) same rationale, same exact-
23
- * match-or-slash-prefix guard so a lookalike package name (`react-native-
24
- * svg-icons`, the same shape of trap `react-native-web` is for the plain
25
- * `react-native` case below) is never aliased by accident. Returns null for
26
- * every other specifier, including `react-native-gtkx` itself.
21
+ * Applies the DEFAULT alias table (../aliases/index.ts) to one specifier:
22
+ * `react-native` and its subpaths onto `react-native-gtkx`, and the five
23
+ * package substitutions onto their compat subpaths. Returns null for every
24
+ * other specifier, including `react-native-gtkx` itself.
25
+ *
26
+ * Exported for tests and for apps driving vite by hand. The plugin does NOT
27
+ * call it the plugin resolves through the table its own `aliases` option
28
+ * produced, so an app's deltas apply.
27
29
  */
28
- export const rewriteReactNativeImport = (source) => {
29
- if (source === REACT_NATIVE) {
30
- return REACT_NATIVE_GTKX;
31
- }
32
- if (source.startsWith(`${REACT_NATIVE}/`)) {
33
- return `${REACT_NATIVE_GTKX}${source.slice(REACT_NATIVE.length)}`;
34
- }
35
- if (source === REACT_NATIVE_SVG) {
36
- return REACT_NATIVE_GTKX_SVG;
37
- }
38
- if (source.startsWith(`${REACT_NATIVE_SVG}/`)) {
39
- return `${REACT_NATIVE_GTKX_SVG}${source.slice(REACT_NATIVE_SVG.length)}`;
40
- }
41
- return null;
42
- };
30
+ export const rewriteReactNativeImport = (source) => applyAliases(DEFAULT_ALIAS_TABLE, source);
43
31
  /** Splits a vite specifier into its path part and its `?query` suffix. */
44
32
  export const splitQuery = (source) => {
45
33
  const index = source.indexOf("?");
@@ -115,60 +103,117 @@ export const resolvePlatformSpecifier = (source, importer, exists, options = {})
115
103
  * and resolves Metro-style platform extensions
116
104
  * (`.linux.tsx` → `.native.tsx` → base) for extensionless imports.
117
105
  */
118
- export const reactNativeGtkx = (options = {}) => ({
119
- name: "react-native-gtkx:preset",
120
- // Before vite's own resolver and the gtkx CLI plugins: the alias must win
121
- // over node resolution and platform files must win over the base file.
122
- enforce: "pre",
123
- config: () => ({
124
- ssr: {
125
- // `gtkx dev` runs vite with ssr.external: true, which would hand
126
- // react-native-gtkx straight to node. Keep the package inside the
127
- // vite pipeline; noExternal wins over external: true.
106
+ export const reactNativeGtkx = (options = {}) => {
107
+ // Throws on an unknown key, an overlapping pattern or an attempt to remove
108
+ // the platform alias at config load, naming what is valid.
109
+ const aliases = compileAliases(options.aliases);
110
+ return {
111
+ name: "react-native-gtkx:preset",
112
+ // Before vite's own resolver and the gtkx CLI plugins: the alias must win
113
+ // over node resolution and platform files must win over the base file.
114
+ enforce: "pre",
115
+ config: (_config, env) => ({
116
+ // `__DEV__` is part of the react-native runtime contract, not a Metro
117
+ // detail: RN's own modules branch on it and so does every library
118
+ // written against them (`@gorhom/bottom-sheet`'s logger and four of its
119
+ // components read it at module scope). The Metro path gets it from the
120
+ // app's stock RN preset; nothing supplied it on the vite path, so a
121
+ // library that reads it crashed the bundle at startup with
122
+ // "ReferenceError: __DEV__ is not defined" — found by building
123
+ // spike/core-exports rather than by reading anything.
128
124
  //
129
- // "react-native" must be listed too: with ssr.external: true vite
130
- // externalizes a bare import BEFORE the plugin pipeline whenever the
131
- // package resolves natively — and the real react-native (a Flow
132
- // codebase Node cannot parse) exists in RN monorepos. noExternal
133
- // forces the full plugin resolution, where the alias rewrites the
134
- // import to react-native-gtkx.
135
- // @react-navigation must go through the pipeline too: it imports
136
- // "react-native", and an externalized copy resolves that to the real
137
- // Flow package (SyntaxError: Unexpected token 'typeof') instead of
138
- // our alias. Only bites on the dev path — a production build inlines
139
- // everything anyway.
140
- noExternal: ["react-native-gtkx", "react-native", /^@react-navigation\//],
141
- },
142
- resolve: {
143
- // RC3-WORKAROUND(runtime-dedupe): see docs/gtkx-rc3-notes.md
144
- // The gtkx runtime and react are single-instance hosts: when the app
145
- // and react-native-gtkx resolve them from different node_modules
146
- // (file:-installed package, nested installs), two bundled copies
147
- // double-init the runtime and GLib aborts. dedupe pins every copy to
148
- // the project's own resolution.
149
- dedupe: [
150
- "@gtkx/css",
151
- "@gtkx/gi",
152
- "@gtkx/jsx",
153
- "@gtkx/native",
154
- "@gtkx/react",
155
- "@gtkx/runtime",
156
- // react-navigation is context-based: two bundled copies of core
157
- // fail with "couldn't find a navigation context".
158
- "@react-navigation/core",
159
- "@react-navigation/native",
160
- "react",
161
- ],
125
+ // vite's mode is the honest source: `gtkx dev` builds in development,
126
+ // `gtkx build` in production, which is exactly the distinction RN draws.
127
+ define: {
128
+ __DEV__: JSON.stringify(env.mode !== "production"),
129
+ },
130
+ ssr: {
131
+ // `gtkx dev` runs vite with ssr.external: true, which would hand
132
+ // react-native-gtkx straight to node. Keep the package inside the
133
+ // vite pipeline; noExternal wins over external: true.
134
+ //
135
+ // "react-native" must be listed too: with ssr.external: true vite
136
+ // externalizes a bare import BEFORE the plugin pipeline whenever the
137
+ // package resolves natively — and the real react-native (a Flow
138
+ // codebase Node cannot parse) exists in RN monorepos. noExternal
139
+ // forces the full plugin resolution, where the alias rewrites the
140
+ // import to react-native-gtkx.
141
+ // "react-native-reanimated" for the same reason as "react-native": an
142
+ // app that also ships iOS/Android keeps the real package installed, it
143
+ // resolves natively, and ssr.external: true would hand Node a codebase
144
+ // built around a Babel plugin and a worklet runtime before the alias
145
+ // ever gets a chance to rewrite the import.
146
+ // "react-native-worklets" is the same case one package over — it is
147
+ // where that worklet runtime actually lives since Reanimated 4.
148
+ //
149
+ // The rule those are instances of, stated once so the next alias does
150
+ // not have to rediscover it: EVERY package name in the alias table must
151
+ // be listed here. An alias is a resolveId hook, and a bare specifier
152
+ // that vite externalizes never reaches one so on the dev path the
153
+ // alias silently loses to whatever is installed under the real name.
154
+ // That is not hypothetical: an app that also ships iOS and Android has
155
+ // all of them in node_modules, which is the case the alias exists to
156
+ // serve. `react-native-gesture-handler` proved it — this list once held
157
+ // three of the six names, its real package loaded, and it failed on an
158
+ // extensionless internal import Node cannot resolve (found by running
159
+ // the gallery's upstream-libraries section, which installs it).
160
+ //
161
+ // So the list is DERIVED rather than written out: it is exactly the
162
+ // table's package names, and a name can no longer go missing from one
163
+ // of the two places it has to appear.
164
+ //
165
+ // `aliases.names` includes the packages an app turned OFF with `false`,
166
+ // deliberately. Dropping an alias means the REAL package loads, and the
167
+ // real package imports `react-native` at module scope — an import that
168
+ // only reaches the platform alias if Node never gets the package first.
169
+ // Un-aliasing a package is therefore a reason to keep it inside the
170
+ // pipeline, not a reason to let it out.
171
+ noExternal: [
172
+ REACT_NATIVE_GTKX,
173
+ ...aliases.names,
174
+ // @react-navigation is not aliased, but must go through the pipeline
175
+ // too: it imports `react-native`, and an externalized copy resolves
176
+ // that to the real Flow package (SyntaxError: Unexpected token
177
+ // 'typeof') instead of our alias. Only bites on the dev path — a
178
+ // production build inlines everything anyway.
179
+ /^@react-navigation\//,
180
+ ],
181
+ },
182
+ resolve: {
183
+ // RC4-WORKAROUND(runtime-dedupe): see docs/gtkx-rc4-notes.md
184
+ // The gtkx runtime and react are single-instance hosts: when the app
185
+ // and react-native-gtkx resolve them from different node_modules
186
+ // (file:-installed package, nested installs), two bundled copies
187
+ // double-init the runtime and GLib aborts. dedupe pins every copy to
188
+ // the project's own resolution.
189
+ dedupe: [
190
+ "@gtkx/css",
191
+ "@gtkx/gi",
192
+ "@gtkx/jsx",
193
+ "@gtkx/native",
194
+ "@gtkx/react",
195
+ "@gtkx/runtime",
196
+ // react-navigation is context-based: two bundled copies of core
197
+ // fail with "couldn't find a navigation context".
198
+ "@react-navigation/core",
199
+ "@react-navigation/native",
200
+ "react",
201
+ ],
202
+ },
203
+ }),
204
+ async resolveId(source, importer) {
205
+ // The app's table, not the default one: a package dropped with `false`
206
+ // falls through to vite's own resolution and the real package loads.
207
+ const aliased = applyAliases(aliases, source);
208
+ if (aliased !== null) {
209
+ const resolved = await this.resolve(aliased, importer, {
210
+ skipSelf: true,
211
+ });
212
+ return resolved ?? aliased;
213
+ }
214
+ return resolvePlatformSpecifier(source, importer, existsSync, options);
162
215
  },
163
- }),
164
- async resolveId(source, importer) {
165
- const aliased = rewriteReactNativeImport(source);
166
- if (aliased !== null) {
167
- const resolved = await this.resolve(aliased, importer, { skipSelf: true });
168
- return resolved ?? aliased;
169
- }
170
- return resolvePlatformSpecifier(source, importer, existsSync, options);
171
- },
172
- });
216
+ };
217
+ };
173
218
  export default reactNativeGtkx;
174
219
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,4BAA4B;AAC5B,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,2EAA2E;AAC3E,6CAA6C;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgBjE,MAAM,CAAC,MAAM,iBAAiB,GAAsB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AAE/E,MAAM,YAAY,GAAG,cAAc,CAAA;AACnC,MAAM,iBAAiB,GAAG,mBAAmB,CAAA;AAC7C,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAC3C,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAErD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,MAAc,EAAiB,EAAE;IACxE,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,GAAG,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAA;IACnE,CAAC;IACD,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChC,OAAO,qBAAqB,CAAA;IAC9B,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,gBAAgB,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,GAAG,qBAAqB,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAA;IAC3E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,MAAc,EACwB,EAAE;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QACjB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;IACzC,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAA;AAC1E,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAW,EAAE,CAChD,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,UAAqC,EAAE,EAC7B,EAAE;IACZ,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,kBAAkB,CAAA;IAC3D,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC,CAC3D,CAAA;AACH,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,IAAY,EACZ,UAAqC,EAAE,EAC7B,EAAE;IACZ,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC1C,OAAO;QACL,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC;QAC/C,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,SAAS,MAAM,EAAE,CAAC;KACtD,CAAA;AACH,CAAC,CAAA;AAED,qEAAqE;AACrE,0EAA0E;AAC1E,qEAAqE;AACrE,0EAA0E;AAC1E,qCAAqC;AACrC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAE7E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,MAAc,EACd,QAA4B,EAC5B,MAAkB,EAClB,UAAqC,EAAE,EACxB,EAAE;IACjB,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IACpC,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC;QACzC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAA;IAC/D,MAAM,IAAI,GACR,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAC9E,KAAK,MAAM,SAAS,IAAI,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QAC1D,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,GAAG,KAAK,CAAA;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAMD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,UAAkC,EAAE,EAC5B,EAAE,CAAC,CAAC;IACZ,IAAI,EAAE,0BAA0B;IAChC,0EAA0E;IAC1E,uEAAuE;IACvE,OAAO,EAAE,KAAK;IAEd,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACb,GAAG,EAAE;YACH,iEAAiE;YACjE,kEAAkE;YAClE,sDAAsD;YACtD,EAAE;YACF,kEAAkE;YAClE,qEAAqE;YACrE,gEAAgE;YAChE,iEAAiE;YACjE,kEAAkE;YAClE,+BAA+B;YAC/B,iEAAiE;YACjE,qEAAqE;YACrE,mEAAmE;YACnE,qEAAqE;YACrE,qBAAqB;YACrB,UAAU,EAAE,CAAC,mBAAmB,EAAE,cAAc,EAAE,sBAAsB,CAAC;SAC1E;QACD,OAAO,EAAE;YACP,6DAA6D;YAC7D,qEAAqE;YACrE,iEAAiE;YACjE,iEAAiE;YACjE,qEAAqE;YACrE,gCAAgC;YAChC,MAAM,EAAE;gBACN,WAAW;gBACX,UAAU;gBACV,WAAW;gBACX,cAAc;gBACd,aAAa;gBACb,eAAe;gBACf,gEAAgE;gBAChE,kDAAkD;gBAClD,wBAAwB;gBACxB,0BAA0B;gBAC1B,OAAO;aACR;SACF;KACF,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ;QAC9B,MAAM,OAAO,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAA;QAChD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;YAC1E,OAAO,QAAQ,IAAI,OAAO,CAAA;QAC5B,CAAC;QACD,OAAO,wBAAwB,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACxE,CAAC;CACF,CAAC,CAAA;AAEF,eAAe,eAAe,CAAA","sourcesContent":["// react-native-gtkx/vite — makes a gtkx project React Native compatible.\n// The gtkx CLI (dev and build) starts vite with an inline config that never\n// sets `configFile: false`, so vite picks up the project's vite.config.ts\n// from the root and merges it beneath the CLI config; this preset plugs in\n// there as a single plugin.\n//\n// Single self-contained file on purpose: vite loads the config's imported\n// packages with BARE Node, so this subpath (like ./metro and ./runner) must\n// not contain extensionless relative imports — the pure resolution helpers\n// live here rather than in a sibling module.\nimport { existsSync } from \"node:fs\"\nimport { dirname, extname, isAbsolute, resolve } from \"node:path\"\nimport type { Plugin } from \"vite\"\n\n// --- pure resolution logic (unit-tested directly) -----------------------\n\n/** Options shared by the preset factory and the pure resolver helpers. */\nexport type PlatformResolutionOptions = {\n /** Platform suffix priority, most specific first. Default: [\"linux\", \"native\"]. */\n platforms?: readonly string[]\n /** Source extensions tried for every platform suffix. Default: [\"tsx\", \"ts\", \"jsx\", \"js\"]. */\n extensions?: readonly string[]\n}\n\n/** Predicate the plugin injects as fs.existsSync; tests inject fakes. */\nexport type FileExists = (filePath: string) => boolean\n\nexport const DEFAULT_PLATFORMS: readonly string[] = [\"linux\", \"native\"]\nexport const DEFAULT_EXTENSIONS: readonly string[] = [\"tsx\", \"ts\", \"jsx\", \"js\"]\n\nconst REACT_NATIVE = \"react-native\"\nconst REACT_NATIVE_GTKX = \"react-native-gtkx\"\nconst REACT_NATIVE_SVG = \"react-native-svg\"\nconst REACT_NATIVE_GTKX_SVG = \"react-native-gtkx/svg\"\n\n/**\n * Maps `react-native` (and its subpaths) to `react-native-gtkx`, and\n * `react-native-svg` (and its subpaths) to the `react-native-gtkx/svg`\n * compat subpath (see src/svg-compat/index.ts) — same rationale, same exact-\n * match-or-slash-prefix guard so a lookalike package name (`react-native-\n * svg-icons`, the same shape of trap `react-native-web` is for the plain\n * `react-native` case below) is never aliased by accident. Returns null for\n * every other specifier, including `react-native-gtkx` itself.\n */\nexport const rewriteReactNativeImport = (source: string): string | null => {\n if (source === REACT_NATIVE) {\n return REACT_NATIVE_GTKX\n }\n if (source.startsWith(`${REACT_NATIVE}/`)) {\n return `${REACT_NATIVE_GTKX}${source.slice(REACT_NATIVE.length)}`\n }\n if (source === REACT_NATIVE_SVG) {\n return REACT_NATIVE_GTKX_SVG\n }\n if (source.startsWith(`${REACT_NATIVE_SVG}/`)) {\n return `${REACT_NATIVE_GTKX_SVG}${source.slice(REACT_NATIVE_SVG.length)}`\n }\n return null\n}\n\n/** Splits a vite specifier into its path part and its `?query` suffix. */\nexport const splitQuery = (\n source: string,\n): { specifier: string; query: string } => {\n const index = source.indexOf(\"?\")\n if (index === -1) {\n return { specifier: source, query: \"\" }\n }\n return { specifier: source.slice(0, index), query: source.slice(index) }\n}\n\nconst isRelative = (specifier: string): boolean =>\n specifier.startsWith(\"./\") || specifier.startsWith(\"../\")\n\n/**\n * Ordered platform suffixes, platform-major: every extension of the first\n * platform is tried before any extension of the next one\n * (`.linux.tsx`, `.linux.ts`, …, `.native.tsx`, …).\n */\nexport const platformSuffixes = (\n options: PlatformResolutionOptions = {},\n): string[] => {\n const platforms = options.platforms ?? DEFAULT_PLATFORMS\n const extensions = options.extensions ?? DEFAULT_EXTENSIONS\n return platforms.flatMap((platform) =>\n extensions.map((extension) => `.${platform}.${extension}`),\n )\n}\n\n/**\n * Candidate file paths for an extensionless base path, in priority order:\n * direct platform files first, then platform index files of a directory —\n * mirroring Metro, which exhausts file resolution before directory resolution.\n * The base file itself is not a candidate: when no platform file exists the\n * plugin bails out and the default resolver picks the base module.\n */\nexport const platformCandidates = (\n base: string,\n options: PlatformResolutionOptions = {},\n): string[] => {\n const suffixes = platformSuffixes(options)\n return [\n ...suffixes.map((suffix) => `${base}${suffix}`),\n ...suffixes.map((suffix) => `${base}/index${suffix}`),\n ]\n}\n\n// Source extensions Metro strips before trying platform variants: an\n// import of \"./useLinking.js\" (the TS-ESM style react-navigation and most\n// compiled RN libraries use) must still find useLinking.native.tsx /\n// useLinking.native.js — Metro resolves the BASE name platform-first, the\n// literal file is only the fallback.\nconst STRIPPABLE_EXTENSIONS = new Set([\".js\", \".jsx\", \".mjs\", \".ts\", \".tsx\"])\n\n/**\n * Metro platform-extension resolution for a single import: relative (or\n * absolute) specifiers that are extensionless — or carry a strippable\n * source extension — try platform candidates first; the first existing\n * candidate wins; the `?query` suffix is carried over. Returns null when\n * the import is out of scope or no platform file exists, handing the\n * import back to the default resolver.\n */\nexport const resolvePlatformSpecifier = (\n source: string,\n importer: string | undefined,\n exists: FileExists,\n options: PlatformResolutionOptions = {},\n): string | null => {\n if (importer === undefined || source.startsWith(\"\\0\")) {\n return null\n }\n const { specifier, query } = splitQuery(source)\n if (!isRelative(specifier) && !isAbsolute(specifier)) {\n return null\n }\n const extension = extname(specifier)\n if (extension !== \"\" && !STRIPPABLE_EXTENSIONS.has(extension)) {\n return null\n }\n const withExtension = isAbsolute(specifier)\n ? specifier\n : resolve(dirname(splitQuery(importer).specifier), specifier)\n const base =\n extension === \"\" ? withExtension : withExtension.slice(0, -extension.length)\n for (const candidate of platformCandidates(base, options)) {\n if (exists(candidate)) {\n return candidate + query\n }\n }\n return null\n}\n\n// --- the vite plugin ----------------------------------------------------\n\nexport type ReactNativeGtkxOptions = PlatformResolutionOptions\n\n/**\n * Vite plugin: aliases `react-native` (and subpaths) to `react-native-gtkx`\n * and resolves Metro-style platform extensions\n * (`.linux.tsx` → `.native.tsx` → base) for extensionless imports.\n */\nexport const reactNativeGtkx = (\n options: ReactNativeGtkxOptions = {},\n): Plugin => ({\n name: \"react-native-gtkx:preset\",\n // Before vite's own resolver and the gtkx CLI plugins: the alias must win\n // over node resolution and platform files must win over the base file.\n enforce: \"pre\",\n\n config: () => ({\n ssr: {\n // `gtkx dev` runs vite with ssr.external: true, which would hand\n // react-native-gtkx straight to node. Keep the package inside the\n // vite pipeline; noExternal wins over external: true.\n //\n // \"react-native\" must be listed too: with ssr.external: true vite\n // externalizes a bare import BEFORE the plugin pipeline whenever the\n // package resolves natively — and the real react-native (a Flow\n // codebase Node cannot parse) exists in RN monorepos. noExternal\n // forces the full plugin resolution, where the alias rewrites the\n // import to react-native-gtkx.\n // @react-navigation must go through the pipeline too: it imports\n // \"react-native\", and an externalized copy resolves that to the real\n // Flow package (SyntaxError: Unexpected token 'typeof') instead of\n // our alias. Only bites on the dev path — a production build inlines\n // everything anyway.\n noExternal: [\"react-native-gtkx\", \"react-native\", /^@react-navigation\\//],\n },\n resolve: {\n // RC3-WORKAROUND(runtime-dedupe): see docs/gtkx-rc3-notes.md\n // The gtkx runtime and react are single-instance hosts: when the app\n // and react-native-gtkx resolve them from different node_modules\n // (file:-installed package, nested installs), two bundled copies\n // double-init the runtime and GLib aborts. dedupe pins every copy to\n // the project's own resolution.\n dedupe: [\n \"@gtkx/css\",\n \"@gtkx/gi\",\n \"@gtkx/jsx\",\n \"@gtkx/native\",\n \"@gtkx/react\",\n \"@gtkx/runtime\",\n // react-navigation is context-based: two bundled copies of core\n // fail with \"couldn't find a navigation context\".\n \"@react-navigation/core\",\n \"@react-navigation/native\",\n \"react\",\n ],\n },\n }),\n\n async resolveId(source, importer) {\n const aliased = rewriteReactNativeImport(source)\n if (aliased !== null) {\n const resolved = await this.resolve(aliased, importer, { skipSelf: true })\n return resolved ?? aliased\n }\n return resolvePlatformSpecifier(source, importer, existsSync, options)\n },\n})\n\nexport default reactNativeGtkx\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"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","sourcesContent":["// react-native-gtkx/vite — makes a gtkx project React Native compatible.\n// The gtkx CLI (dev and build) starts vite with an inline config that never\n// sets `configFile: false`, so vite picks up the project's vite.config.ts\n// from the root and merges it beneath the CLI config; this preset plugs in\n// there as a single plugin.\n//\n// vite loads the config's imported packages with BARE Node, so this subpath\n// (like ./metro and ./runner) must not contain EXTENSIONLESS relative imports\n// — the pure resolution helpers live here rather than in a sibling module,\n// and the one import that does cross a file boundary spells out its `.js`.\nimport { existsSync } from \"node:fs\"\nimport { dirname, extname, isAbsolute, resolve } from \"node:path\"\nimport type { Plugin } from \"vite\"\nimport {\n applyAliases,\n compileAliases,\n DEFAULT_ALIAS_TABLE,\n type AliasOverrides,\n} from \"../aliases/index.js\"\n\n// Re-exported so an app configuring `aliases` never has to reach past the\n// preset subpath it already imports.\nexport {\n CONFIGURABLE_ALIASES,\n DEFAULT_ALIASES,\n PLATFORM_ALIAS,\n} from \"../aliases/index.js\"\nexport type {\n AliasOverride,\n AliasOverrides,\n AliasPattern,\n AliasTable,\n CompiledAlias,\n} from \"../aliases/index.js\"\n\n// --- pure resolution logic (unit-tested directly) -----------------------\n\n/** Options shared by the preset factory and the pure resolver helpers. */\nexport type PlatformResolutionOptions = {\n /** Platform suffix priority, most specific first. Default: [\"linux\", \"native\"]. */\n platforms?: readonly string[]\n /** Source extensions tried for every platform suffix. Default: [\"tsx\", \"ts\", \"jsx\", \"js\"]. */\n extensions?: readonly string[]\n}\n\n/** Predicate the plugin injects as fs.existsSync; tests inject fakes. */\nexport type FileExists = (filePath: string) => boolean\n\nexport const DEFAULT_PLATFORMS: readonly string[] = [\"linux\", \"native\"]\nexport const DEFAULT_EXTENSIONS: readonly string[] = [\"tsx\", \"ts\", \"jsx\", \"js\"]\n\nconst REACT_NATIVE_GTKX = \"react-native-gtkx\"\n\n/**\n * Applies the DEFAULT alias table (../aliases/index.ts) to one specifier:\n * `react-native` and its subpaths onto `react-native-gtkx`, and the five\n * package substitutions onto their compat subpaths. Returns null for every\n * other specifier, including `react-native-gtkx` itself.\n *\n * Exported for tests and for apps driving vite by hand. The plugin does NOT\n * call it — the plugin resolves through the table its own `aliases` option\n * produced, so an app's deltas apply.\n */\nexport const rewriteReactNativeImport = (source: string): string | null =>\n applyAliases(DEFAULT_ALIAS_TABLE, source)\n\n/** Splits a vite specifier into its path part and its `?query` suffix. */\nexport const splitQuery = (\n source: string,\n): { specifier: string; query: string } => {\n const index = source.indexOf(\"?\")\n if (index === -1) {\n return { specifier: source, query: \"\" }\n }\n return { specifier: source.slice(0, index), query: source.slice(index) }\n}\n\nconst isRelative = (specifier: string): boolean =>\n specifier.startsWith(\"./\") || specifier.startsWith(\"../\")\n\n/**\n * Ordered platform suffixes, platform-major: every extension of the first\n * platform is tried before any extension of the next one\n * (`.linux.tsx`, `.linux.ts`, …, `.native.tsx`, …).\n */\nexport const platformSuffixes = (\n options: PlatformResolutionOptions = {},\n): string[] => {\n const platforms = options.platforms ?? DEFAULT_PLATFORMS\n const extensions = options.extensions ?? DEFAULT_EXTENSIONS\n return platforms.flatMap((platform) =>\n extensions.map((extension) => `.${platform}.${extension}`),\n )\n}\n\n/**\n * Candidate file paths for an extensionless base path, in priority order:\n * direct platform files first, then platform index files of a directory —\n * mirroring Metro, which exhausts file resolution before directory resolution.\n * The base file itself is not a candidate: when no platform file exists the\n * plugin bails out and the default resolver picks the base module.\n */\nexport const platformCandidates = (\n base: string,\n options: PlatformResolutionOptions = {},\n): string[] => {\n const suffixes = platformSuffixes(options)\n return [\n ...suffixes.map((suffix) => `${base}${suffix}`),\n ...suffixes.map((suffix) => `${base}/index${suffix}`),\n ]\n}\n\n// Source extensions Metro strips before trying platform variants: an\n// import of \"./useLinking.js\" (the TS-ESM style react-navigation and most\n// compiled RN libraries use) must still find useLinking.native.tsx /\n// useLinking.native.js — Metro resolves the BASE name platform-first, the\n// literal file is only the fallback.\nconst STRIPPABLE_EXTENSIONS = new Set([\".js\", \".jsx\", \".mjs\", \".ts\", \".tsx\"])\n\n/**\n * Metro platform-extension resolution for a single import: relative (or\n * absolute) specifiers that are extensionless — or carry a strippable\n * source extension — try platform candidates first; the first existing\n * candidate wins; the `?query` suffix is carried over. Returns null when\n * the import is out of scope or no platform file exists, handing the\n * import back to the default resolver.\n */\nexport const resolvePlatformSpecifier = (\n source: string,\n importer: string | undefined,\n exists: FileExists,\n options: PlatformResolutionOptions = {},\n): string | null => {\n if (importer === undefined || source.startsWith(\"\\0\")) {\n return null\n }\n const { specifier, query } = splitQuery(source)\n if (!isRelative(specifier) && !isAbsolute(specifier)) {\n return null\n }\n const extension = extname(specifier)\n if (extension !== \"\" && !STRIPPABLE_EXTENSIONS.has(extension)) {\n return null\n }\n const withExtension = isAbsolute(specifier)\n ? specifier\n : resolve(dirname(splitQuery(importer).specifier), specifier)\n const base =\n extension === \"\" ? withExtension : withExtension.slice(0, -extension.length)\n for (const candidate of platformCandidates(base, options)) {\n if (exists(candidate)) {\n return candidate + query\n }\n }\n return null\n}\n\n// --- the vite plugin ----------------------------------------------------\n\nexport type ReactNativeGtkxOptions = PlatformResolutionOptions & {\n /**\n * Deltas over the preset's package aliases, keyed by package name — a\n * string target, a `{ pattern, replace }` rule, or `false` to drop one of\n * ours so the real package loads. Identical semantics to the Metro\n * preset's option of the same name: both compile the same table.\n * Invalid entries throw here, while the config is being read.\n */\n aliases?: AliasOverrides\n}\n\n/**\n * Vite plugin: aliases `react-native` (and subpaths) to `react-native-gtkx`\n * and resolves Metro-style platform extensions\n * (`.linux.tsx` → `.native.tsx` → base) for extensionless imports.\n */\nexport const reactNativeGtkx = (\n options: ReactNativeGtkxOptions = {},\n): Plugin => {\n // Throws on an unknown key, an overlapping pattern or an attempt to remove\n // the platform alias — at config load, naming what is valid.\n const aliases = compileAliases(options.aliases)\n return {\n name: \"react-native-gtkx:preset\",\n // Before vite's own resolver and the gtkx CLI plugins: the alias must win\n // over node resolution and platform files must win over the base file.\n enforce: \"pre\",\n\n config: (_config, env) => ({\n // `__DEV__` is part of the react-native runtime contract, not a Metro\n // detail: RN's own modules branch on it and so does every library\n // written against them (`@gorhom/bottom-sheet`'s logger and four of its\n // components read it at module scope). The Metro path gets it from the\n // app's stock RN preset; nothing supplied it on the vite path, so a\n // library that reads it crashed the bundle at startup with\n // \"ReferenceError: __DEV__ is not defined\" — found by building\n // spike/core-exports rather than by reading anything.\n //\n // vite's mode is the honest source: `gtkx dev` builds in development,\n // `gtkx build` in production, which is exactly the distinction RN draws.\n define: {\n __DEV__: JSON.stringify(env.mode !== \"production\"),\n },\n ssr: {\n // `gtkx dev` runs vite with ssr.external: true, which would hand\n // react-native-gtkx straight to node. Keep the package inside the\n // vite pipeline; noExternal wins over external: true.\n //\n // \"react-native\" must be listed too: with ssr.external: true vite\n // externalizes a bare import BEFORE the plugin pipeline whenever the\n // package resolves natively — and the real react-native (a Flow\n // codebase Node cannot parse) exists in RN monorepos. noExternal\n // forces the full plugin resolution, where the alias rewrites the\n // import to react-native-gtkx.\n // \"react-native-reanimated\" for the same reason as \"react-native\": an\n // app that also ships iOS/Android keeps the real package installed, it\n // resolves natively, and ssr.external: true would hand Node a codebase\n // built around a Babel plugin and a worklet runtime before the alias\n // ever gets a chance to rewrite the import.\n // \"react-native-worklets\" is the same case one package over — it is\n // where that worklet runtime actually lives since Reanimated 4.\n //\n // The rule those are instances of, stated once so the next alias does\n // not have to rediscover it: EVERY package name in the alias table must\n // be listed here. An alias is a resolveId hook, and a bare specifier\n // that vite externalizes never reaches one — so on the dev path the\n // alias silently loses to whatever is installed under the real name.\n // That is not hypothetical: an app that also ships iOS and Android has\n // all of them in node_modules, which is the case the alias exists to\n // serve. `react-native-gesture-handler` proved it — this list once held\n // three of the six names, its real package loaded, and it failed on an\n // extensionless internal import Node cannot resolve (found by running\n // the gallery's upstream-libraries section, which installs it).\n //\n // So the list is DERIVED rather than written out: it is exactly the\n // table's package names, and a name can no longer go missing from one\n // of the two places it has to appear.\n //\n // `aliases.names` includes the packages an app turned OFF with `false`,\n // deliberately. Dropping an alias means the REAL package loads, and the\n // real package imports `react-native` at module scope — an import that\n // only reaches the platform alias if Node never gets the package first.\n // Un-aliasing a package is therefore a reason to keep it inside the\n // pipeline, not a reason to let it out.\n noExternal: [\n REACT_NATIVE_GTKX,\n ...aliases.names,\n // @react-navigation is not aliased, but must go through the pipeline\n // too: it imports `react-native`, and an externalized copy resolves\n // that to the real Flow package (SyntaxError: Unexpected token\n // 'typeof') instead of our alias. Only bites on the dev path — a\n // production build inlines everything anyway.\n /^@react-navigation\\//,\n ],\n },\n resolve: {\n // RC4-WORKAROUND(runtime-dedupe): see docs/gtkx-rc4-notes.md\n // The gtkx runtime and react are single-instance hosts: when the app\n // and react-native-gtkx resolve them from different node_modules\n // (file:-installed package, nested installs), two bundled copies\n // double-init the runtime and GLib aborts. dedupe pins every copy to\n // the project's own resolution.\n dedupe: [\n \"@gtkx/css\",\n \"@gtkx/gi\",\n \"@gtkx/jsx\",\n \"@gtkx/native\",\n \"@gtkx/react\",\n \"@gtkx/runtime\",\n // react-navigation is context-based: two bundled copies of core\n // fail with \"couldn't find a navigation context\".\n \"@react-navigation/core\",\n \"@react-navigation/native\",\n \"react\",\n ],\n },\n }),\n\n async resolveId(source, importer) {\n // The app's table, not the default one: a package dropped with `false`\n // falls through to vite's own resolution and the real package loads.\n const aliased = applyAliases(aliases, source)\n if (aliased !== null) {\n const resolved = await this.resolve(aliased, importer, {\n skipSelf: true,\n })\n return resolved ?? aliased\n }\n return resolvePlatformSpecifier(source, importer, existsSync, options)\n },\n }\n}\n\nexport default reactNativeGtkx\n"]}
@@ -1,4 +1,4 @@
1
- import type { GtkxPluginOptions } from "@gtkx/vitest";
1
+ import type { PluginOptions as GtkxPluginOptions } from "@gtkx/vitest";
2
2
  import type { UserWorkspaceConfig } from "vitest/config";
3
3
  import { type ReactNativeGtkxOptions } from "../vite/index.js";
4
4
  /**
@@ -26,7 +26,7 @@ export type ReactNativeGtkxTestOptions = {
26
26
  /**
27
27
  * Run this project's test files serially. Default: false — window-resize
28
28
  * signal delivery races when several per-worker headless compositors run
29
- * at once (see docs/gtkx-rc3-notes.md); the suite this recipe is proven
29
+ * at once (see docs/gtkx-rc4-notes.md); the suite this recipe is proven
30
30
  * on takes seconds, so serial execution is the cheap fix. Override once a
31
31
  * suite is large enough for parallelism to matter more than that race.
32
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vitest/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,mDAAmD;AACnD,EAAE;AACF,iEAAiE;AACjE,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAC5E,qEAAqE;AACrE,0EAA0E;AAC1E,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAI7C,OAAO,EAAE,eAAe,EAA+B,MAAM,kBAAkB,CAAA;AAkC/E,MAAM,eAAe,GAAG,CAAC,wBAAwB,CAAC,CAAA;AAClD,MAAM,mBAAmB,GAAwB,CAAC,mBAAmB,CAAC,CAAA;AACtE,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAExE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,UAAsC,EAAE,EACV,EAAE;IAChC,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAA;IACnD,MAAM,OAAO,GAAa;QACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC;KAClC,CAAA;IACD,OAAO;QACL,OAAO;QACP,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;YAC3B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,eAAe;YAC3C,UAAU,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;YACvD,MAAM,EAAE;gBACN,IAAI,EAAE;oBACJ,MAAM,EAAE,CAAC,GAAG,mBAAmB,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;iBAChE;aACF;YACD,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,KAAK;SAClD;KACF,CAAA;AACH,CAAC,CAAA;AAED,eAAe,mBAAmB,CAAA","sourcesContent":["// react-native-gtkx/vitest — the vitest recipe this repo's own test suite\n// runs on (see vitest.config.ts's \"gtk\" project), packaged for a consumer\n// app: the @gtkx/vitest headless-compositor plugin, the react-native-gtkx\n// vite preset (react-native alias + Metro-style platform extensions), a\n// default inline-deps list for RN libraries that import \"react-native\"\n// themselves, and the React act-environment setup.\n//\n// Self-contained like ./vite, ./metro and ./runner: a consumer's\n// vitest.config.ts is loaded the same way vite.config.ts is (vite's config\n// loader bundles only the user's own relative import graph; node_modules\n// imports stay bare specifiers, resolved afterwards by plain Node ESM) — so\n// this file must not contain extensionless relative imports. The one\n// relative import below carries an explicit \".js\" extension, which a real\n// sibling file on disk resolves under plain Node without any bundler.\nimport { fileURLToPath, URL } from \"node:url\"\nimport type { GtkxPluginOptions } from \"@gtkx/vitest\"\nimport type { Plugin } from \"vite\"\nimport type { UserWorkspaceConfig } from \"vitest/config\"\nimport { reactNativeGtkx, type ReactNativeGtkxOptions } from \"../vite/index.js\"\n\n/**\n * Options accepted by {@link reactNativeGtkxTest}. Every field is optional\n * and falls back to the recipe this repo's own test suite runs on.\n */\nexport type ReactNativeGtkxTestOptions = {\n /** Vitest project name. Default: \"gtk\". */\n name?: string\n /** Test file glob(s), relative to the project root. Default: `[\"**\\/*.gtk.test.{ts,tsx}\"]`. */\n include?: string[]\n /** Headless compositor size/compositor, forwarded to @gtkx/vitest's plugin. */\n headless?: GtkxPluginOptions\n /** Metro-style platform resolution options, forwarded to the vite preset. */\n platform?: ReactNativeGtkxOptions\n /**\n * Extra `server.deps.inline` patterns, merged after the default\n * (`/@react-navigation/`). Needed for any node_modules library that\n * itself imports \"react-native\" — Vitest externalizes node_modules code\n * by default, a path the react-native alias cannot reach.\n */\n inlineDeps?: (string | RegExp)[]\n /** Extra setup files, run after the built-in React act-environment setup. */\n setupFiles?: string[]\n /**\n * Run this project's test files serially. Default: false — window-resize\n * signal delivery races when several per-worker headless compositors run\n * at once (see docs/gtkx-rc3-notes.md); the suite this recipe is proven\n * on takes seconds, so serial execution is the cheap fix. Override once a\n * suite is large enough for parallelism to matter more than that race.\n */\n fileParallelism?: boolean\n}\n\nconst DEFAULT_INCLUDE = [\"**/*.gtk.test.{ts,tsx}\"]\nconst DEFAULT_INLINE_DEPS: (string | RegExp)[] = [/@react-navigation/]\nconst SETUP_FILE = fileURLToPath(new URL(\"./setup.js\", import.meta.url))\n\n/**\n * A ready Vitest project config for react-native-gtkx component tests: the\n * headless Wayland compositor, the react-native alias and platform\n * extensions, and the React act-environment setup — the same recipe this\n * repo's own suite runs on. Use the result as a whole config\n * (`defineConfig(reactNativeGtkxTest())`) or as one entry of\n * `test.projects` alongside a portable \"unit\" project.\n *\n * Requires a headless Wayland compositor on PATH (`sway` by default —\n * `apt install sway xwayland dbus`, see docs/getting-started.md) and\n * `gtkx codegen` to have already generated the project's `@gtkx/gi`\n * bindings — a bare `vitest run` does not trigger codegen itself, unlike\n * `gtkx dev`/`gtkx build`. A missing compositor or codegen store fails with\n * a readable error (e.g. `Cannot find the \"sway\" executable on PATH`), not\n * a hang.\n */\nexport const reactNativeGtkxTest = async (\n options: ReactNativeGtkxTestOptions = {},\n): Promise<UserWorkspaceConfig> => {\n const gtkx = (await import(\"@gtkx/vitest\")).default\n const plugins: Plugin[] = [\n gtkx(options.headless),\n reactNativeGtkx(options.platform),\n ]\n return {\n plugins,\n test: {\n name: options.name ?? \"gtk\",\n include: options.include ?? DEFAULT_INCLUDE,\n setupFiles: [SETUP_FILE, ...(options.setupFiles ?? [])],\n server: {\n deps: {\n inline: [...DEFAULT_INLINE_DEPS, ...(options.inlineDeps ?? [])],\n },\n },\n fileParallelism: options.fileParallelism ?? false,\n },\n }\n}\n\nexport default reactNativeGtkxTest\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vitest/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,mDAAmD;AACnD,EAAE;AACF,iEAAiE;AACjE,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAC5E,qEAAqE;AACrE,0EAA0E;AAC1E,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAI7C,OAAO,EAAE,eAAe,EAA+B,MAAM,kBAAkB,CAAA;AAkC/E,MAAM,eAAe,GAAG,CAAC,wBAAwB,CAAC,CAAA;AAClD,MAAM,mBAAmB,GAAwB,CAAC,mBAAmB,CAAC,CAAA;AACtE,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAExE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,UAAsC,EAAE,EACV,EAAE;IAChC,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAA;IACnD,MAAM,OAAO,GAAa;QACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC;KAClC,CAAA;IACD,OAAO;QACL,OAAO;QACP,IAAI,EAAE;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;YAC3B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,eAAe;YAC3C,UAAU,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;YACvD,MAAM,EAAE;gBACN,IAAI,EAAE;oBACJ,MAAM,EAAE,CAAC,GAAG,mBAAmB,EAAE,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;iBAChE;aACF;YACD,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,KAAK;SAClD;KACF,CAAA;AACH,CAAC,CAAA;AAED,eAAe,mBAAmB,CAAA","sourcesContent":["// react-native-gtkx/vitest — the vitest recipe this repo's own test suite\n// runs on (see vitest.config.ts's \"gtk\" project), packaged for a consumer\n// app: the @gtkx/vitest headless-compositor plugin, the react-native-gtkx\n// vite preset (react-native alias + Metro-style platform extensions), a\n// default inline-deps list for RN libraries that import \"react-native\"\n// themselves, and the React act-environment setup.\n//\n// Self-contained like ./vite, ./metro and ./runner: a consumer's\n// vitest.config.ts is loaded the same way vite.config.ts is (vite's config\n// loader bundles only the user's own relative import graph; node_modules\n// imports stay bare specifiers, resolved afterwards by plain Node ESM) — so\n// this file must not contain extensionless relative imports. The one\n// relative import below carries an explicit \".js\" extension, which a real\n// sibling file on disk resolves under plain Node without any bundler.\nimport { fileURLToPath, URL } from \"node:url\"\nimport type { PluginOptions as GtkxPluginOptions } from \"@gtkx/vitest\"\nimport type { Plugin } from \"vite\"\nimport type { UserWorkspaceConfig } from \"vitest/config\"\nimport { reactNativeGtkx, type ReactNativeGtkxOptions } from \"../vite/index.js\"\n\n/**\n * Options accepted by {@link reactNativeGtkxTest}. Every field is optional\n * and falls back to the recipe this repo's own test suite runs on.\n */\nexport type ReactNativeGtkxTestOptions = {\n /** Vitest project name. Default: \"gtk\". */\n name?: string\n /** Test file glob(s), relative to the project root. Default: `[\"**\\/*.gtk.test.{ts,tsx}\"]`. */\n include?: string[]\n /** Headless compositor size/compositor, forwarded to @gtkx/vitest's plugin. */\n headless?: GtkxPluginOptions\n /** Metro-style platform resolution options, forwarded to the vite preset. */\n platform?: ReactNativeGtkxOptions\n /**\n * Extra `server.deps.inline` patterns, merged after the default\n * (`/@react-navigation/`). Needed for any node_modules library that\n * itself imports \"react-native\" — Vitest externalizes node_modules code\n * by default, a path the react-native alias cannot reach.\n */\n inlineDeps?: (string | RegExp)[]\n /** Extra setup files, run after the built-in React act-environment setup. */\n setupFiles?: string[]\n /**\n * Run this project's test files serially. Default: false — window-resize\n * signal delivery races when several per-worker headless compositors run\n * at once (see docs/gtkx-rc4-notes.md); the suite this recipe is proven\n * on takes seconds, so serial execution is the cheap fix. Override once a\n * suite is large enough for parallelism to matter more than that race.\n */\n fileParallelism?: boolean\n}\n\nconst DEFAULT_INCLUDE = [\"**/*.gtk.test.{ts,tsx}\"]\nconst DEFAULT_INLINE_DEPS: (string | RegExp)[] = [/@react-navigation/]\nconst SETUP_FILE = fileURLToPath(new URL(\"./setup.js\", import.meta.url))\n\n/**\n * A ready Vitest project config for react-native-gtkx component tests: the\n * headless Wayland compositor, the react-native alias and platform\n * extensions, and the React act-environment setup — the same recipe this\n * repo's own suite runs on. Use the result as a whole config\n * (`defineConfig(reactNativeGtkxTest())`) or as one entry of\n * `test.projects` alongside a portable \"unit\" project.\n *\n * Requires a headless Wayland compositor on PATH (`sway` by default —\n * `apt install sway xwayland dbus`, see docs/getting-started.md) and\n * `gtkx codegen` to have already generated the project's `@gtkx/gi`\n * bindings — a bare `vitest run` does not trigger codegen itself, unlike\n * `gtkx dev`/`gtkx build`. A missing compositor or codegen store fails with\n * a readable error (e.g. `Cannot find the \"sway\" executable on PATH`), not\n * a hang.\n */\nexport const reactNativeGtkxTest = async (\n options: ReactNativeGtkxTestOptions = {},\n): Promise<UserWorkspaceConfig> => {\n const gtkx = (await import(\"@gtkx/vitest\")).default\n const plugins: Plugin[] = [\n gtkx(options.headless),\n reactNativeGtkx(options.platform),\n ]\n return {\n plugins,\n test: {\n name: options.name ?? \"gtk\",\n include: options.include ?? DEFAULT_INCLUDE,\n setupFiles: [SETUP_FILE, ...(options.setupFiles ?? [])],\n server: {\n deps: {\n inline: [...DEFAULT_INLINE_DEPS, ...(options.inlineDeps ?? [])],\n },\n },\n fileParallelism: options.fileParallelism ?? false,\n },\n }\n}\n\nexport default reactNativeGtkxTest\n"]}
@@ -0,0 +1,4 @@
1
+ declare const runOnUI: <A extends unknown[]>(worklet: (...args: A) => unknown) => (...args: A) => void, scheduleOnUI: <A extends unknown[]>(worklet: (...args: A) => unknown, ...args: A) => void, runOnJS: <A extends unknown[]>(fn: (...args: A) => unknown) => (...args: A) => void, scheduleOnRN: <A extends unknown[]>(fn: (...args: A) => unknown, ...args: A) => void, runOnUIAsync: <A extends unknown[], R>(worklet: (...args: A) => R, ...args: A) => Promise<R>;
2
+ export { runOnJS, runOnUI, runOnUIAsync, scheduleOnRN, scheduleOnUI };
3
+ export { callMicrotasks, createSerializable, createShareable, createSynchronizable, createWorkletRuntime, executeOnUIRuntimeSync, getDynamicFeatureFlag, getRuntimeKind, getStaticFeatureFlag, getUIRuntimeHolder, getUISchedulerHolder, isBundleModeEnabled, isRNRuntime, isSerializableRef, isShareable, isShareableRef, isSynchronizable, isUIRuntime, isWorkerRuntime, isWorkletFunction, isWorkletRuntime, makeShareable, makeShareableCloneOnUIRecursive, makeShareableCloneRecursive, registerCustomSerializable, runOnRuntime, runOnRuntimeAsync, runOnRuntimeAsyncWithId, runOnRuntimeSync, runOnRuntimeSyncWithId, RuntimeKind, runOnUISync, scheduleOnRuntime, scheduleOnRuntimeWithId, serializableMappingCache, setDynamicFeatureFlag, shareableMappingCache, toggleSlowAnimationsOnUIRuntime, UIRuntimeId, WorkletsModule, } from "./surface";
4
+ export type { SerializableRef, ShareableRef, WorkletFunction, WorkletRuntime, } from "./surface";