@gtkx/cli 1.0.0-rc.1 → 1.0.0-rc.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.
- package/dist/builder.d.ts +3 -2
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -1
- package/dist/builder.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +21 -6
- package/dist/cli.js.map +1 -1
- package/dist/codegen/freshness.d.ts +5 -5
- package/dist/codegen/freshness.d.ts.map +1 -1
- package/dist/codegen/freshness.js +26 -23
- package/dist/codegen/freshness.js.map +1 -1
- package/dist/codegen/report.d.ts +2 -1
- package/dist/codegen/report.d.ts.map +1 -1
- package/dist/codegen/report.js +4 -2
- package/dist/codegen/report.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +8 -8
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +72 -43
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +8 -5
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +26 -6
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts +4 -3
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +2 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts +2 -1
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +6 -4
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +2 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts +2 -1
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +22 -7
- package/dist/commands/docs.js.map +1 -1
- package/dist/dev/icon-dir.d.ts +2 -1
- package/dist/dev/icon-dir.d.ts.map +1 -1
- package/dist/dev/icon-dir.js +6 -3
- package/dist/dev/icon-dir.js.map +1 -1
- package/dist/dev/refresh-tracker.d.ts +5 -4
- package/dist/dev/refresh-tracker.d.ts.map +1 -1
- package/dist/dev/refresh-tracker.js +6 -5
- package/dist/dev/refresh-tracker.js.map +1 -1
- package/dist/dev/runner-deps.d.ts +2 -1
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +20 -4
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.d.ts +2 -1
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +3 -2
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/runner.d.ts +6 -5
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +69 -38
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/schema-dir.d.ts +2 -1
- package/dist/dev/schema-dir.d.ts.map +1 -1
- package/dist/dev/schema-dir.js +4 -2
- package/dist/dev/schema-dir.js.map +1 -1
- package/dist/dev/supervisor.d.ts +7 -6
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +107 -67
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/dev/vite-dev-server.d.ts +3 -3
- package/dist/dev/vite-dev-server.d.ts.map +1 -1
- package/dist/dev/vite-dev-server.js +2 -1
- package/dist/dev/vite-dev-server.js.map +1 -1
- package/dist/internal/banner.d.ts +2 -1
- package/dist/internal/banner.d.ts.map +1 -1
- package/dist/internal/banner.js +2 -1
- package/dist/internal/banner.js.map +1 -1
- package/dist/internal/data-dir.d.ts +3 -2
- package/dist/internal/data-dir.d.ts.map +1 -1
- package/dist/internal/data-dir.js +29 -14
- package/dist/internal/data-dir.js.map +1 -1
- package/dist/internal/entry-arg.d.ts +5 -4
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +10 -7
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/errors.d.ts +3 -2
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +7 -5
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/list-files.d.ts +3 -2
- package/dist/internal/list-files.d.ts.map +1 -1
- package/dist/internal/list-files.js +5 -3
- package/dist/internal/list-files.js.map +1 -1
- package/dist/internal/resolve-cli-tool.d.ts +2 -1
- package/dist/internal/resolve-cli-tool.d.ts.map +1 -1
- package/dist/internal/resolve-cli-tool.js +17 -10
- package/dist/internal/resolve-cli-tool.js.map +1 -1
- package/dist/internal/staging-dir.d.ts +3 -2
- package/dist/internal/staging-dir.d.ts.map +1 -1
- package/dist/internal/staging-dir.js +3 -2
- package/dist/internal/staging-dir.js.map +1 -1
- package/dist/internal/xdg-data-dirs.d.ts +2 -1
- package/dist/internal/xdg-data-dirs.d.ts.map +1 -1
- package/dist/internal/xdg-data-dirs.js +4 -2
- package/dist/internal/xdg-data-dirs.js.map +1 -1
- package/dist/mcp/client.d.ts +9 -4
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +106 -81
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/handlers.d.ts +3 -2
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +89 -61
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +30 -13
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/serialize-widget.d.ts +3 -3
- package/dist/mcp/serialize-widget.d.ts.map +1 -1
- package/dist/mcp/serialize-widget.js +9 -6
- package/dist/mcp/serialize-widget.js.map +1 -1
- package/dist/mcp/testing-loader.d.ts +3 -4
- package/dist/mcp/testing-loader.d.ts.map +1 -1
- package/dist/mcp/testing-loader.js +43 -21
- package/dist/mcp/testing-loader.js.map +1 -1
- package/dist/mcp/widget-registry.d.ts +3 -2
- package/dist/mcp/widget-registry.d.ts.map +1 -1
- package/dist/mcp/widget-registry.js +4 -3
- package/dist/mcp/widget-registry.js.map +1 -1
- package/dist/refresh-globals.d.ts +2 -0
- package/dist/refresh-globals.d.ts.map +1 -0
- package/dist/refresh-globals.js +8 -0
- package/dist/refresh-globals.js.map +1 -0
- package/dist/refresh-runtime.d.ts +5 -11
- package/dist/refresh-runtime.d.ts.map +1 -1
- package/dist/refresh-runtime.js +16 -14
- package/dist/refresh-runtime.js.map +1 -1
- package/dist/settings/compile.d.ts +2 -1
- package/dist/settings/compile.d.ts.map +1 -1
- package/dist/settings/compile.js +6 -4
- package/dist/settings/compile.js.map +1 -1
- package/dist/settings/parser.d.ts +6 -5
- package/dist/settings/parser.d.ts.map +1 -1
- package/dist/settings/parser.js +26 -22
- package/dist/settings/parser.js.map +1 -1
- package/dist/settings/render.d.ts +3 -2
- package/dist/settings/render.d.ts.map +1 -1
- package/dist/settings/render.js +38 -64
- package/dist/settings/render.js.map +1 -1
- package/dist/settings/schema.d.ts +8 -8
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +61 -43
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-extensions.d.ts +4 -3
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
- package/dist/vite-plugins/asset-extensions.js +4 -3
- package/dist/vite-plugins/asset-extensions.js.map +1 -1
- package/dist/vite-plugins/built-url.d.ts +2 -1
- package/dist/vite-plugins/built-url.d.ts.map +1 -1
- package/dist/vite-plugins/built-url.js +19 -13
- package/dist/vite-plugins/built-url.js.map +1 -1
- package/dist/vite-plugins/css.d.ts +2 -1
- package/dist/vite-plugins/css.d.ts.map +1 -1
- package/dist/vite-plugins/css.js +23 -15
- package/dist/vite-plugins/css.js.map +1 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +5 -4
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.js +11 -7
- package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +4 -3
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.js +45 -41
- package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
- package/dist/vite-plugins/icons.d.ts +2 -1
- package/dist/vite-plugins/icons.d.ts.map +1 -1
- package/dist/vite-plugins/icons.js +24 -20
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +2 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +3 -2
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/native.d.ts +2 -1
- package/dist/vite-plugins/native.d.ts.map +1 -1
- package/dist/vite-plugins/native.js +6 -4
- package/dist/vite-plugins/native.js.map +1 -1
- package/dist/vite-plugins/react-compiler.d.ts +3 -2
- package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
- package/dist/vite-plugins/react-compiler.js +26 -20
- package/dist/vite-plugins/react-compiler.js.map +1 -1
- package/dist/vite-plugins/react-dom-prebundle.d.ts +2 -1
- package/dist/vite-plugins/react-dom-prebundle.d.ts.map +1 -1
- package/dist/vite-plugins/react-dom-prebundle.js +2 -1
- package/dist/vite-plugins/react-dom-prebundle.js.map +1 -1
- package/dist/vite-plugins/resource-init-module.d.ts +2 -1
- package/dist/vite-plugins/resource-init-module.d.ts.map +1 -1
- package/dist/vite-plugins/resource-init-module.js +39 -38
- package/dist/vite-plugins/resource-init-module.js.map +1 -1
- package/dist/vite-plugins/resource-shared.d.ts +7 -5
- package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
- package/dist/vite-plugins/resource-shared.js +17 -10
- package/dist/vite-plugins/resource-shared.js.map +1 -1
- package/dist/vite-plugins/resources.d.ts +3 -2
- package/dist/vite-plugins/resources.d.ts.map +1 -1
- package/dist/vite-plugins/resources.js +94 -54
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts +2 -1
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +4 -2
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vite-plugins/settings.d.ts +2 -1
- package/dist/vite-plugins/settings.d.ts.map +1 -1
- package/dist/vite-plugins/settings.js +56 -32
- package/dist/vite-plugins/settings.js.map +1 -1
- package/dist/vite-plugins/strip-query.d.ts +3 -0
- package/dist/vite-plugins/strip-query.d.ts.map +1 -0
- package/dist/vite-plugins/strip-query.js +6 -0
- package/dist/vite-plugins/strip-query.js.map +1 -0
- package/dist/vite-plugins/undeclared-library.d.ts +2 -1
- package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
- package/dist/vite-plugins/undeclared-library.js +8 -5
- package/dist/vite-plugins/undeclared-library.js.map +1 -1
- package/dist/vite-plugins/virtual-module.d.ts +2 -2
- package/dist/vite-plugins/virtual-module.d.ts.map +1 -1
- package/dist/vite-plugins/virtual-module.js +5 -3
- package/dist/vite-plugins/virtual-module.js.map +1 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js.map +1 -1
- package/env.d.ts +21 -61
- package/package.json +12 -14
- package/src/babel-modules.d.ts +0 -2
- package/src/builder.ts +7 -6
- package/src/cli.ts +26 -6
- package/src/codegen/freshness.ts +38 -25
- package/src/codegen/report.ts +10 -2
- package/src/codegen/run-codegen.ts +135 -60
- package/src/codegen/store-resolver.ts +56 -15
- package/src/commands/build.ts +3 -2
- package/src/commands/codegen.ts +9 -4
- package/src/commands/dev.ts +3 -4
- package/src/commands/docs.ts +36 -7
- package/src/dev/icon-dir.ts +13 -3
- package/src/dev/refresh-tracker.ts +12 -8
- package/src/dev/runner-deps.ts +30 -7
- package/src/dev/runner-main.ts +4 -3
- package/src/dev/runner.ts +100 -41
- package/src/dev/schema-dir.ts +7 -2
- package/src/dev/supervisor.ts +169 -71
- package/src/dev/vite-dev-server.ts +4 -2
- package/src/internal/banner.ts +5 -1
- package/src/internal/data-dir.ts +47 -16
- package/src/internal/entry-arg.ts +16 -8
- package/src/internal/errors.ts +15 -7
- package/src/internal/list-files.ts +10 -4
- package/src/internal/resolve-cli-tool.ts +28 -12
- package/src/internal/staging-dir.ts +5 -2
- package/src/internal/xdg-data-dirs.ts +8 -2
- package/src/mcp/client.ts +143 -85
- package/src/mcp/handlers.ts +126 -69
- package/src/mcp/index.ts +38 -14
- package/src/mcp/serialize-widget.ts +15 -8
- package/src/mcp/testing-loader.ts +64 -23
- package/src/mcp/widget-registry.ts +11 -5
- package/src/refresh-globals.ts +10 -0
- package/src/refresh-runtime.ts +20 -16
- package/src/settings/compile.ts +7 -4
- package/src/settings/parser.ts +69 -30
- package/src/settings/render.ts +66 -66
- package/src/settings/schema.ts +100 -46
- package/src/vite-plugins/asset-extensions.ts +4 -3
- package/src/vite-plugins/built-url.ts +30 -15
- package/src/vite-plugins/css.ts +35 -20
- package/src/vite-plugins/fast-refresh/refresh-filter.ts +18 -10
- package/src/vite-plugins/fast-refresh/swc-refresh.ts +60 -47
- package/src/vite-plugins/icons.ts +40 -24
- package/src/vite-plugins/index.ts +6 -3
- package/src/vite-plugins/native.ts +14 -5
- package/src/vite-plugins/react-compiler.ts +44 -30
- package/src/vite-plugins/react-dom-prebundle.ts +4 -1
- package/src/vite-plugins/resource-init-module.ts +41 -38
- package/src/vite-plugins/resource-shared.ts +27 -14
- package/src/vite-plugins/resources.ts +153 -59
- package/src/vite-plugins/settings-worker-env.ts +7 -2
- package/src/vite-plugins/settings.ts +107 -42
- package/src/vite-plugins/strip-query.ts +7 -0
- package/src/vite-plugins/undeclared-library.ts +21 -12
- package/src/vite-plugins/virtual-module.ts +9 -2
- package/src/vitest-plugin.ts +1 -2
|
@@ -1,54 +1,57 @@
|
|
|
1
|
-
import { BUNDLE_FILENAME } from "./resource-shared.js";
|
|
1
|
+
import { BUNDLE_FILENAME, REFRESH_EXPORT } from "./resource-shared.js";
|
|
2
2
|
|
|
3
3
|
const buildInitModuleSource = (): string =>
|
|
4
4
|
[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`const resource =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`export function
|
|
5
|
+
"import { dirname, join } from \"node:path\";",
|
|
6
|
+
"import { fileURLToPath } from \"node:url\";",
|
|
7
|
+
"import { Resource, resourcesRegister } from \"@gtkx/gi/gio\";",
|
|
8
|
+
"",
|
|
9
|
+
"const bundleDir = dirname(fileURLToPath(import.meta.url));",
|
|
10
|
+
`const resource = Resource.load(join(bundleDir, ${JSON.stringify(BUNDLE_FILENAME)}));`,
|
|
11
|
+
"resourcesRegister(resource);",
|
|
12
|
+
"",
|
|
13
|
+
"export function ensureRegistered() {}",
|
|
14
|
+
`export function ${REFRESH_EXPORT}() {}`,
|
|
15
15
|
].join("\n");
|
|
16
16
|
|
|
17
17
|
const devInitModuleSource = (bundlePath: string): string => {
|
|
18
18
|
const bundlePathLiteral = JSON.stringify(bundlePath);
|
|
19
|
+
|
|
19
20
|
return [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
` const next =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
"import { existsSync, statSync } from \"node:fs\";",
|
|
22
|
+
"import { Resource, resourcesRegister, resourcesUnregister } from \"@gtkx/gi/gio\";",
|
|
23
|
+
"",
|
|
24
|
+
"let current = null;",
|
|
25
|
+
"let lastSig = \"\";",
|
|
26
|
+
"",
|
|
27
|
+
"function register() {",
|
|
28
|
+
` const next = Resource.load(${bundlePathLiteral});`,
|
|
29
|
+
" if (current) resourcesUnregister(current);",
|
|
30
|
+
" resourcesRegister(next);",
|
|
31
|
+
" current = next;",
|
|
32
|
+
"}",
|
|
33
|
+
"",
|
|
34
|
+
"export function ensureRegistered() {",
|
|
34
35
|
` if (!existsSync(${bundlePathLiteral})) return;`,
|
|
35
36
|
` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`export function
|
|
37
|
+
" const sig = size + \":\" + mtimeMs;",
|
|
38
|
+
" if (sig === lastSig) return;",
|
|
39
|
+
" register();",
|
|
40
|
+
" lastSig = sig;",
|
|
41
|
+
"}",
|
|
42
|
+
"",
|
|
43
|
+
"ensureRegistered();",
|
|
44
|
+
"",
|
|
45
|
+
`export function ${REFRESH_EXPORT}() {`,
|
|
45
46
|
` if (!existsSync(${bundlePathLiteral})) return;`,
|
|
46
|
-
|
|
47
|
+
" register();",
|
|
47
48
|
` const { size, mtimeMs } = statSync(${bundlePathLiteral});`,
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
" lastSig = size + \":\" + mtimeMs;",
|
|
50
|
+
"}",
|
|
50
51
|
].join("\n");
|
|
51
52
|
};
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
const renderInitModule = (options: { isBuild: boolean; devBundlePath: string }): string =>
|
|
54
55
|
options.isBuild ? buildInitModuleSource() : devInitModuleSource(options.devBundlePath);
|
|
56
|
+
|
|
57
|
+
export { renderInitModule };
|
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import { createVirtualNamespace } from "./virtual-module.js";
|
|
2
2
|
|
|
3
3
|
const VIRTUAL_PREFIX = "\0gtkx-resources:";
|
|
4
|
+
const VIRTUAL_INIT = "\0gtkx-resources-init";
|
|
5
|
+
const BUNDLE_FILENAME = "gtkx.gresource";
|
|
6
|
+
const REL_SEPARATOR = "\0rel=";
|
|
7
|
+
const REFRESH_EXPORT = "__refresh";
|
|
8
|
+
const { isVirtual, toVirtualId, fromVirtualId } = createVirtualNamespace(VIRTUAL_PREFIX);
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const BUNDLE_FILENAME = "gtkx.gresource";
|
|
8
|
-
|
|
9
|
-
export const REL_SEPARATOR = "\0rel=";
|
|
10
|
-
|
|
11
|
-
export const { isVirtual, toVirtualId, fromVirtualId } = createVirtualNamespace(VIRTUAL_PREFIX);
|
|
12
|
-
|
|
13
|
-
export const escapeXml = (value: string): string =>
|
|
10
|
+
const escapeXml = (value: string): string =>
|
|
14
11
|
value.replaceAll(/[<>&"']/g, (char) => {
|
|
15
12
|
switch (char) {
|
|
16
|
-
case "<":
|
|
13
|
+
case "<": {
|
|
17
14
|
return "<";
|
|
18
|
-
|
|
15
|
+
}
|
|
16
|
+
case ">": {
|
|
19
17
|
return ">";
|
|
20
|
-
|
|
18
|
+
}
|
|
19
|
+
case "&": {
|
|
21
20
|
return "&";
|
|
22
|
-
|
|
21
|
+
}
|
|
22
|
+
case "\"": {
|
|
23
23
|
return """;
|
|
24
|
-
|
|
24
|
+
}
|
|
25
|
+
default: {
|
|
25
26
|
return "'";
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
29
|
});
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
VIRTUAL_INIT,
|
|
33
|
+
BUNDLE_FILENAME,
|
|
34
|
+
REL_SEPARATOR,
|
|
35
|
+
REFRESH_EXPORT,
|
|
36
|
+
escapeXml,
|
|
37
|
+
isVirtual,
|
|
38
|
+
toVirtualId,
|
|
39
|
+
fromVirtualId,
|
|
40
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type { Plugin, ResolvedConfig, UserConfig, ViteDevServer } from "vite";
|
|
2
|
+
import { type ConfigLoader, createConfigLoader } from "@gtkx/config/internal";
|
|
3
|
+
import { error, formatChildProcessError, info, sortStrings } from "@gtkx/utils";
|
|
1
4
|
import { execFileSync } from "node:child_process";
|
|
2
5
|
import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
6
|
import { tmpdir } from "node:os";
|
|
4
7
|
import { dirname, join } from "node:path";
|
|
5
|
-
import { type ConfigLoader, createConfigLoader } from "@gtkx/config/internal";
|
|
6
|
-
import { error, formatChildProcessError, info } from "@gtkx/utils";
|
|
7
|
-
import type { Plugin, ResolvedConfig, UserConfig, ViteDevServer } from "vite";
|
|
8
8
|
import { DATA_IMPORT_PREFIX, resolveDataDir } from "../internal/data-dir.js";
|
|
9
9
|
import { type ListedFile, listFilesRecursive } from "../internal/list-files.js";
|
|
10
10
|
import { resolveCliTool } from "../internal/resolve-cli-tool.js";
|
|
@@ -16,22 +16,12 @@ import {
|
|
|
16
16
|
escapeXml,
|
|
17
17
|
fromVirtualId,
|
|
18
18
|
isVirtual,
|
|
19
|
+
REFRESH_EXPORT,
|
|
19
20
|
REL_SEPARATOR,
|
|
20
21
|
toVirtualId,
|
|
21
22
|
VIRTUAL_INIT,
|
|
22
23
|
} from "./resource-shared.js";
|
|
23
|
-
|
|
24
|
-
const DATA_PREFIX = `${DATA_IMPORT_PREFIX}/`;
|
|
25
|
-
|
|
26
|
-
const RESOURCE_COMPILER = "glib-compile-resources";
|
|
27
|
-
const MANIFEST_PREFIX = "/";
|
|
28
|
-
|
|
29
|
-
const deriveResourcePrefix = (applicationId: string): string => `/${applicationId.replaceAll(".", "/")}`;
|
|
30
|
-
|
|
31
|
-
const stripQuery = (source: string): string => {
|
|
32
|
-
const queryIndex = source.indexOf("?");
|
|
33
|
-
return queryIndex === -1 ? source : source.slice(0, queryIndex);
|
|
34
|
-
};
|
|
24
|
+
import { stripQuery } from "./strip-query.js";
|
|
35
25
|
|
|
36
26
|
type ResourceEntry = {
|
|
37
27
|
sourcePath: string;
|
|
@@ -51,32 +41,44 @@ type PluginState = {
|
|
|
51
41
|
dataDir: string | null;
|
|
52
42
|
};
|
|
53
43
|
|
|
44
|
+
const DATA_PREFIX = `${DATA_IMPORT_PREFIX}/`;
|
|
45
|
+
const RESOURCE_COMPILER = "glib-compile-resources";
|
|
46
|
+
const MANIFEST_PREFIX = "/";
|
|
47
|
+
|
|
48
|
+
const deriveResourcePrefix = (applicationId: string): string => `/${applicationId.replaceAll(".", "/")}`;
|
|
49
|
+
|
|
54
50
|
const compileBundle = (state: PluginState, outputPath: string): Buffer =>
|
|
55
51
|
withStagingDir("resources", (dir) => {
|
|
56
52
|
const manifest = stageBundle(dir, state.entries);
|
|
53
|
+
|
|
57
54
|
return runCompiler(dir, manifest, outputPath);
|
|
58
55
|
});
|
|
59
56
|
|
|
60
57
|
const stageBundle = (dir: string, entries: Map<string, ResourceEntry>): string => {
|
|
61
58
|
const fileNodes: string[] = [];
|
|
59
|
+
|
|
62
60
|
for (const entry of entries.values()) {
|
|
63
61
|
const targetPath = join(dir, entry.stagedRelPath);
|
|
64
62
|
mkdirSync(dirname(targetPath), { recursive: true });
|
|
65
63
|
copyFileSync(entry.sourcePath, targetPath);
|
|
66
64
|
fileNodes.push(` <file>${escapeXml(entry.stagedRelPath)}</file>`);
|
|
67
65
|
}
|
|
66
|
+
|
|
68
67
|
const prefix = escapeXml(MANIFEST_PREFIX);
|
|
69
68
|
const manifest = join(dir, "gtkx.gresource.xml");
|
|
69
|
+
|
|
70
70
|
const xml = [
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
|
|
72
|
+
"<gresources>",
|
|
73
73
|
` <gresource prefix="${prefix}">`,
|
|
74
74
|
...fileNodes,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
" </gresource>",
|
|
76
|
+
"</gresources>",
|
|
77
|
+
"",
|
|
78
78
|
].join("\n");
|
|
79
|
+
|
|
79
80
|
writeFileSync(manifest, xml);
|
|
81
|
+
|
|
80
82
|
return manifest;
|
|
81
83
|
};
|
|
82
84
|
|
|
@@ -89,42 +91,63 @@ const runCompiler = (sourceDir: string, manifest: string, outputPath: string): B
|
|
|
89
91
|
]);
|
|
90
92
|
} catch (error) {
|
|
91
93
|
const details = formatChildProcessError(error);
|
|
92
|
-
|
|
94
|
+
const suffix = details ? `:\n${details}` : "";
|
|
95
|
+
throw new Error(`${RESOURCE_COMPILER} failed${suffix}`, { cause: error });
|
|
93
96
|
}
|
|
97
|
+
|
|
94
98
|
return readFileSync(outputPath);
|
|
95
99
|
};
|
|
96
100
|
|
|
97
101
|
const ensureStagingDir = (state: PluginState): void => {
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
state.devBundlePath = join(state.devStagingDir, BUNDLE_FILENAME);
|
|
102
|
+
if (state.devStagingDir) {
|
|
103
|
+
return;
|
|
101
104
|
}
|
|
105
|
+
|
|
106
|
+
state.devStagingDir = mkdtempSync(join(tmpdir(), "gtkx-resources-dev-"));
|
|
107
|
+
state.devBundlePath = join(state.devStagingDir, BUNDLE_FILENAME);
|
|
102
108
|
};
|
|
103
109
|
|
|
104
|
-
const entriesSignature = (state: PluginState): string =>
|
|
105
|
-
[...state.entries.keys()].sort((a, b) => a.localeCompare(b)).join("\0");
|
|
110
|
+
const entriesSignature = (state: PluginState): string => sortStrings(state.entries.keys()).join("\0");
|
|
106
111
|
|
|
107
112
|
const compileDevBundle = (state: PluginState): void => {
|
|
108
113
|
ensureStagingDir(state);
|
|
109
|
-
|
|
114
|
+
|
|
115
|
+
if (state.entries.size === 0) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
110
119
|
compileBundle(state, state.devBundlePath);
|
|
111
120
|
state.compiledSignature = entriesSignature(state);
|
|
112
121
|
};
|
|
113
122
|
|
|
123
|
+
const isRefreshHook = (value: unknown): value is () => void => typeof value === "function";
|
|
124
|
+
|
|
114
125
|
const reregisterDevBundle = async (state: PluginState): Promise<void> => {
|
|
115
126
|
const server = state.server;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
127
|
+
|
|
128
|
+
if (!server) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const mod = await server.ssrLoadModule(VIRTUAL_INIT);
|
|
133
|
+
const refresh: unknown = mod[REFRESH_EXPORT];
|
|
134
|
+
|
|
135
|
+
if (isRefreshHook(refresh)) {
|
|
136
|
+
refresh();
|
|
137
|
+
}
|
|
119
138
|
};
|
|
120
139
|
|
|
121
140
|
const scanDataAssets = (dataDir: string): ListedFile[] => listFilesRecursive(dataDir, (name) => ASSET_RE.test(name));
|
|
122
141
|
|
|
123
142
|
const primeDevBundle = (state: PluginState): void => {
|
|
124
|
-
if (state.dataDir === null)
|
|
143
|
+
if (state.dataDir === null) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
125
147
|
for (const { absPath, rel } of scanDataAssets(state.dataDir)) {
|
|
126
148
|
registerEntry(state, absPath, rel);
|
|
127
149
|
}
|
|
150
|
+
|
|
128
151
|
compileDevBundle(state);
|
|
129
152
|
};
|
|
130
153
|
|
|
@@ -136,21 +159,56 @@ const registerDevAsset = (state: PluginState): void => {
|
|
|
136
159
|
|
|
137
160
|
const registerEntry = (state: PluginState, absPath: string, rel: string): ResourceEntry => {
|
|
138
161
|
const existing = state.entries.get(absPath);
|
|
139
|
-
|
|
162
|
+
|
|
163
|
+
if (existing) {
|
|
164
|
+
return existing;
|
|
165
|
+
}
|
|
140
166
|
|
|
141
167
|
const resourcePath = `${state.prefix}/${rel}`;
|
|
168
|
+
|
|
142
169
|
const entry: ResourceEntry = {
|
|
143
170
|
sourcePath: absPath,
|
|
144
171
|
stagedRelPath: resourcePath.replace(/^\/+/, ""),
|
|
145
172
|
resourcePath,
|
|
146
173
|
};
|
|
174
|
+
|
|
147
175
|
state.entries.set(absPath, entry);
|
|
148
176
|
state.sourcePaths.add(absPath);
|
|
177
|
+
|
|
149
178
|
return entry;
|
|
150
179
|
};
|
|
151
180
|
|
|
152
181
|
const isTrackedSource = (state: PluginState, file: string): boolean => state.sourcePaths.has(file);
|
|
153
182
|
|
|
183
|
+
const dataAssetSource = (source: string): string | null => {
|
|
184
|
+
const clean = stripQuery(source);
|
|
185
|
+
|
|
186
|
+
if (!clean.startsWith(DATA_PREFIX) || !ASSET_PATH_RE.test(clean)) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return clean;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const resolvedAssetId = (
|
|
194
|
+
resolved: { id: string; external: boolean | string } | null,
|
|
195
|
+
clean: string,
|
|
196
|
+
): string | undefined => {
|
|
197
|
+
if (!resolved || resolved.external) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return toVirtualId(resolved.id) + REL_SEPARATOR + clean.slice(DATA_PREFIX.length);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const loadInitModule = (state: PluginState): string => {
|
|
205
|
+
if (!state.isBuild) {
|
|
206
|
+
ensureStagingDir(state);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return renderInitModule({ isBuild: state.isBuild, devBundlePath: state.devBundlePath });
|
|
210
|
+
};
|
|
211
|
+
|
|
154
212
|
const loadAssetModule = (state: PluginState, virtualId: string): string => {
|
|
155
213
|
const rest = fromVirtualId(virtualId);
|
|
156
214
|
const separatorIndex = rest.indexOf(REL_SEPARATOR);
|
|
@@ -165,7 +223,7 @@ const loadAssetModule = (state: PluginState, virtualId: string): string => {
|
|
|
165
223
|
|
|
166
224
|
return [
|
|
167
225
|
`import { ensureRegistered } from ${JSON.stringify(VIRTUAL_INIT)};`,
|
|
168
|
-
|
|
226
|
+
"ensureRegistered();",
|
|
169
227
|
`export default ${JSON.stringify(uri)};`,
|
|
170
228
|
`export const path = ${JSON.stringify(entry.resourcePath)};`,
|
|
171
229
|
].join("\n");
|
|
@@ -175,42 +233,81 @@ const emitBuildBundle = (
|
|
|
175
233
|
ctx: { emitFile: (asset: { type: "asset"; fileName: string; source: Buffer }) => string },
|
|
176
234
|
state: PluginState,
|
|
177
235
|
): void => {
|
|
178
|
-
if (!state.isBuild || state.entries.size === 0)
|
|
236
|
+
if (!state.isBuild || state.entries.size === 0) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
179
240
|
const compiled = withStagingDir("resources-out", (outDir) => compileBundle(state, join(outDir, BUNDLE_FILENAME)));
|
|
180
241
|
ctx.emitFile({ type: "asset", fileName: BUNDLE_FILENAME, source: compiled });
|
|
181
|
-
info(`Compiled ${state.entries.size} resource(s) into ${BUNDLE_FILENAME}`);
|
|
242
|
+
info(`Compiled ${String(state.entries.size)} resource(s) into ${BUNDLE_FILENAME}`);
|
|
182
243
|
};
|
|
183
244
|
|
|
184
245
|
const refreshDevRegistration = async (state: PluginState): Promise<void> => {
|
|
185
246
|
compileDevBundle(state);
|
|
247
|
+
|
|
186
248
|
try {
|
|
187
249
|
await reregisterDevBundle(state);
|
|
188
|
-
} catch (
|
|
189
|
-
error("Failed to refresh GResource bundle:",
|
|
250
|
+
} catch (error_) {
|
|
251
|
+
error("Failed to refresh GResource bundle:", error_);
|
|
190
252
|
}
|
|
191
253
|
};
|
|
192
254
|
|
|
193
255
|
const resolveResourceConfig = async (state: PluginState, config: UserConfig, loadConfig: ConfigLoader) => {
|
|
194
256
|
const { applicationId } = await loadConfig(config.root ?? process.cwd());
|
|
195
257
|
state.prefix = deriveResourcePrefix(applicationId);
|
|
258
|
+
|
|
196
259
|
return {
|
|
197
260
|
assetsInclude: [ASSET_RE],
|
|
198
261
|
};
|
|
199
262
|
};
|
|
200
263
|
|
|
264
|
+
const refreshTrackedSource = async (state: PluginState, file: string): Promise<void> => {
|
|
265
|
+
if (!isTrackedSource(state, file)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await refreshDevRegistration(state);
|
|
271
|
+
} catch (error_) {
|
|
272
|
+
error("GResource refresh failed:", error_);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
201
276
|
const attachResourceWatcher = (state: PluginState, server: ViteDevServer): void => {
|
|
202
277
|
state.server = server;
|
|
278
|
+
|
|
203
279
|
const onFileEvent = (file: string): void => {
|
|
204
|
-
|
|
205
|
-
refreshDevRegistration(state).catch((cause) => {
|
|
206
|
-
error("GResource refresh failed:", cause);
|
|
207
|
-
});
|
|
280
|
+
void refreshTrackedSource(state, file);
|
|
208
281
|
};
|
|
282
|
+
|
|
209
283
|
server.watcher.on("change", onFileEvent);
|
|
210
284
|
server.watcher.on("add", onFileEvent);
|
|
211
285
|
};
|
|
212
286
|
|
|
213
|
-
|
|
287
|
+
const applyResolvedConfig = (state: PluginState, config: ResolvedConfig): void => {
|
|
288
|
+
state.isBuild = config.command === "build";
|
|
289
|
+
|
|
290
|
+
if (state.isBuild) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const relativeDataDir = resolveDataDir(config.root);
|
|
295
|
+
state.dataDir = relativeDataDir === null ? null : join(config.root, relativeDataDir);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const loadResourceModule = (state: PluginState, id: string): string | undefined => {
|
|
299
|
+
if (id === VIRTUAL_INIT) {
|
|
300
|
+
return loadInitModule(state);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!isVirtual(id)) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return loadAssetModule(state, id);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
|
|
214
311
|
const state: PluginState = {
|
|
215
312
|
prefix: "",
|
|
216
313
|
isBuild: false,
|
|
@@ -232,11 +329,7 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
|
|
|
232
329
|
},
|
|
233
330
|
|
|
234
331
|
configResolved(config: ResolvedConfig) {
|
|
235
|
-
state
|
|
236
|
-
if (!state.isBuild) {
|
|
237
|
-
const relativeDataDir = resolveDataDir(config.root);
|
|
238
|
-
state.dataDir = relativeDataDir === null ? null : join(config.root, relativeDataDir);
|
|
239
|
-
}
|
|
332
|
+
applyResolvedConfig(state, config);
|
|
240
333
|
},
|
|
241
334
|
|
|
242
335
|
configureServer(server) {
|
|
@@ -245,24 +338,23 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
|
|
|
245
338
|
},
|
|
246
339
|
|
|
247
340
|
async resolveId(source, importer, opts) {
|
|
248
|
-
if (source === VIRTUAL_INIT)
|
|
249
|
-
|
|
250
|
-
|
|
341
|
+
if (source === VIRTUAL_INIT) {
|
|
342
|
+
return VIRTUAL_INIT;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const clean = dataAssetSource(source);
|
|
346
|
+
|
|
347
|
+
if (clean === null) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
251
350
|
|
|
252
351
|
const resolved = await this.resolve(clean, importer, { ...opts, skipSelf: true });
|
|
253
|
-
if (!resolved || resolved.external) return;
|
|
254
352
|
|
|
255
|
-
|
|
256
|
-
return toVirtualId(resolved.id) + REL_SEPARATOR + rel;
|
|
353
|
+
return resolvedAssetId(resolved, clean);
|
|
257
354
|
},
|
|
258
355
|
|
|
259
356
|
load(id) {
|
|
260
|
-
|
|
261
|
-
if (!state.isBuild) ensureStagingDir(state);
|
|
262
|
-
return renderInitModule({ isBuild: state.isBuild, devBundlePath: state.devBundlePath });
|
|
263
|
-
}
|
|
264
|
-
if (!isVirtual(id)) return;
|
|
265
|
-
return loadAssetModule(state, id);
|
|
357
|
+
return loadResourceModule(state, id);
|
|
266
358
|
},
|
|
267
359
|
|
|
268
360
|
buildEnd() {
|
|
@@ -270,3 +362,5 @@ export function gtkxResources(loadConfig: ConfigLoader = createConfigLoader()):
|
|
|
270
362
|
},
|
|
271
363
|
};
|
|
272
364
|
}
|
|
365
|
+
|
|
366
|
+
export { gtkxResources };
|
|
@@ -3,7 +3,7 @@ import type { Plugin } from "vitest/config";
|
|
|
3
3
|
import { resolveDataDir } from "../internal/data-dir.js";
|
|
4
4
|
import { prependSchemaDir, stageAndCompileProjectSchemas } from "../settings/schema.js";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
function gtkxSettingsWorkerEnv(): Plugin {
|
|
7
7
|
return {
|
|
8
8
|
name: "gtkx:settings-worker-env",
|
|
9
9
|
enforce: "pre",
|
|
@@ -11,7 +11,10 @@ export function gtkxSettingsWorkerEnv(): Plugin {
|
|
|
11
11
|
config(config: UserConfig) {
|
|
12
12
|
const root = config.root ?? process.cwd();
|
|
13
13
|
const dir = stageAndCompileProjectSchemas(root, resolveDataDir(root));
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
if (dir === null) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
process.env.GTKX_DEV_SCHEMA_DIR = dir;
|
|
17
20
|
|
|
@@ -23,3 +26,5 @@ export function gtkxSettingsWorkerEnv(): Plugin {
|
|
|
23
26
|
},
|
|
24
27
|
};
|
|
25
28
|
}
|
|
29
|
+
|
|
30
|
+
export { gtkxSettingsWorkerEnv };
|