react-native-gtkx 0.1.0-alpha.4 → 0.2.0-alpha.2

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 (257) hide show
  1. package/README.md +22 -9
  2. package/dist/adw/index.d.ts +3 -0
  3. package/dist/adw/index.js +41 -0
  4. package/dist/adw/index.js.map +1 -0
  5. package/dist/adw/widgets.generated.d.ts +63 -0
  6. package/dist/adw/widgets.generated.js +125 -0
  7. package/dist/adw/widgets.generated.js.map +1 -0
  8. package/dist/animated/create-animated.d.ts +2 -0
  9. package/dist/animated/create-animated.js +2 -0
  10. package/dist/animated/create-animated.js.map +1 -1
  11. package/dist/animated/index.d.ts +2 -0
  12. package/dist/animated/index.js +1 -0
  13. package/dist/animated/index.js.map +1 -1
  14. package/dist/animated/value-xy.d.ts +41 -0
  15. package/dist/animated/value-xy.js +90 -0
  16. package/dist/animated/value-xy.js.map +1 -0
  17. package/dist/animated/value.d.ts +9 -0
  18. package/dist/animated/value.js +30 -2
  19. package/dist/animated/value.js.map +1 -1
  20. package/dist/common/content.d.ts +69 -0
  21. package/dist/common/content.js +84 -0
  22. package/dist/common/content.js.map +1 -0
  23. package/dist/common/icon.d.ts +23 -0
  24. package/dist/common/icon.js +14 -0
  25. package/dist/common/icon.js.map +1 -0
  26. package/dist/common/index.d.ts +5 -0
  27. package/dist/common/index.js +21 -0
  28. package/dist/common/index.js.map +1 -0
  29. package/dist/common/list.d.ts +82 -0
  30. package/dist/common/list.js +166 -0
  31. package/dist/common/list.js.map +1 -0
  32. package/dist/common/navigation-stack.d.ts +84 -0
  33. package/dist/common/navigation-stack.js +313 -0
  34. package/dist/common/navigation-stack.js.map +1 -0
  35. package/dist/common/widget.d.ts +62 -0
  36. package/dist/common/widget.js +209 -0
  37. package/dist/common/widget.js.map +1 -0
  38. package/dist/components/animated.d.ts +7 -4
  39. package/dist/components/animated.js +88 -67
  40. package/dist/components/animated.js.map +1 -1
  41. package/dist/components/app-registry.d.ts +36 -1
  42. package/dist/components/app-registry.js +8 -3
  43. package/dist/components/app-registry.js.map +1 -1
  44. package/dist/components/host-node.d.ts +7 -0
  45. package/dist/components/host-node.js +26 -1
  46. package/dist/components/host-node.js.map +1 -1
  47. package/dist/components/index.d.ts +6 -2
  48. package/dist/components/index.js +2 -1
  49. package/dist/components/index.js.map +1 -1
  50. package/dist/components/measure.d.ts +13 -0
  51. package/dist/components/measure.js +51 -0
  52. package/dist/components/measure.js.map +1 -0
  53. package/dist/components/modal.d.ts +1 -1
  54. package/dist/components/press-event.d.ts +28 -0
  55. package/dist/components/press-event.js +46 -0
  56. package/dist/components/press-event.js.map +1 -0
  57. package/dist/components/pressable.d.ts +2 -6
  58. package/dist/components/pressable.js +119 -20
  59. package/dist/components/pressable.js.map +1 -1
  60. package/dist/components/rect-store.d.ts +11 -1
  61. package/dist/components/rect-store.js +27 -3
  62. package/dist/components/rect-store.js.map +1 -1
  63. package/dist/components/scroll-view.d.ts +4 -0
  64. package/dist/components/scroll-view.js +8 -2
  65. package/dist/components/scroll-view.js.map +1 -1
  66. package/dist/components/svg/animated-support.d.ts +19 -0
  67. package/dist/components/svg/animated-support.js +64 -0
  68. package/dist/components/svg/animated-support.js.map +1 -0
  69. package/dist/components/svg/context.d.ts +8 -0
  70. package/dist/components/svg/context.js +15 -0
  71. package/dist/components/svg/context.js.map +1 -0
  72. package/dist/components/svg/gradients.d.ts +31 -0
  73. package/dist/components/svg/gradients.js +93 -0
  74. package/dist/components/svg/gradients.js.map +1 -0
  75. package/dist/components/svg/group.d.ts +8 -0
  76. package/dist/components/svg/group.js +30 -0
  77. package/dist/components/svg/group.js.map +1 -0
  78. package/dist/components/svg/index.d.ts +6 -0
  79. package/dist/components/svg/index.js +5 -0
  80. package/dist/components/svg/index.js.map +1 -0
  81. package/dist/components/svg/node.d.ts +7 -0
  82. package/dist/components/svg/node.js +7 -0
  83. package/dist/components/svg/node.js.map +1 -0
  84. package/dist/components/svg/paint.d.ts +24 -0
  85. package/dist/components/svg/paint.js +57 -0
  86. package/dist/components/svg/paint.js.map +1 -0
  87. package/dist/components/svg/shapes.d.ts +47 -0
  88. package/dist/components/svg/shapes.js +51 -0
  89. package/dist/components/svg/shapes.js.map +1 -0
  90. package/dist/components/svg/svg.d.ts +14 -0
  91. package/dist/components/svg/svg.js +48 -0
  92. package/dist/components/svg/svg.js.map +1 -0
  93. package/dist/components/svg/use-shape-node.d.ts +12 -0
  94. package/dist/components/svg/use-shape-node.js +52 -0
  95. package/dist/components/svg/use-shape-node.js.map +1 -0
  96. package/dist/components/text-input.js +1 -1
  97. package/dist/components/text-input.js.map +1 -1
  98. package/dist/components/text.js +36 -3
  99. package/dist/components/text.js.map +1 -1
  100. package/dist/components/use-layout-child.js +50 -4
  101. package/dist/components/use-layout-child.js.map +1 -1
  102. package/dist/components/view.d.ts +9 -4
  103. package/dist/components/view.js +8 -2
  104. package/dist/components/view.js.map +1 -1
  105. package/dist/contracts.d.ts +31 -4
  106. package/dist/contracts.js.map +1 -1
  107. package/dist/gtk/index.d.ts +7 -0
  108. package/dist/gtk/index.js +46 -0
  109. package/dist/gtk/index.js.map +1 -0
  110. package/dist/gtk/widgets.generated.d.ts +103 -0
  111. package/dist/gtk/widgets.generated.js +205 -0
  112. package/dist/gtk/widgets.generated.js.map +1 -0
  113. package/dist/gtk/window-actions.d.ts +77 -0
  114. package/dist/gtk/window-actions.js +193 -0
  115. package/dist/gtk/window-actions.js.map +1 -0
  116. package/dist/gtkx/bridge/geometry.d.ts +15 -0
  117. package/dist/gtkx/bridge/geometry.js +38 -0
  118. package/dist/gtkx/bridge/geometry.js.map +1 -0
  119. package/dist/gtkx/bridge/index.d.ts +11 -4
  120. package/dist/gtkx/bridge/index.js +47 -6
  121. package/dist/gtkx/bridge/index.js.map +1 -1
  122. package/dist/gtkx/bridge/layout-manager.d.ts +2 -1
  123. package/dist/gtkx/bridge/layout-manager.js +31 -9
  124. package/dist/gtkx/bridge/layout-manager.js.map +1 -1
  125. package/dist/gtkx/bridge/slot-portal.d.ts +12 -0
  126. package/dist/gtkx/bridge/slot-portal.js +17 -0
  127. package/dist/gtkx/bridge/slot-portal.js.map +1 -0
  128. package/dist/gtkx/bridge/svg-node.d.ts +79 -0
  129. package/dist/gtkx/bridge/svg-node.js +323 -0
  130. package/dist/gtkx/bridge/svg-node.js.map +1 -0
  131. package/dist/gtkx/bridge/use-signal.js +19 -9
  132. package/dist/gtkx/bridge/use-signal.js.map +1 -1
  133. package/dist/gtkx/bridge/widgets.generated.d.ts +2 -0
  134. package/dist/gtkx/bridge/widgets.generated.js +14 -0
  135. package/dist/gtkx/bridge/widgets.generated.js.map +1 -0
  136. package/dist/index.d.ts +2 -2
  137. package/dist/index.js +1 -1
  138. package/dist/index.js.map +1 -1
  139. package/dist/mcp/bin.d.ts +2 -0
  140. package/dist/mcp/bin.js +17 -0
  141. package/dist/mcp/bin.js.map +1 -0
  142. package/dist/mcp/data/generated.d.ts +1304 -0
  143. package/dist/mcp/data/generated.js +1179 -0
  144. package/dist/mcp/data/generated.js.map +1 -0
  145. package/dist/mcp/index.d.ts +5 -0
  146. package/dist/mcp/index.js +9 -0
  147. package/dist/mcp/index.js.map +1 -0
  148. package/dist/mcp/list.d.ts +4 -0
  149. package/dist/mcp/list.js +56 -0
  150. package/dist/mcp/list.js.map +1 -0
  151. package/dist/mcp/resolve.d.ts +55 -0
  152. package/dist/mcp/resolve.js +151 -0
  153. package/dist/mcp/resolve.js.map +1 -0
  154. package/dist/mcp/search.d.ts +13 -0
  155. package/dist/mcp/search.js +48 -0
  156. package/dist/mcp/search.js.map +1 -0
  157. package/dist/mcp/server.d.ts +7 -0
  158. package/dist/mcp/server.js +135 -0
  159. package/dist/mcp/server.js.map +1 -0
  160. package/dist/mcp/tool.d.ts +21 -0
  161. package/dist/mcp/tool.js +36 -0
  162. package/dist/mcp/tool.js.map +1 -0
  163. package/dist/metro/index.js +10 -0
  164. package/dist/metro/index.js.map +1 -1
  165. package/dist/navigation/index.d.ts +50 -13
  166. package/dist/navigation/index.js +183 -148
  167. package/dist/navigation/index.js.map +1 -1
  168. package/dist/navigation/option-warnings.js +9 -1
  169. package/dist/navigation/option-warnings.js.map +1 -1
  170. package/dist/navigation/sidebar.d.ts +207 -9
  171. package/dist/navigation/sidebar.js +294 -10
  172. package/dist/navigation/sidebar.js.map +1 -1
  173. package/dist/responder/system.d.ts +27 -0
  174. package/dist/responder/system.js +184 -0
  175. package/dist/responder/system.js.map +1 -0
  176. package/dist/responder/touch-history.d.ts +10 -0
  177. package/dist/responder/touch-history.js +78 -0
  178. package/dist/responder/touch-history.js.map +1 -0
  179. package/dist/responder/types.d.ts +63 -0
  180. package/dist/responder/types.js +29 -0
  181. package/dist/responder/types.js.map +1 -0
  182. package/dist/responder/use-responder.d.ts +12 -0
  183. package/dist/responder/use-responder.js +98 -0
  184. package/dist/responder/use-responder.js.map +1 -0
  185. package/dist/runner/host-dev.js +3 -1
  186. package/dist/runner/host-dev.js.map +1 -1
  187. package/dist/runner/host.js +5 -1
  188. package/dist/runner/host.js.map +1 -1
  189. package/dist/runner/index.d.ts +22 -2
  190. package/dist/runner/index.js +163 -13
  191. package/dist/runner/index.js.map +1 -1
  192. package/dist/sea/assemble.d.ts +29 -0
  193. package/dist/sea/assemble.js +129 -0
  194. package/dist/sea/assemble.js.map +1 -0
  195. package/dist/sea/bundle.d.ts +61 -0
  196. package/dist/sea/bundle.js +202 -0
  197. package/dist/sea/bundle.js.map +1 -0
  198. package/dist/sea/gtkx-config-module.d.ts +18 -0
  199. package/dist/sea/gtkx-config-module.js +67 -0
  200. package/dist/sea/gtkx-config-module.js.map +1 -0
  201. package/dist/sea/native-shim.d.ts +40 -0
  202. package/dist/sea/native-shim.js +121 -0
  203. package/dist/sea/native-shim.js.map +1 -0
  204. package/dist/sea/react-anchor-plugin.d.ts +2 -0
  205. package/dist/sea/react-anchor-plugin.js +30 -0
  206. package/dist/sea/react-anchor-plugin.js.map +1 -0
  207. package/dist/style/box-shadow.d.ts +7 -0
  208. package/dist/style/box-shadow.js +197 -0
  209. package/dist/style/box-shadow.js.map +1 -0
  210. package/dist/style/index.d.ts +3 -0
  211. package/dist/style/index.js +3 -0
  212. package/dist/style/index.js.map +1 -1
  213. package/dist/style/split-style.d.ts +5 -2
  214. package/dist/style/split-style.js +33 -5
  215. package/dist/style/split-style.js.map +1 -1
  216. package/dist/style/text-decoration.d.ts +15 -0
  217. package/dist/style/text-decoration.js +26 -0
  218. package/dist/style/text-decoration.js.map +1 -0
  219. package/dist/style/transform.d.ts +22 -0
  220. package/dist/style/transform.js +137 -0
  221. package/dist/style/transform.js.map +1 -0
  222. package/dist/style/visual-css.js +40 -3
  223. package/dist/style/visual-css.js.map +1 -1
  224. package/dist/svg/geometry.d.ts +19 -0
  225. package/dist/svg/geometry.js +80 -0
  226. package/dist/svg/geometry.js.map +1 -0
  227. package/dist/svg/gradient-geometry.d.ts +15 -0
  228. package/dist/svg/gradient-geometry.js +15 -0
  229. package/dist/svg/gradient-geometry.js.map +1 -0
  230. package/dist/svg/transform.d.ts +22 -0
  231. package/dist/svg/transform.js +74 -0
  232. package/dist/svg/transform.js.map +1 -0
  233. package/dist/svg/view-box.d.ts +34 -0
  234. package/dist/svg/view-box.js +108 -0
  235. package/dist/svg/view-box.js.map +1 -0
  236. package/dist/svg-compat/index.d.ts +1 -0
  237. package/dist/svg-compat/index.js +16 -0
  238. package/dist/svg-compat/index.js.map +1 -0
  239. package/dist/testing/index.d.ts +14 -0
  240. package/dist/testing/index.js +14 -0
  241. package/dist/testing/index.js.map +1 -0
  242. package/dist/vendor/react-native/pan-responder.d.ts +102 -0
  243. package/dist/vendor/react-native/pan-responder.js +196 -0
  244. package/dist/vendor/react-native/pan-responder.js.map +1 -0
  245. package/dist/vendor/react-native/touch-history-math.d.ts +18 -0
  246. package/dist/vendor/react-native/touch-history-math.js +102 -0
  247. package/dist/vendor/react-native/touch-history-math.js.map +1 -0
  248. package/dist/vite/index.d.ts +7 -3
  249. package/dist/vite/index.js +16 -4
  250. package/dist/vite/index.js.map +1 -1
  251. package/dist/vitest/index.d.ts +52 -0
  252. package/dist/vitest/index.js +58 -0
  253. package/dist/vitest/index.js.map +1 -0
  254. package/dist/vitest/setup.d.ts +4 -0
  255. package/dist/vitest/setup.js +22 -0
  256. package/dist/vitest/setup.js.map +1 -0
  257. package/package.json +52 -13
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ const noCentroid = -1;
8
+ /**
9
+ * This code is optimized and not intended to look beautiful. This allows
10
+ * computing of touch centroids that have moved after `touchesChangedAfter`
11
+ * timeStamp. You can compute the current centroid involving all touches
12
+ * moves after `touchesChangedAfter`, or you can compute the previous
13
+ * centroid of all touches that were moved after `touchesChangedAfter`.
14
+ *
15
+ * @param touchHistory Standard Responder touch track data.
16
+ * @param touchesChangedAfter timeStamp after which moved touches are
17
+ * considered "actively moving" - not just "active".
18
+ * @param isXAxis Consider `x` dimension vs. `y` dimension.
19
+ * @param ofCurrent Compute current centroid for actively moving touches vs.
20
+ * previous centroid of now actively moving touches.
21
+ * @return value of centroid in specified dimension.
22
+ */
23
+ const centroidDimension = (touchHistory, touchesChangedAfter, isXAxis, ofCurrent) => {
24
+ const touchBank = touchHistory.touchBank;
25
+ let total = 0;
26
+ let count = 0;
27
+ const oneTouchData = touchHistory.numberActiveTouches === 1
28
+ ? touchHistory.touchBank[touchHistory.indexOfSingleActiveTouch]
29
+ : null;
30
+ if (oneTouchData !== null && oneTouchData !== undefined) {
31
+ if (oneTouchData.touchActive &&
32
+ oneTouchData.currentTimeStamp > touchesChangedAfter) {
33
+ total +=
34
+ ofCurrent && isXAxis
35
+ ? oneTouchData.currentPageX
36
+ : ofCurrent && !isXAxis
37
+ ? oneTouchData.currentPageY
38
+ : !ofCurrent && isXAxis
39
+ ? oneTouchData.previousPageX
40
+ : oneTouchData.previousPageY;
41
+ count = 1;
42
+ }
43
+ }
44
+ else {
45
+ for (let i = 0; i < touchBank.length; i++) {
46
+ const touchTrack = touchBank[i];
47
+ if (touchTrack !== null &&
48
+ touchTrack !== undefined &&
49
+ touchTrack.touchActive &&
50
+ touchTrack.currentTimeStamp >= touchesChangedAfter) {
51
+ let toAdd; // Yuck, program temporarily in invalid state.
52
+ if (ofCurrent && isXAxis) {
53
+ toAdd = touchTrack.currentPageX;
54
+ }
55
+ else if (ofCurrent && !isXAxis) {
56
+ toAdd = touchTrack.currentPageY;
57
+ }
58
+ else if (!ofCurrent && isXAxis) {
59
+ toAdd = touchTrack.previousPageX;
60
+ }
61
+ else {
62
+ toAdd = touchTrack.previousPageY;
63
+ }
64
+ total += toAdd;
65
+ count++;
66
+ }
67
+ }
68
+ }
69
+ return count > 0 ? total / count : noCentroid;
70
+ };
71
+ const TouchHistoryMath = {
72
+ centroidDimension,
73
+ currentCentroidXOfTouchesChangedAfter(touchHistory, touchesChangedAfter) {
74
+ return centroidDimension(touchHistory, touchesChangedAfter, true, // isXAxis
75
+ true);
76
+ },
77
+ currentCentroidYOfTouchesChangedAfter(touchHistory, touchesChangedAfter) {
78
+ return centroidDimension(touchHistory, touchesChangedAfter, false, // isXAxis
79
+ true);
80
+ },
81
+ previousCentroidXOfTouchesChangedAfter(touchHistory, touchesChangedAfter) {
82
+ return centroidDimension(touchHistory, touchesChangedAfter, true, // isXAxis
83
+ false);
84
+ },
85
+ previousCentroidYOfTouchesChangedAfter(touchHistory, touchesChangedAfter) {
86
+ return centroidDimension(touchHistory, touchesChangedAfter, false, // isXAxis
87
+ false);
88
+ },
89
+ currentCentroidX(touchHistory) {
90
+ return centroidDimension(touchHistory, 0, // touchesChangedAfter
91
+ true, // isXAxis
92
+ true);
93
+ },
94
+ currentCentroidY(touchHistory) {
95
+ return centroidDimension(touchHistory, 0, // touchesChangedAfter
96
+ false, // isXAxis
97
+ true);
98
+ },
99
+ noCentroid,
100
+ };
101
+ export default TouchHistoryMath;
102
+ //# sourceMappingURL=touch-history-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"touch-history-math.js","sourceRoot":"","sources":["../../../src/vendor/react-native/touch-history-math.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// VENDORED from react-native (MIT), Libraries/Interaction/TouchHistoryMath.js.\n// Kept in this repository for the same reason react-native-web vendors\n// PanResponder: the maths are the contract, and reimplementing them would\n// mean reimplementing a subtlety we do not have the test cases for (see the\n// comment about clustered multi-touch movement in pan-responder.ts).\n//\n// Changes from upstream, and only these:\n// - Flow annotations transliterated to TypeScript;\n// - upstream annotates its own touch-history parameter with the name of the\n// const it is declaring (a self-reference Flow tolerates behind two\n// $FlowFixMe suppressions); that parameter is typed `TouchHistory` here;\n// - the trailing `as {...}` cast, which existed only to break that Flow\n// cycle, is dropped;\n// - `object.method` shorthand instead of `key: function ()`.\n//\n// Do not \"improve\" this file. Diffing it against upstream must stay trivial.\nimport type { TouchHistory } from \"../../responder/types\"\n\nconst noCentroid = -1\n\n/**\n * This code is optimized and not intended to look beautiful. This allows\n * computing of touch centroids that have moved after `touchesChangedAfter`\n * timeStamp. You can compute the current centroid involving all touches\n * moves after `touchesChangedAfter`, or you can compute the previous\n * centroid of all touches that were moved after `touchesChangedAfter`.\n *\n * @param touchHistory Standard Responder touch track data.\n * @param touchesChangedAfter timeStamp after which moved touches are\n * considered \"actively moving\" - not just \"active\".\n * @param isXAxis Consider `x` dimension vs. `y` dimension.\n * @param ofCurrent Compute current centroid for actively moving touches vs.\n * previous centroid of now actively moving touches.\n * @return value of centroid in specified dimension.\n */\nconst centroidDimension = (\n touchHistory: TouchHistory,\n touchesChangedAfter: number,\n isXAxis: boolean,\n ofCurrent: boolean,\n): number => {\n const touchBank = touchHistory.touchBank\n let total = 0\n let count = 0\n\n const oneTouchData =\n touchHistory.numberActiveTouches === 1\n ? touchHistory.touchBank[touchHistory.indexOfSingleActiveTouch]\n : null\n\n if (oneTouchData !== null && oneTouchData !== undefined) {\n if (\n oneTouchData.touchActive &&\n oneTouchData.currentTimeStamp > touchesChangedAfter\n ) {\n total +=\n ofCurrent && isXAxis\n ? oneTouchData.currentPageX\n : ofCurrent && !isXAxis\n ? oneTouchData.currentPageY\n : !ofCurrent && isXAxis\n ? oneTouchData.previousPageX\n : oneTouchData.previousPageY\n count = 1\n }\n } else {\n for (let i = 0; i < touchBank.length; i++) {\n const touchTrack = touchBank[i]\n if (\n touchTrack !== null &&\n touchTrack !== undefined &&\n touchTrack.touchActive &&\n touchTrack.currentTimeStamp >= touchesChangedAfter\n ) {\n let toAdd // Yuck, program temporarily in invalid state.\n if (ofCurrent && isXAxis) {\n toAdd = touchTrack.currentPageX\n } else if (ofCurrent && !isXAxis) {\n toAdd = touchTrack.currentPageY\n } else if (!ofCurrent && isXAxis) {\n toAdd = touchTrack.previousPageX\n } else {\n toAdd = touchTrack.previousPageY\n }\n total += toAdd\n count++\n }\n }\n }\n return count > 0 ? total / count : noCentroid\n}\n\nconst TouchHistoryMath = {\n centroidDimension,\n\n currentCentroidXOfTouchesChangedAfter(\n touchHistory: TouchHistory,\n touchesChangedAfter: number,\n ): number {\n return centroidDimension(\n touchHistory,\n touchesChangedAfter,\n true, // isXAxis\n true, // ofCurrent\n )\n },\n\n currentCentroidYOfTouchesChangedAfter(\n touchHistory: TouchHistory,\n touchesChangedAfter: number,\n ): number {\n return centroidDimension(\n touchHistory,\n touchesChangedAfter,\n false, // isXAxis\n true, // ofCurrent\n )\n },\n\n previousCentroidXOfTouchesChangedAfter(\n touchHistory: TouchHistory,\n touchesChangedAfter: number,\n ): number {\n return centroidDimension(\n touchHistory,\n touchesChangedAfter,\n true, // isXAxis\n false, // ofCurrent\n )\n },\n\n previousCentroidYOfTouchesChangedAfter(\n touchHistory: TouchHistory,\n touchesChangedAfter: number,\n ): number {\n return centroidDimension(\n touchHistory,\n touchesChangedAfter,\n false, // isXAxis\n false, // ofCurrent\n )\n },\n\n currentCentroidX(touchHistory: TouchHistory): number {\n return centroidDimension(\n touchHistory,\n 0, // touchesChangedAfter\n true, // isXAxis\n true, // ofCurrent\n )\n },\n\n currentCentroidY(touchHistory: TouchHistory): number {\n return centroidDimension(\n touchHistory,\n 0, // touchesChangedAfter\n false, // isXAxis\n true, // ofCurrent\n )\n },\n\n noCentroid,\n}\n\nexport default TouchHistoryMath\n"]}
@@ -11,9 +11,13 @@ export type FileExists = (filePath: string) => boolean;
11
11
  export declare const DEFAULT_PLATFORMS: readonly string[];
