@gtkx/cli 0.18.0 → 0.18.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/dist/builder.d.ts +25 -6
- package/dist/builder.js +7 -31
- package/dist/cli.js +5 -0
- package/dist/vite-plugin-gtkx-built-url.d.ts +17 -0
- package/dist/vite-plugin-gtkx-built-url.js +42 -0
- package/dist/vite-plugin-gtkx-native.d.ts +13 -0
- package/dist/vite-plugin-gtkx-native.js +52 -0
- package/package.json +6 -6
package/dist/builder.d.ts
CHANGED
|
@@ -5,6 +5,28 @@ import { type InlineConfig } from "vite";
|
|
|
5
5
|
export type BuildOptions = {
|
|
6
6
|
/** Path to the entry file (e.g., "src/index.tsx") */
|
|
7
7
|
entry: string;
|
|
8
|
+
/**
|
|
9
|
+
* Base path for resolving asset imports at runtime, relative to the
|
|
10
|
+
* executable directory.
|
|
11
|
+
*
|
|
12
|
+
* When set, asset imports resolve to
|
|
13
|
+
* `path.join(path.dirname(process.execPath), assetBase, filename)`.
|
|
14
|
+
* This is useful for FHS-compliant packaging where assets live under
|
|
15
|
+
* a `share/` directory rather than next to the binary.
|
|
16
|
+
*
|
|
17
|
+
* When omitted, assets resolve relative to the bundle via
|
|
18
|
+
* `import.meta.url`, which works when assets are co-located with
|
|
19
|
+
* the executable (e.g., in `bin/assets/`).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* await build({
|
|
24
|
+
* entry: "./src/index.tsx",
|
|
25
|
+
* assetBase: "../share/my-app",
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
assetBase?: string;
|
|
8
30
|
/** Additional Vite configuration */
|
|
9
31
|
vite?: InlineConfig;
|
|
10
32
|
};
|
|
@@ -12,12 +34,9 @@ export type BuildOptions = {
|
|
|
12
34
|
* Builds a GTKX application for production using Vite's SSR build mode.
|
|
13
35
|
*
|
|
14
36
|
* Produces a single minified ESM bundle at `dist/bundle.js` with all
|
|
15
|
-
* dependencies
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* an absolute path at build time. This ensures the bundle works under
|
|
19
|
-
* strict package managers (pnpm) where transitive dependencies are not
|
|
20
|
-
* directly resolvable from the bundle location.
|
|
37
|
+
* dependencies inlined. The native `.node` binary is copied into the
|
|
38
|
+
* output directory as `gtkx.node`, making the bundle fully self-contained
|
|
39
|
+
* with no `node_modules` dependency at runtime.
|
|
21
40
|
*
|
|
22
41
|
* @param options - Build configuration including entry point and Vite options
|
|
23
42
|
*
|
package/dist/builder.js
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
import { join } from "node:path";
|
|
3
1
|
import { build as viteBuild } from "vite";
|
|
4
2
|
import { gtkxAssets } from "./vite-plugin-gtkx-assets.js";
|
|
5
|
-
|
|
3
|
+
import { gtkxBuiltUrl } from "./vite-plugin-gtkx-built-url.js";
|
|
4
|
+
import { gtkxNative } from "./vite-plugin-gtkx-native.js";
|
|
6
5
|
/**
|
|
7
6
|
* Builds a GTKX application for production using Vite's SSR build mode.
|
|
8
7
|
*
|
|
9
8
|
* Produces a single minified ESM bundle at `dist/bundle.js` with all
|
|
10
|
-
* dependencies
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* an absolute path at build time. This ensures the bundle works under
|
|
14
|
-
* strict package managers (pnpm) where transitive dependencies are not
|
|
15
|
-
* directly resolvable from the bundle location.
|
|
9
|
+
* dependencies inlined. The native `.node` binary is copied into the
|
|
10
|
+
* output directory as `gtkx.node`, making the bundle fully self-contained
|
|
11
|
+
* with no `node_modules` dependency at runtime.
|
|
16
12
|
*
|
|
17
13
|
* @param options - Build configuration including entry point and Vite options
|
|
18
14
|
*
|
|
@@ -29,12 +25,11 @@ const NATIVE_PACKAGE_RE = /^@gtkx\/native(-linux-(x64|arm64))?$/;
|
|
|
29
25
|
* @see {@link BuildOptions} for configuration options
|
|
30
26
|
*/
|
|
31
27
|
export const build = async (options) => {
|
|
32
|
-
const { entry, vite: viteConfig } = options;
|
|
28
|
+
const { entry, assetBase, vite: viteConfig } = options;
|
|
33
29
|
const root = viteConfig?.root ?? process.cwd();
|
|
34
|
-
const projectRequire = createRequire(join(root, "package.json"));
|
|
35
30
|
await viteBuild({
|
|
36
31
|
...viteConfig,
|
|
37
|
-
plugins: [...(viteConfig?.plugins ?? []), gtkxAssets()],
|
|
32
|
+
plugins: [...(viteConfig?.plugins ?? []), gtkxAssets(), gtkxBuiltUrl(assetBase), gtkxNative(root)],
|
|
38
33
|
build: {
|
|
39
34
|
...viteConfig?.build,
|
|
40
35
|
ssr: entry,
|
|
@@ -47,17 +42,6 @@ export const build = async (options) => {
|
|
|
47
42
|
output: {
|
|
48
43
|
...(viteConfig?.build?.rollupOptions?.output ?? {}),
|
|
49
44
|
entryFileNames: "bundle.js",
|
|
50
|
-
paths: (id) => {
|
|
51
|
-
if (NATIVE_PACKAGE_RE.test(id)) {
|
|
52
|
-
try {
|
|
53
|
-
return projectRequire.resolve(id);
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return id;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return id;
|
|
60
|
-
},
|
|
61
45
|
},
|
|
62
46
|
},
|
|
63
47
|
},
|
|
@@ -68,17 +52,9 @@ export const build = async (options) => {
|
|
|
68
52
|
ssr: {
|
|
69
53
|
...viteConfig?.ssr,
|
|
70
54
|
noExternal: true,
|
|
71
|
-
external: ["@gtkx/native", "@gtkx/native-linux-x64", "@gtkx/native-linux-arm64"],
|
|
72
55
|
},
|
|
73
56
|
experimental: {
|
|
74
57
|
...viteConfig?.experimental,
|
|
75
|
-
renderBuiltUrl(filename, { type }) {
|
|
76
|
-
if (type === "asset") {
|
|
77
|
-
return {
|
|
78
|
-
runtime: `new URL(${JSON.stringify(`./${filename}`)}, import.meta.url).pathname`,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
58
|
},
|
|
83
59
|
});
|
|
84
60
|
};
|
package/dist/cli.js
CHANGED
|
@@ -61,12 +61,17 @@ const buildCmd = defineCommand({
|
|
|
61
61
|
description: "Entry file (default: src/index.tsx)",
|
|
62
62
|
required: false,
|
|
63
63
|
},
|
|
64
|
+
"asset-base": {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "Asset base path relative to executable directory (e.g., ../share/my-app)",
|
|
67
|
+
},
|
|
64
68
|
},
|
|
65
69
|
async run({ args }) {
|
|
66
70
|
const entry = resolve(process.cwd(), args.entry ?? "src/index.tsx");
|
|
67
71
|
console.log(`[gtkx] Building ${entry}`);
|
|
68
72
|
await build({
|
|
69
73
|
entry,
|
|
74
|
+
assetBase: args["asset-base"],
|
|
70
75
|
vite: {
|
|
71
76
|
root: process.cwd(),
|
|
72
77
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Vite plugin that configures `renderBuiltUrl` for resolving asset imports
|
|
4
|
+
* to filesystem paths at runtime.
|
|
5
|
+
*
|
|
6
|
+
* When `assetBase` is provided, assets resolve relative to the executable
|
|
7
|
+
* directory using `path.join(path.dirname(process.execPath), assetBase, filename)`.
|
|
8
|
+
* This supports FHS-compliant layouts where assets live in `../share/<app>/`.
|
|
9
|
+
*
|
|
10
|
+
* When `assetBase` is omitted, assets resolve relative to the bundle file
|
|
11
|
+
* via `import.meta.url`, which works when assets are co-located with the
|
|
12
|
+
* executable.
|
|
13
|
+
*
|
|
14
|
+
* Only applies when the user has not already configured
|
|
15
|
+
* `experimental.renderBuiltUrl` in their Vite config.
|
|
16
|
+
*/
|
|
17
|
+
export declare function gtkxBuiltUrl(assetBase?: string): Plugin;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite plugin that configures `renderBuiltUrl` for resolving asset imports
|
|
3
|
+
* to filesystem paths at runtime.
|
|
4
|
+
*
|
|
5
|
+
* When `assetBase` is provided, assets resolve relative to the executable
|
|
6
|
+
* directory using `path.join(path.dirname(process.execPath), assetBase, filename)`.
|
|
7
|
+
* This supports FHS-compliant layouts where assets live in `../share/<app>/`.
|
|
8
|
+
*
|
|
9
|
+
* When `assetBase` is omitted, assets resolve relative to the bundle file
|
|
10
|
+
* via `import.meta.url`, which works when assets are co-located with the
|
|
11
|
+
* executable.
|
|
12
|
+
*
|
|
13
|
+
* Only applies when the user has not already configured
|
|
14
|
+
* `experimental.renderBuiltUrl` in their Vite config.
|
|
15
|
+
*/
|
|
16
|
+
export function gtkxBuiltUrl(assetBase) {
|
|
17
|
+
return {
|
|
18
|
+
name: "gtkx:built-url",
|
|
19
|
+
config(userConfig) {
|
|
20
|
+
if (userConfig.experimental?.renderBuiltUrl) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
experimental: {
|
|
25
|
+
renderBuiltUrl(filename, { type }) {
|
|
26
|
+
if (type !== "asset") {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (assetBase) {
|
|
30
|
+
return {
|
|
31
|
+
runtime: `require("path").join(require("path").dirname(process.execPath),${JSON.stringify(assetBase)},${JSON.stringify(filename)})`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
runtime: `new URL(${JSON.stringify(`./${filename}`)}, import.meta.url).pathname`,
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Vite plugin that embeds the native `.node` binary into the build output.
|
|
4
|
+
*
|
|
5
|
+
* During production builds, resolves the platform-specific `.node` binary,
|
|
6
|
+
* copies it into the output directory as `gtkx.node`, and transforms the
|
|
7
|
+
* `loadNativeBinding` function in `@gtkx/native` to load `./gtkx.node`
|
|
8
|
+
* directly. This makes the bundle self-contained with no `node_modules`
|
|
9
|
+
* dependency at runtime.
|
|
10
|
+
*
|
|
11
|
+
* @param root - Project root directory used to resolve native packages
|
|
12
|
+
*/
|
|
13
|
+
export declare function gtkxNative(root: string): Plugin;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { arch, platform } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
const LOAD_NATIVE_BINDING_RE = /function loadNativeBinding\(\) \{[\s\S]*?\n\}/;
|
|
6
|
+
const NODE_OS_IMPORT_RE = /import\s*\{[^}]*\}\s*from\s*["']node:os["'];?\n?/;
|
|
7
|
+
/**
|
|
8
|
+
* Vite plugin that embeds the native `.node` binary into the build output.
|
|
9
|
+
*
|
|
10
|
+
* During production builds, resolves the platform-specific `.node` binary,
|
|
11
|
+
* copies it into the output directory as `gtkx.node`, and transforms the
|
|
12
|
+
* `loadNativeBinding` function in `@gtkx/native` to load `./gtkx.node`
|
|
13
|
+
* directly. This makes the bundle self-contained with no `node_modules`
|
|
14
|
+
* dependency at runtime.
|
|
15
|
+
*
|
|
16
|
+
* @param root - Project root directory used to resolve native packages
|
|
17
|
+
*/
|
|
18
|
+
export function gtkxNative(root) {
|
|
19
|
+
const projectRequire = createRequire(join(root, "package.json"));
|
|
20
|
+
let nativeIndexPath;
|
|
21
|
+
return {
|
|
22
|
+
name: "gtkx:native",
|
|
23
|
+
enforce: "pre",
|
|
24
|
+
buildStart() {
|
|
25
|
+
const currentPlatform = platform();
|
|
26
|
+
const currentArch = arch();
|
|
27
|
+
const packageName = `@gtkx/native-linux-${currentArch}`;
|
|
28
|
+
if (currentPlatform !== "linux") {
|
|
29
|
+
throw new Error(`Unsupported build platform: ${currentPlatform}. Only Linux is supported.`);
|
|
30
|
+
}
|
|
31
|
+
if (currentArch !== "x64" && currentArch !== "arm64") {
|
|
32
|
+
throw new Error(`Unsupported build architecture: ${currentArch}. Only x64 and arm64 are supported.`);
|
|
33
|
+
}
|
|
34
|
+
nativeIndexPath = projectRequire.resolve("@gtkx/native");
|
|
35
|
+
const nodePath = projectRequire.resolve(`${packageName}/index.node`);
|
|
36
|
+
const source = readFileSync(nodePath);
|
|
37
|
+
this.emitFile({
|
|
38
|
+
type: "asset",
|
|
39
|
+
fileName: "gtkx.node",
|
|
40
|
+
source,
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
transform(code, id) {
|
|
44
|
+
if (id !== nativeIndexPath) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
return code
|
|
48
|
+
.replace(NODE_OS_IMPORT_RE, "")
|
|
49
|
+
.replace(LOAD_NATIVE_BINDING_RE, 'function loadNativeBinding() { return require("./gtkx.node"); }');
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/cli",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "CLI for GTKX - create and develop GTK4 React applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -62,19 +62,19 @@
|
|
|
62
62
|
"ejs": "^4.0.1",
|
|
63
63
|
"react-refresh": "^0.18.0",
|
|
64
64
|
"vite": "^7.3.1",
|
|
65
|
-
"@gtkx/ffi": "0.18.
|
|
66
|
-
"@gtkx/mcp": "0.18.
|
|
67
|
-
"@gtkx/react": "0.18.
|
|
65
|
+
"@gtkx/ffi": "0.18.1",
|
|
66
|
+
"@gtkx/mcp": "0.18.1",
|
|
67
|
+
"@gtkx/react": "0.18.1"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/ejs": "^3.1.5",
|
|
71
71
|
"@types/react-refresh": "^0.14.7",
|
|
72
72
|
"memfs": "^4.56.10",
|
|
73
|
-
"@gtkx/testing": "0.18.
|
|
73
|
+
"@gtkx/testing": "0.18.1"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"react": "^19",
|
|
77
|
-
"@gtkx/testing": "0.18.
|
|
77
|
+
"@gtkx/testing": "0.18.1"
|
|
78
78
|
},
|
|
79
79
|
"peerDependenciesMeta": {
|
|
80
80
|
"@gtkx/testing": {
|