react-native-gtkx 0.1.0-alpha.4 → 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/dist/adw/index.d.ts +3 -0
- package/dist/adw/index.js +41 -0
- package/dist/adw/index.js.map +1 -0
- package/dist/adw/widgets.generated.d.ts +63 -0
- package/dist/adw/widgets.generated.js +125 -0
- package/dist/adw/widgets.generated.js.map +1 -0
- package/dist/common/content.d.ts +69 -0
- package/dist/common/content.js +84 -0
- package/dist/common/content.js.map +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.js +19 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/navigation-stack.d.ts +84 -0
- package/dist/common/navigation-stack.js +313 -0
- package/dist/common/navigation-stack.js.map +1 -0
- package/dist/common/widget.d.ts +83 -0
- package/dist/common/widget.js +142 -0
- package/dist/common/widget.js.map +1 -0
- package/dist/components/animated.d.ts +3 -2
- package/dist/components/animated.js +85 -66
- package/dist/components/animated.js.map +1 -1
- package/dist/components/app-registry.d.ts +10 -1
- package/dist/components/app-registry.js +8 -3
- package/dist/components/app-registry.js.map +1 -1
- package/dist/components/pressable.js +105 -12
- package/dist/components/pressable.js.map +1 -1
- package/dist/components/rect-store.d.ts +11 -1
- package/dist/components/rect-store.js +27 -3
- package/dist/components/rect-store.js.map +1 -1
- package/dist/components/svg/animated-support.d.ts +19 -0
- package/dist/components/svg/animated-support.js +64 -0
- package/dist/components/svg/animated-support.js.map +1 -0
- package/dist/components/svg/context.d.ts +8 -0
- package/dist/components/svg/context.js +15 -0
- package/dist/components/svg/context.js.map +1 -0
- package/dist/components/svg/gradients.d.ts +31 -0
- package/dist/components/svg/gradients.js +93 -0
- package/dist/components/svg/gradients.js.map +1 -0
- package/dist/components/svg/group.d.ts +8 -0
- package/dist/components/svg/group.js +30 -0
- package/dist/components/svg/group.js.map +1 -0
- package/dist/components/svg/index.d.ts +6 -0
- package/dist/components/svg/index.js +5 -0
- package/dist/components/svg/index.js.map +1 -0
- package/dist/components/svg/node.d.ts +7 -0
- package/dist/components/svg/node.js +7 -0
- package/dist/components/svg/node.js.map +1 -0
- package/dist/components/svg/paint.d.ts +24 -0
- package/dist/components/svg/paint.js +57 -0
- package/dist/components/svg/paint.js.map +1 -0
- package/dist/components/svg/shapes.d.ts +47 -0
- package/dist/components/svg/shapes.js +51 -0
- package/dist/components/svg/shapes.js.map +1 -0
- package/dist/components/svg/svg.d.ts +14 -0
- package/dist/components/svg/svg.js +48 -0
- package/dist/components/svg/svg.js.map +1 -0
- package/dist/components/svg/use-shape-node.d.ts +12 -0
- package/dist/components/svg/use-shape-node.js +52 -0
- package/dist/components/svg/use-shape-node.js.map +1 -0
- package/dist/components/text.js +11 -2
- package/dist/components/text.js.map +1 -1
- package/dist/components/use-layout-child.js +47 -4
- package/dist/components/use-layout-child.js.map +1 -1
- package/dist/contracts.d.ts +12 -1
- package/dist/contracts.js.map +1 -1
- package/dist/gtk/index.d.ts +6 -0
- package/dist/gtk/index.js +39 -0
- package/dist/gtk/index.js.map +1 -0
- package/dist/gtk/widgets.generated.d.ts +103 -0
- package/dist/gtk/widgets.generated.js +206 -0
- package/dist/gtk/widgets.generated.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +9 -4
- package/dist/gtkx/bridge/index.js +40 -4
- package/dist/gtkx/bridge/index.js.map +1 -1
- package/dist/gtkx/bridge/layout-manager.d.ts +2 -1
- package/dist/gtkx/bridge/layout-manager.js +31 -9
- package/dist/gtkx/bridge/layout-manager.js.map +1 -1
- package/dist/gtkx/bridge/svg-node.d.ts +79 -0
- package/dist/gtkx/bridge/svg-node.js +367 -0
- package/dist/gtkx/bridge/svg-node.js.map +1 -0
- package/dist/gtkx/bridge/use-signal.js +18 -8
- package/dist/gtkx/bridge/use-signal.js.map +1 -1
- package/dist/gtkx/bridge/widgets.generated.d.ts +2 -0
- package/dist/gtkx/bridge/widgets.generated.js +14 -0
- package/dist/gtkx/bridge/widgets.generated.js.map +1 -0
- package/dist/mcp/bin.d.ts +2 -0
- package/dist/mcp/bin.js +17 -0
- package/dist/mcp/bin.js.map +1 -0
- package/dist/mcp/data/generated.d.ts +1282 -0
- package/dist/mcp/data/generated.js +1148 -0
- package/dist/mcp/data/generated.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/list.d.ts +4 -0
- package/dist/mcp/list.js +56 -0
- package/dist/mcp/list.js.map +1 -0
- package/dist/mcp/resolve.d.ts +55 -0
- package/dist/mcp/resolve.js +151 -0
- package/dist/mcp/resolve.js.map +1 -0
- package/dist/mcp/search.d.ts +13 -0
- package/dist/mcp/search.js +48 -0
- package/dist/mcp/search.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +135 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool.d.ts +21 -0
- package/dist/mcp/tool.js +36 -0
- package/dist/mcp/tool.js.map +1 -0
- package/dist/metro/index.js +10 -0
- package/dist/metro/index.js.map +1 -1
- package/dist/navigation/index.d.ts +50 -13
- package/dist/navigation/index.js +183 -148
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/option-warnings.js +9 -1
- package/dist/navigation/option-warnings.js.map +1 -1
- package/dist/navigation/sidebar.d.ts +177 -9
- package/dist/navigation/sidebar.js +284 -10
- package/dist/navigation/sidebar.js.map +1 -1
- package/dist/runner/index.d.ts +22 -2
- package/dist/runner/index.js +163 -13
- package/dist/runner/index.js.map +1 -1
- package/dist/sea/assemble.d.ts +29 -0
- package/dist/sea/assemble.js +129 -0
- package/dist/sea/assemble.js.map +1 -0
- package/dist/sea/bundle.d.ts +61 -0
- package/dist/sea/bundle.js +202 -0
- package/dist/sea/bundle.js.map +1 -0
- package/dist/sea/gtkx-config-module.d.ts +18 -0
- package/dist/sea/gtkx-config-module.js +67 -0
- package/dist/sea/gtkx-config-module.js.map +1 -0
- package/dist/sea/native-shim.d.ts +40 -0
- package/dist/sea/native-shim.js +121 -0
- package/dist/sea/native-shim.js.map +1 -0
- package/dist/sea/react-anchor-plugin.d.ts +2 -0
- package/dist/sea/react-anchor-plugin.js +30 -0
- package/dist/sea/react-anchor-plugin.js.map +1 -0
- package/dist/style/index.d.ts +1 -0
- package/dist/style/index.js +1 -0
- package/dist/style/index.js.map +1 -1
- package/dist/style/split-style.js +2 -2
- package/dist/style/split-style.js.map +1 -1
- package/dist/style/transform.d.ts +22 -0
- package/dist/style/transform.js +137 -0
- package/dist/style/transform.js.map +1 -0
- package/dist/style/visual-css.js +3 -2
- package/dist/style/visual-css.js.map +1 -1
- package/dist/svg/geometry.d.ts +19 -0
- package/dist/svg/geometry.js +80 -0
- package/dist/svg/geometry.js.map +1 -0
- package/dist/svg/gradient-geometry.d.ts +15 -0
- package/dist/svg/gradient-geometry.js +18 -0
- package/dist/svg/gradient-geometry.js.map +1 -0
- package/dist/svg/transform.d.ts +22 -0
- package/dist/svg/transform.js +74 -0
- package/dist/svg/transform.js.map +1 -0
- package/dist/svg/view-box.d.ts +34 -0
- package/dist/svg/view-box.js +108 -0
- package/dist/svg/view-box.js.map +1 -0
- package/dist/svg-compat/index.d.ts +1 -0
- package/dist/svg-compat/index.js +16 -0
- package/dist/svg-compat/index.js.map +1 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +14 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/vite/index.d.ts +7 -3
- package/dist/vite/index.js +15 -3
- package/dist/vite/index.js.map +1 -1
- package/dist/vitest/index.d.ts +52 -0
- package/dist/vitest/index.js +58 -0
- package/dist/vitest/index.js.map +1 -0
- package/dist/vitest/setup.d.ts +4 -0
- package/dist/vitest/setup.js +22 -0
- package/dist/vitest/setup.js.map +1 -0
- package/package.json +47 -8
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Pure viewBox / preserveAspectRatio math (SVG 1.1 §7.11). No gtkx imports —
|
|
2
|
+
// the bridge feeds the result into Gtk.Snapshot.scale()/translate(), but the
|
|
3
|
+
// arithmetic itself has nothing to do with GTK and is fully unit-testable.
|
|
4
|
+
// "minX minY width height", comma or whitespace separated (SVG allows
|
|
5
|
+
// either). Returns null for anything that doesn't parse to exactly 4
|
|
6
|
+
// numbers or has a non-positive size — callers fall back to the identity
|
|
7
|
+
// transform, same as SVG does when viewBox is absent.
|
|
8
|
+
export const parseViewBox = (value) => {
|
|
9
|
+
if (!value) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const parts = value
|
|
13
|
+
.trim()
|
|
14
|
+
.split(/[\s,]+/)
|
|
15
|
+
.map(Number);
|
|
16
|
+
if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const [minX, minY, width, height] = parts;
|
|
20
|
+
if (width <= 0 || height <= 0) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return { minX, minY, width, height };
|
|
24
|
+
};
|
|
25
|
+
const ALIGN_PATTERN = /^x(Min|Mid|Max)Y(Min|Mid|Max)$/;
|
|
26
|
+
export const DEFAULT_PRESERVE_ASPECT_RATIO = {
|
|
27
|
+
align: { x: "mid", y: "mid" },
|
|
28
|
+
meetOrSlice: "meet",
|
|
29
|
+
};
|
|
30
|
+
// Tolerant like the transform-string parser: unrecognized tokens fall back
|
|
31
|
+
// to the SVG default (xMidYMid meet) rather than throwing.
|
|
32
|
+
export const parsePreserveAspectRatio = (value) => {
|
|
33
|
+
if (!value) {
|
|
34
|
+
return DEFAULT_PRESERVE_ASPECT_RATIO;
|
|
35
|
+
}
|
|
36
|
+
const tokens = value.trim().split(/\s+/);
|
|
37
|
+
const alignToken = tokens[0] ?? "";
|
|
38
|
+
const meetOrSlice = tokens[1] === "slice" ? "slice" : "meet";
|
|
39
|
+
if (alignToken === "none") {
|
|
40
|
+
return { align: "none", meetOrSlice };
|
|
41
|
+
}
|
|
42
|
+
const match = ALIGN_PATTERN.exec(alignToken);
|
|
43
|
+
if (!match) {
|
|
44
|
+
return DEFAULT_PRESERVE_ASPECT_RATIO;
|
|
45
|
+
}
|
|
46
|
+
const x = match[1].toLowerCase();
|
|
47
|
+
const y = match[2].toLowerCase();
|
|
48
|
+
return { align: { x, y }, meetOrSlice };
|
|
49
|
+
};
|
|
50
|
+
const IDENTITY = {
|
|
51
|
+
scaleX: 1,
|
|
52
|
+
scaleY: 1,
|
|
53
|
+
translateX: 0,
|
|
54
|
+
translateY: 0,
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Maps viewBox user-space coordinates onto a `viewportWidth` x
|
|
58
|
+
* `viewportHeight` box: `screen = user * scale + translate`. Mirrors the SVG
|
|
59
|
+
* algorithm exactly (see spec §7.11) — "none" stretches independently per
|
|
60
|
+
* axis, "meet" fits the whole viewBox inside the viewport (letterboxing),
|
|
61
|
+
* "slice" fills the viewport and overflows the viewBox (the bridge clips to
|
|
62
|
+
* the viewport bounds, same as a real SVG renderer).
|
|
63
|
+
*/
|
|
64
|
+
export const resolveViewBoxTransform = (viewBox, viewportWidth, viewportHeight, preserveAspectRatio = DEFAULT_PRESERVE_ASPECT_RATIO) => {
|
|
65
|
+
if (!viewBox || viewportWidth <= 0 || viewportHeight <= 0) {
|
|
66
|
+
return IDENTITY;
|
|
67
|
+
}
|
|
68
|
+
const rawScaleX = viewportWidth / viewBox.width;
|
|
69
|
+
const rawScaleY = viewportHeight / viewBox.height;
|
|
70
|
+
let scaleX;
|
|
71
|
+
let scaleY;
|
|
72
|
+
if (preserveAspectRatio.align === "none") {
|
|
73
|
+
scaleX = rawScaleX;
|
|
74
|
+
scaleY = rawScaleY;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const scale = preserveAspectRatio.meetOrSlice === "meet"
|
|
78
|
+
? Math.min(rawScaleX, rawScaleY)
|
|
79
|
+
: Math.max(rawScaleX, rawScaleY);
|
|
80
|
+
scaleX = scale;
|
|
81
|
+
scaleY = scale;
|
|
82
|
+
}
|
|
83
|
+
let alignOffsetX = 0;
|
|
84
|
+
let alignOffsetY = 0;
|
|
85
|
+
if (preserveAspectRatio.align !== "none") {
|
|
86
|
+
const extraX = viewportWidth - viewBox.width * scaleX;
|
|
87
|
+
const extraY = viewportHeight - viewBox.height * scaleY;
|
|
88
|
+
if (preserveAspectRatio.align.x === "mid") {
|
|
89
|
+
alignOffsetX = extraX / 2;
|
|
90
|
+
}
|
|
91
|
+
else if (preserveAspectRatio.align.x === "max") {
|
|
92
|
+
alignOffsetX = extraX;
|
|
93
|
+
}
|
|
94
|
+
if (preserveAspectRatio.align.y === "mid") {
|
|
95
|
+
alignOffsetY = extraY / 2;
|
|
96
|
+
}
|
|
97
|
+
else if (preserveAspectRatio.align.y === "max") {
|
|
98
|
+
alignOffsetY = extraY;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
scaleX,
|
|
103
|
+
scaleY,
|
|
104
|
+
translateX: alignOffsetX - viewBox.minX * scaleX,
|
|
105
|
+
translateY: alignOffsetY - viewBox.minY * scaleY,
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=view-box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-box.js","sourceRoot":"","sources":["../../src/svg/view-box.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure viewBox / preserveAspectRatio math (SVG 1.1 §7.11). No gtkx imports —\n// the bridge feeds the result into Gtk.Snapshot.scale()/translate(), but the\n// arithmetic itself has nothing to do with GTK and is fully unit-testable.\n\nexport type ViewBox = {\n minX: number\n minY: number\n width: number\n height: number\n}\n\n// \"minX minY width height\", comma or whitespace separated (SVG allows\n// either). Returns null for anything that doesn't parse to exactly 4\n// numbers or has a non-positive size — callers fall back to the identity\n// transform, same as SVG does when viewBox is absent.\nexport const parseViewBox = (value: string | undefined): ViewBox | null => {\n if (!value) {\n return null\n }\n const parts = value\n .trim()\n .split(/[\\s,]+/)\n .map(Number)\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) {\n return null\n }\n const [minX, minY, width, height] = parts as [number, number, number, number]\n if (width <= 0 || height <= 0) {\n return null\n }\n return { minX, minY, width, height }\n}\n\nexport type AlignX = \"min\" | \"mid\" | \"max\"\nexport type AlignY = \"min\" | \"mid\" | \"max\"\nexport type MeetOrSlice = \"meet\" | \"slice\"\n\nexport type PreserveAspectRatio = {\n align: \"none\" | { x: AlignX; y: AlignY }\n meetOrSlice: MeetOrSlice\n}\n\nconst ALIGN_PATTERN = /^x(Min|Mid|Max)Y(Min|Mid|Max)$/\n\nexport const DEFAULT_PRESERVE_ASPECT_RATIO: PreserveAspectRatio = {\n align: { x: \"mid\", y: \"mid\" },\n meetOrSlice: \"meet\",\n}\n\n// Tolerant like the transform-string parser: unrecognized tokens fall back\n// to the SVG default (xMidYMid meet) rather than throwing.\nexport const parsePreserveAspectRatio = (\n value: string | undefined,\n): PreserveAspectRatio => {\n if (!value) {\n return DEFAULT_PRESERVE_ASPECT_RATIO\n }\n const tokens = value.trim().split(/\\s+/)\n const alignToken = tokens[0] ?? \"\"\n const meetOrSlice: MeetOrSlice = tokens[1] === \"slice\" ? \"slice\" : \"meet\"\n if (alignToken === \"none\") {\n return { align: \"none\", meetOrSlice }\n }\n const match = ALIGN_PATTERN.exec(alignToken)\n if (!match) {\n return DEFAULT_PRESERVE_ASPECT_RATIO\n }\n const x = match[1]!.toLowerCase() as AlignX\n const y = match[2]!.toLowerCase() as AlignY\n return { align: { x, y }, meetOrSlice }\n}\n\nexport type ViewBoxTransform = {\n scaleX: number\n scaleY: number\n translateX: number\n translateY: number\n}\n\nconst IDENTITY: ViewBoxTransform = {\n scaleX: 1,\n scaleY: 1,\n translateX: 0,\n translateY: 0,\n}\n\n/**\n * Maps viewBox user-space coordinates onto a `viewportWidth` x\n * `viewportHeight` box: `screen = user * scale + translate`. Mirrors the SVG\n * algorithm exactly (see spec §7.11) — \"none\" stretches independently per\n * axis, \"meet\" fits the whole viewBox inside the viewport (letterboxing),\n * \"slice\" fills the viewport and overflows the viewBox (the bridge clips to\n * the viewport bounds, same as a real SVG renderer).\n */\nexport const resolveViewBoxTransform = (\n viewBox: ViewBox | null,\n viewportWidth: number,\n viewportHeight: number,\n preserveAspectRatio: PreserveAspectRatio = DEFAULT_PRESERVE_ASPECT_RATIO,\n): ViewBoxTransform => {\n if (!viewBox || viewportWidth <= 0 || viewportHeight <= 0) {\n return IDENTITY\n }\n const rawScaleX = viewportWidth / viewBox.width\n const rawScaleY = viewportHeight / viewBox.height\n\n let scaleX: number\n let scaleY: number\n if (preserveAspectRatio.align === \"none\") {\n scaleX = rawScaleX\n scaleY = rawScaleY\n } else {\n const scale =\n preserveAspectRatio.meetOrSlice === \"meet\"\n ? Math.min(rawScaleX, rawScaleY)\n : Math.max(rawScaleX, rawScaleY)\n scaleX = scale\n scaleY = scale\n }\n\n let alignOffsetX = 0\n let alignOffsetY = 0\n if (preserveAspectRatio.align !== \"none\") {\n const extraX = viewportWidth - viewBox.width * scaleX\n const extraY = viewportHeight - viewBox.height * scaleY\n if (preserveAspectRatio.align.x === \"mid\") {\n alignOffsetX = extraX / 2\n } else if (preserveAspectRatio.align.x === \"max\") {\n alignOffsetX = extraX\n }\n if (preserveAspectRatio.align.y === \"mid\") {\n alignOffsetY = extraY / 2\n } else if (preserveAspectRatio.align.y === \"max\") {\n alignOffsetY = extraY\n }\n }\n\n return {\n scaleX,\n scaleY,\n translateX: alignOffsetX - viewBox.minX * scaleX,\n translateY: alignOffsetY - viewBox.minY * scaleY,\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Circle, Defs, Ellipse, G, Line, LinearGradient, Path, Polygon, Polyline, RadialGradient, Rect, Stop, Svg, Svg as default, type AnimatableNumber, type CircleProps, type DefsProps, type EllipseProps, type GProps, type LinearGradientProps, type LineProps, type PathProps, type PolygonProps, type PolylineProps, type RadialGradientProps, type RectProps, type StopProps, type SvgFillRule, type SvgLineCap, type SvgLineJoin, type SvgProps, } from "../components/svg/index";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// react-native-svg compatibility subpath (by the same pattern as
|
|
2
|
+
// react-native-gtkx/navigation): re-exports our SVG component set in the
|
|
3
|
+
// shape portable code expects — `Svg` as both the default and a named
|
|
4
|
+
// export, everything else named — once an app aliases the bare
|
|
5
|
+
// react-native-svg package name to this subpath. See the alias the metro/
|
|
6
|
+
// vite presets add automatically (packages/react-native-gtkx/src/metro/
|
|
7
|
+
// index.ts, src/vite/index.ts), or a manual bundler alias for apps using
|
|
8
|
+
// neither. The upstream package itself is never a dependency of this one;
|
|
9
|
+
// nothing here imports it — this module only mirrors its export shape.
|
|
10
|
+
//
|
|
11
|
+
// Deliberate gaps against react-native-svg's full surface (see docs/api.md
|
|
12
|
+
// "Svg" for the complete list and the reasoning): no SvgXml/SvgUri (SVG
|
|
13
|
+
// files already load through Image, a different mechanism), no Text/
|
|
14
|
+
// TSpan/TextPath, no Mask/ClipPath/Filter/Marker/Symbol/Use/Pattern.
|
|
15
|
+
export { Circle, Defs, Ellipse, G, Line, LinearGradient, Path, Polygon, Polyline, RadialGradient, Rect, Stop, Svg, Svg as default, } from "../components/svg/index";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/svg-compat/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yEAAyE;AACzE,sEAAsE;AACtE,+DAA+D;AAC/D,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,EAAE;AACF,2EAA2E;AAC3E,wEAAwE;AACxE,qEAAqE;AACrE,qEAAqE;AACrE,OAAO,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,CAAC,EACD,IAAI,EACJ,cAAc,EACd,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,GAAG,IAAI,OAAO,GAkBf,MAAM,yBAAyB,CAAA","sourcesContent":["// react-native-svg compatibility subpath (by the same pattern as\n// react-native-gtkx/navigation): re-exports our SVG component set in the\n// shape portable code expects — `Svg` as both the default and a named\n// export, everything else named — once an app aliases the bare\n// react-native-svg package name to this subpath. See the alias the metro/\n// vite presets add automatically (packages/react-native-gtkx/src/metro/\n// index.ts, src/vite/index.ts), or a manual bundler alias for apps using\n// neither. The upstream package itself is never a dependency of this one;\n// nothing here imports it — this module only mirrors its export shape.\n//\n// Deliberate gaps against react-native-svg's full surface (see docs/api.md\n// \"Svg\" for the complete list and the reasoning): no SvgXml/SvgUri (SVG\n// files already load through Image, a different mechanism), no Text/\n// TSpan/TextPath, no Mask/ClipPath/Filter/Marker/Symbol/Use/Pattern.\nexport {\n Circle,\n Defs,\n Ellipse,\n G,\n Line,\n LinearGradient,\n Path,\n Polygon,\n Polyline,\n RadialGradient,\n Rect,\n Stop,\n Svg,\n Svg as default,\n type AnimatableNumber,\n type CircleProps,\n type DefsProps,\n type EllipseProps,\n type GProps,\n type LinearGradientProps,\n type LineProps,\n type PathProps,\n type PolygonProps,\n type PolylineProps,\n type RadialGradientProps,\n type RectProps,\n type StopProps,\n type SvgFillRule,\n type SvgLineCap,\n type SvgLineJoin,\n type SvgProps,\n} from \"../components/svg/index\"\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RenderHookOptions, RenderHookResult, RenderResult } from "@gtkx/testing";
|
|
2
|
+
export * from "@gtkx/testing";
|
|
3
|
+
/**
|
|
4
|
+
* Like `renderHook`, but first creates and presents a harness window (via
|
|
5
|
+
* `render(null)`), so window-dependent hooks have a toplevel to read.
|
|
6
|
+
* Cleanup is automatic — @gtkx/testing tears down every active render
|
|
7
|
+
* (including the harness window) after each test.
|
|
8
|
+
*/
|
|
9
|
+
export declare function renderHookWithWindow<Result>(callback: () => Result, options?: RenderHookOptions<undefined>): Promise<RenderHookResult<Result, undefined> & {
|
|
10
|
+
window: RenderResult["container"];
|
|
11
|
+
}>;
|
|
12
|
+
export declare function renderHookWithWindow<Result, Props>(callback: (props: Props) => Result, options: RenderHookOptions<Props>): Promise<RenderHookResult<Result, Props> & {
|
|
13
|
+
window: RenderResult["container"];
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { render, renderHook } from "@gtkx/testing";
|
|
2
|
+
// react-native-gtkx/testing — @gtkx/testing's queries, render, renderHook,
|
|
3
|
+
// fireEvent and userEvent already operate on the real GTK widget tree our
|
|
4
|
+
// RN components render into, so `getByText` on a `Text` or `userEvent.click`
|
|
5
|
+
// on a `Pressable` already work with no RN-flavoured wrapper: this subpath
|
|
6
|
+
// re-exports that surface as-is, one import source for a consumer, plus the
|
|
7
|
+
// one genuinely repeated workaround (see below).
|
|
8
|
+
export * from "@gtkx/testing";
|
|
9
|
+
export async function renderHookWithWindow(callback, options) {
|
|
10
|
+
const { container: window } = await render(null);
|
|
11
|
+
const hook = await renderHook(callback, options);
|
|
12
|
+
return { ...hook, window };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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// RC2-WORKAROUND(renderhook-no-window): see docs/gtkx-rc2-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"]}
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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
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. */
|
package/dist/vite/index.js
CHANGED
|
@@ -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
|
-
*
|
|
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
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. */
|
package/dist/vite/index.js.map
CHANGED
|
@@ -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 // 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"]}
|
|
@@ -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-rc2-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-rc2-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,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.
|
|
3
|
+
"version": "0.2.0-alpha.1",
|
|
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": "
|
|
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": "^
|
|
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
113
|
"@gtkx/cli": "1.0.0-rc.2",
|
|
114
|
+
"@gtkx/codegen": "1.0.0-rc.2",
|
|
79
115
|
"@gtkx/config": "1.0.0-rc.2",
|
|
80
116
|
"@gtkx/css": "1.0.0-rc.2",
|
|
81
117
|
"@gtkx/react": "1.0.0-rc.2",
|
|
82
118
|
"@gtkx/runtime": "1.0.0-rc.2",
|
|
83
|
-
"yoga-layout": "^3.2.1"
|
|
84
|
-
},
|
|
85
|
-
"devDependencies": {
|
|
86
119
|
"@gtkx/testing": "1.0.0-rc.2",
|
|
87
120
|
"@gtkx/vitest": "1.0.0-rc.2",
|
|
121
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
122
|
+
"rolldown": "^1.1.5",
|
|
123
|
+
"yoga-layout": "^3.2.1",
|
|
124
|
+
"zod": "^4.4.3"
|
|
125
|
+
},
|
|
126
|
+
"devDependencies": {
|
|
88
127
|
"vite": "^8.1.4"
|
|
89
128
|
},
|
|
90
129
|
"files": [
|