12
12
  export declare const DEFAULT_EXTENSIONS: readonly string[];
13
13
  /**
14
- * Maps `react-native` (and its subpaths) to `react-native-gtkx`.
15
- * Returns null for every other specifier, including `react-native-gtkx`
16
- * itself and lookalikes such as `react-native-web`.
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
21
  */
18
22
  export declare const rewriteReactNativeImport: (source: string) => string | null;
19
23
  /** Splits a vite specifier into its path part and its `?query` suffix. */
@@ -14,10 +14,16 @@ export const DEFAULT_PLATFORMS = ["linux", "native"];
14
14
  export const DEFAULT_EXTENSIONS = ["tsx", "ts", "jsx", "js"];
15
15
  const REACT_NATIVE = "react-native";
16
16
  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";
17
19
  /**
18
- * Maps `react-native` (and its subpaths) to `react-native-gtkx`.
19
- * Returns null for every other specifier, including `react-native-gtkx`
20
- * itself and lookalikes such as `react-native-web`.
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
27
  */
22
28
  export const rewriteReactNativeImport = (source) => {
23
29
  if (source === REACT_NATIVE) {
@@ -26,6 +32,12 @@ export const rewriteReactNativeImport = (source) => {
26
32
  if (source.startsWith(`${REACT_NATIVE}/`)) {
27
33
  return `${REACT_NATIVE_GTKX}${source.slice(REACT_NATIVE.length)}`;
28
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
+ }
29
41
  return null;
30
42
  };
31
43
  /** Splits a vite specifier into its path part and its `?query` suffix. */
@@ -128,7 +140,7 @@ export const reactNativeGtkx = (options = {}) => ({
128
140
  noExternal: ["react-native-gtkx", "react-native", /^@react-navigation\//],
129
141
  },
130
142
  resolve: {
131
- // RC2-WORKAROUND(runtime-dedupe): see docs/gtkx-rc2-notes.md
143
+ // RC3-WORKAROUND(runtime-dedupe): see docs/gtkx-rc3-notes.md
132
144
  // The gtkx runtime and react are single-instance hosts: when the app
133
145
  // and react-native-gtkx resolve them from different node_modules
134
146
  // (file:-installed package, nested installs), two bundled copies
@@ -1 +1 @@
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// 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\"\n\n/**\n * Maps `react-native` (and its subpaths) to `react-native-gtkx`.\n * Returns null for every other specifier, including `react-native-gtkx`\n * itself and lookalikes such as `react-native-web`.\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 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 // RC2-WORKAROUND(runtime-dedupe): see docs/gtkx-rc2-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// 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"]}
@@ -0,0 +1,52 @@
1
+ import type { GtkxPluginOptions } from "@gtkx/vitest";
2
+ import type { UserWorkspaceConfig } from "vitest/config";
3
+ import { type ReactNativeGtkxOptions } from "../vite/index.js";
4
+ /**
5
+ * Options accepted by {@link reactNativeGtkxTest}. Every field is optional
6
+ * and falls back to the recipe this repo's own test suite runs on.
7
+ */
8
+ export type ReactNativeGtkxTestOptions = {
9
+ /** Vitest project name. Default: "gtk". */
10
+ name?: string;
11
+ /** Test file glob(s), relative to the project root. Default: `["**\/*.gtk.test.{ts,tsx}"]`. */
12
+ include?: string[];
13
+ /** Headless compositor size/compositor, forwarded to @gtkx/vitest's plugin. */
14
+ headless?: GtkxPluginOptions;
15
+ /** Metro-style platform resolution options, forwarded to the vite preset. */
16
+ platform?: ReactNativeGtkxOptions;
17
+ /**
18
+ * Extra `server.deps.inline` patterns, merged after the default
19
+ * (`/@react-navigation/`). Needed for any node_modules library that
20
+ * itself imports "react-native" — Vitest externalizes node_modules code
21
+ * by default, a path the react-native alias cannot reach.
22
+ */
23
+ inlineDeps?: (string | RegExp)[];
24
+ /** Extra setup files, run after the built-in React act-environment setup. */
25
+ setupFiles?: string[];
26
+ /**
27
+ * Run this project's test files serially. Default: false — window-resize
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
30
+ * on takes seconds, so serial execution is the cheap fix. Override once a
31
+ * suite is large enough for parallelism to matter more than that race.
32
+ */
33
+ fileParallelism?: boolean;
34
+ };
35
+ /**
36
+ * A ready Vitest project config for react-native-gtkx component tests: the
37
+ * headless Wayland compositor, the react-native alias and platform
38
+ * extensions, and the React act-environment setup — the same recipe this
39
+ * repo's own suite runs on. Use the result as a whole config
40
+ * (`defineConfig(reactNativeGtkxTest())`) or as one entry of
41
+ * `test.projects` alongside a portable "unit" project.
42
+ *
43
+ * Requires a headless Wayland compositor on PATH (`sway` by default —
44
+ * `apt install sway xwayland dbus`, see docs/getting-started.md) and
45
+ * `gtkx codegen` to have already generated the project's `@gtkx/gi`
46
+ * bindings — a bare `vitest run` does not trigger codegen itself, unlike
47
+ * `gtkx dev`/`gtkx build`. A missing compositor or codegen store fails with
48
+ * a readable error (e.g. `Cannot find the "sway" executable on PATH`), not
49
+ * a hang.
50
+ */
51
+ export declare const reactNativeGtkxTest: (options?: ReactNativeGtkxTestOptions) => Promise<UserWorkspaceConfig>;
52
+ export default reactNativeGtkxTest;
@@ -0,0 +1,58 @@
1
+ // react-native-gtkx/vitest — the vitest recipe this repo's own test suite
2
+ // runs on (see vitest.config.ts's "gtk" project), packaged for a consumer
3
+ // app: the @gtkx/vitest headless-compositor plugin, the react-native-gtkx
4
+ // vite preset (react-native alias + Metro-style platform extensions), a
5
+ // default inline-deps list for RN libraries that import "react-native"
6
+ // themselves, and the React act-environment setup.
7
+ //
8
+ // Self-contained like ./vite, ./metro and ./runner: a consumer's
9
+ // vitest.config.ts is loaded the same way vite.config.ts is (vite's config
10
+ // loader bundles only the user's own relative import graph; node_modules
11
+ // imports stay bare specifiers, resolved afterwards by plain Node ESM) — so
12
+ // this file must not contain extensionless relative imports. The one
13
+ // relative import below carries an explicit ".js" extension, which a real
14
+ // sibling file on disk resolves under plain Node without any bundler.
15
+ import { fileURLToPath, URL } from "node:url";
16
+ import { reactNativeGtkx } from "../vite/index.js";
17
+ const DEFAULT_INCLUDE = ["**/*.gtk.test.{ts,tsx}"];
18
+ const DEFAULT_INLINE_DEPS = [/@react-navigation/];
19
+ const SETUP_FILE = fileURLToPath(new URL("./setup.js", import.meta.url));
20
+ /**
21
+ * A ready Vitest project config for react-native-gtkx component tests: the
22
+ * headless Wayland compositor, the react-native alias and platform
23
+ * extensions, and the React act-environment setup — the same recipe this
24
+ * repo's own suite runs on. Use the result as a whole config
25
+ * (`defineConfig(reactNativeGtkxTest())`) or as one entry of
26
+ * `test.projects` alongside a portable "unit" project.
27
+ *
28
+ * Requires a headless Wayland compositor on PATH (`sway` by default —
29
+ * `apt install sway xwayland dbus`, see docs/getting-started.md) and
30
+ * `gtkx codegen` to have already generated the project's `@gtkx/gi`
31
+ * bindings — a bare `vitest run` does not trigger codegen itself, unlike
32
+ * `gtkx dev`/`gtkx build`. A missing compositor or codegen store fails with
33
+ * a readable error (e.g. `Cannot find the "sway" executable on PATH`), not
34
+ * a hang.
35
+ */
36
+ export const reactNativeGtkxTest = async (options = {}) => {
37
+ const gtkx = (await import("@gtkx/vitest")).default;
38
+ const plugins = [
39
+ gtkx(options.headless),
40
+ reactNativeGtkx(options.platform),
41
+ ];
42
+ return {
43
+ plugins,
44
+ test: {
45
+ name: options.name ?? "gtk",
46
+ include: options.include ?? DEFAULT_INCLUDE,
47
+ setupFiles: [SETUP_FILE, ...(options.setupFiles ?? [])],
48
+ server: {
49
+ deps: {
50
+ inline: [...DEFAULT_INLINE_DEPS, ...(options.inlineDeps ?? [])],
51
+ },
52
+ },
53
+ fileParallelism: options.fileParallelism ?? false,
54
+ },
55
+ };
56
+ };
57
+ export default reactNativeGtkxTest;
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,4 @@
1
+ declare global {
2
+ var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
3
+ }
4
+ export {};
@@ -0,0 +1,22 @@
1
+ // The React "act environment" flag. React batches and warns about updates
2
+ // outside of `act()` unless this is set — required for @gtkx/testing's
3
+ // render/renderHook to behave like React Testing Library. Referenced by an
4
+ // absolute path computed with `import.meta.url` (see index.ts), not
5
+ // statically imported, so it is a plain vitest setupFiles entry like
6
+ // @gtkx/vitest's own worker-setup.js.
7
+ import { beforeAll } from "vitest";
8
+ const setActEnvironment = (value) => {
9
+ Object.defineProperty(globalThis, "IS_REACT_ACT_ENVIRONMENT", {
10
+ value,
11
+ configurable: true,
12
+ writable: true,
13
+ });
14
+ };
15
+ beforeAll(() => {
16
+ const previous = globalThis.IS_REACT_ACT_ENVIRONMENT;
17
+ setActEnvironment(true);
18
+ return () => {
19
+ setActEnvironment(previous);
20
+ };
21
+ });
22
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/vitest/setup.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,uEAAuE;AACvE,2EAA2E;AAC3E,oEAAoE;AACpE,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAMlC,MAAM,iBAAiB,GAAG,CAAC,KAA0B,EAAQ,EAAE;IAC7D,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,0BAA0B,EAAE;QAC5D,KAAK;QACL,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,QAAQ,GAAG,UAAU,CAAC,wBAAwB,CAAA;IACpD,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAEvB,OAAO,GAAG,EAAE;QACV,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC,CAAA;AACH,CAAC,CAAC,CAAA","sourcesContent":["// The React \"act environment\" flag. React batches and warns about updates\n// outside of `act()` unless this is set — required for @gtkx/testing's\n// render/renderHook to behave like React Testing Library. Referenced by an\n// absolute path computed with `import.meta.url` (see index.ts), not\n// statically imported, so it is a plain vitest setupFiles entry like\n// @gtkx/vitest's own worker-setup.js.\nimport { beforeAll } from \"vitest\"\n\ndeclare global {\n var IS_REACT_ACT_ENVIRONMENT: boolean | undefined\n}\n\nconst setActEnvironment = (value: boolean | undefined): void => {\n Object.defineProperty(globalThis, \"IS_REACT_ACT_ENVIRONMENT\", {\n value,\n configurable: true,\n writable: true,\n })\n}\n\nbeforeAll(() => {\n const previous = globalThis.IS_REACT_ACT_ENVIRONMENT\n setActEnvironment(true)\n\n return () => {\n setActEnvironment(previous)\n }\n})\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gtkx",
3
- "version": "0.1.0-alpha.4",
3
+ "version": "0.2.0-alpha.2",
4
4
  "description": "React Native components and APIs for Linux desktop, rendered as native GTK4 widgets via gtkx",
5
5
  "license": "MIT",
6
6
  "author": "Anton Petrov <anton@itsmepetrov.com>",
@@ -47,24 +47,56 @@
47
47
  "types": "./dist/navigation/index.d.ts",
48
48
  "default": "./dist/navigation/index.js"
49
49
  },
50
+ "./svg": {
51
+ "types": "./dist/svg-compat/index.d.ts",
52
+ "default": "./dist/svg-compat/index.js"
53
+ },
54
+ "./gtk": {
55
+ "types": "./dist/gtk/index.d.ts",
56
+ "default": "./dist/gtk/index.js"
57
+ },
58
+ "./adw": {
59
+ "types": "./dist/adw/index.d.ts",
60
+ "default": "./dist/adw/index.js"
61
+ },
62
+ "./common": {
63
+ "types": "./dist/common/index.d.ts",
64
+ "default": "./dist/common/index.js"
65
+ },
66
+ "./mcp": {
67
+ "types": "./dist/mcp/index.d.ts",
68
+ "default": "./dist/mcp/index.js"
69
+ },
50
70
  "./vite": {
51
71
  "types": "./dist/vite/index.d.ts",
52
72
  "default": "./dist/vite/index.js"
53
73
  },
74
+ "./vitest": {
75
+ "types": "./dist/vitest/index.d.ts",
76
+ "default": "./dist/vitest/index.js"
77
+ },
78
+ "./testing": {
79
+ "types": "./dist/testing/index.d.ts",
80
+ "default": "./dist/testing/index.js"
81
+ },
54
82
  "./types": {
55
83
  "types": "./types.d.ts",
56
84
  "default": "./types.js"
57
85
  }
58
86
  },
87
+ "bin": {
88
+ "react-native-gtkx-mcp": "./dist/mcp/bin.js"
89
+ },
59
90
  "scripts": {
60
- "prepack": "bash ../../scripts/sync-package-readme.sh",
61
- "build:dist": "rm -rf dist && tsc -p tsconfig.build.json",
91
+ "prepack": "node ../../scripts/sync-package-readme.ts",
92
+ "build:dist": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/mcp/bin.js",
62
93
  "watch:dist": "tsc -p tsconfig.build.json --watch --preserveWatchOutput"
63
94
  },
64
95
  "peerDependencies": {
65
- "@react-navigation/native": "^7.0.0",
96
+ "@react-navigation/native": "^8.0.0-alpha.40 || ^8.0.0",
66
97
  "react": "^19.2",
67
- "vite": "^7.0.0 || ^8.0.0"
98
+ "vite": "^7.0.0 || ^8.0.0",
99
+ "vitest": ">=4"
68
100
  },
69
101
  "peerDependenciesMeta": {
70
102
  "@react-navigation/native": {
@@ -72,19 +104,26 @@
72
104
  },
73
105
  "vite": {
74
106
  "optional": true
107
+ },
108
+ "vitest": {
109
+ "optional": true
75
110
  }
76
111
  },
77
112
  "dependencies": {
78
- "@gtkx/cli": "1.0.0-rc.2",
79
- "@gtkx/config": "1.0.0-rc.2",
80
- "@gtkx/css": "1.0.0-rc.2",
81
- "@gtkx/react": "1.0.0-rc.2",
82
- "@gtkx/runtime": "1.0.0-rc.2",
83
- "yoga-layout": "^3.2.1"
113
+ "@gtkx/cli": "1.0.0-rc.3",
114
+ "@gtkx/codegen": "1.0.0-rc.3",
115
+ "@gtkx/config": "1.0.0-rc.3",
116
+ "@gtkx/css": "1.0.0-rc.3",
117
+ "@gtkx/react": "1.0.0-rc.3",
118
+ "@gtkx/runtime": "1.0.0-rc.3",
119
+ "@gtkx/testing": "1.0.0-rc.3",
120
+ "@gtkx/vitest": "1.0.0-rc.3",
121
+ "@modelcontextprotocol/sdk": "^1.30.0",
122
+ "rolldown": "^1.1.5",
123
+ "yoga-layout": "^3.2.1",
124
+ "zod": "^4.4.3"
84
125
  },
85
126
  "devDependencies": {
86
- "@gtkx/testing": "1.0.0-rc.2",
87
- "@gtkx/vitest": "1.0.0-rc.2",
88
127
  "vite": "^8.1.4"
89
128
  },
90
129
  "files": [