@gtkx/cli 2.0.0-beta.1 → 2.0.0-beta.3
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 +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +17 -5
- 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 +9 -1
- package/dist/cli.js.map +1 -1
- package/dist/codegen/reference.d.ts.map +1 -1
- package/dist/codegen/reference.js +1 -0
- package/dist/codegen/reference.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +4 -2
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +15 -16
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +2 -1
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +4 -3
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +83 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts +1 -0
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +6 -5
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +4 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +9 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +29 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +1 -0
- package/dist/commands/docs.js.map +1 -1
- package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
- package/dist/deploy/freedesktop/metainfo.js +41 -2
- package/dist/deploy/freedesktop/metainfo.js.map +1 -1
- package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
- package/dist/deploy/freedesktop/validate.js +10 -4
- package/dist/deploy/freedesktop/validate.js.map +1 -1
- package/dist/deploy/nfpm/config.d.ts +3 -2
- package/dist/deploy/nfpm/config.d.ts.map +1 -1
- package/dist/deploy/nfpm/config.js +7 -4
- package/dist/deploy/nfpm/config.js.map +1 -1
- package/dist/deploy/nfpm/contents.d.ts.map +1 -1
- package/dist/deploy/nfpm/contents.js +8 -0
- package/dist/deploy/nfpm/contents.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +2 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +32 -5
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +2 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +75 -5
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/notices/node-runtime.js +2 -2
- package/dist/deploy/notices/node-runtime.js.map +1 -1
- package/dist/deploy/payload/launcher.d.ts.map +1 -1
- package/dist/deploy/payload/launcher.js +14 -1
- package/dist/deploy/payload/launcher.js.map +1 -1
- package/dist/deploy/payload/stage.js +1 -1
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts +1 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +100 -14
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/build-manifest.d.ts +6 -1
- package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
- package/dist/deploy/settings/build-manifest.js +15 -4
- package/dist/deploy/settings/build-manifest.js.map +1 -1
- package/dist/deploy/settings/extra-files.d.ts +1 -1
- package/dist/deploy/settings/extra-files.d.ts.map +1 -1
- package/dist/deploy/settings/extra-files.js +22 -1
- package/dist/deploy/settings/extra-files.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +1 -0
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +2 -1
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +2 -1
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +113 -5
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +11 -2
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
- package/dist/deploy/targets/nfpm-target.js +12 -7
- package/dist/deploy/targets/nfpm-target.js.map +1 -1
- package/dist/deploy/types.d.ts +1 -0
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/dev/entry-env.d.ts +2 -1
- package/dist/dev/entry-env.d.ts.map +1 -1
- package/dist/dev/entry-env.js +2 -1
- package/dist/dev/entry-env.js.map +1 -1
- package/dist/dev/headless.d.ts +3 -0
- package/dist/dev/headless.d.ts.map +1 -0
- package/dist/dev/headless.js +35 -0
- package/dist/dev/headless.js.map +1 -0
- package/dist/dev/runner-deps.d.ts +1 -1
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +3 -3
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +8 -3
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/supervisor.d.ts +1 -0
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +4 -3
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/i18n/catalogs.d.ts.map +1 -1
- package/dist/i18n/catalogs.js +1 -0
- package/dist/i18n/catalogs.js.map +1 -1
- package/dist/i18n/source-messages.d.ts.map +1 -1
- package/dist/i18n/source-messages.js +960 -8
- package/dist/i18n/source-messages.js.map +1 -1
- package/dist/internal/build-manifest.d.ts +5 -2
- package/dist/internal/build-manifest.d.ts.map +1 -1
- package/dist/internal/build-manifest.js +15 -2
- package/dist/internal/build-manifest.js.map +1 -1
- package/dist/internal/build-output.d.ts +8 -0
- package/dist/internal/build-output.d.ts.map +1 -0
- package/dist/internal/build-output.js +79 -0
- package/dist/internal/build-output.js.map +1 -0
- package/dist/internal/docs-elements.d.ts +1 -0
- package/dist/internal/docs-elements.d.ts.map +1 -1
- package/dist/internal/docs-elements.js +5 -4
- package/dist/internal/docs-elements.js.map +1 -1
- package/dist/internal/entry-arg.d.ts +4 -1
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +7 -1
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/errors.d.ts +2 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +1 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/output-directory.d.ts +15 -0
- package/dist/internal/output-directory.d.ts.map +1 -0
- package/dist/internal/output-directory.js +490 -0
- package/dist/internal/output-directory.js.map +1 -0
- package/dist/internal/parent-process.d.ts +12 -0
- package/dist/internal/parent-process.d.ts.map +1 -0
- package/dist/internal/parent-process.js +74 -0
- package/dist/internal/parent-process.js.map +1 -0
- package/dist/internal/prepare-project.d.ts +2 -0
- package/dist/internal/prepare-project.d.ts.map +1 -1
- package/dist/internal/prepare-project.js +3 -3
- package/dist/internal/prepare-project.js.map +1 -1
- package/dist/internal/source-imports.js +1 -1
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/client.js.map +1 -1
- package/dist/vite-plugins/build-manifest.d.ts +5 -1
- package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
- package/dist/vite-plugins/build-manifest.js +2 -1
- package/dist/vite-plugins/build-manifest.js.map +1 -1
- package/dist/vite-plugins/ensure-store.d.ts +1 -1
- package/dist/vite-plugins/ensure-store.d.ts.map +1 -1
- package/dist/vite-plugins/ensure-store.js +2 -2
- package/dist/vite-plugins/ensure-store.js.map +1 -1
- package/dist/vite-plugins/i18n.d.ts.map +1 -1
- package/dist/vite-plugins/i18n.js +58 -6
- package/dist/vite-plugins/i18n.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +8 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +6 -2
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/native.d.ts.map +1 -1
- package/dist/vite-plugins/native.js +0 -4
- package/dist/vite-plugins/native.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts.map +1 -1
- package/dist/vite-plugins/self-contained.js +159 -158
- package/dist/vite-plugins/self-contained.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +2 -2
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vitest-plugin.d.ts +2 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +6 -6
- package/dist/vitest-plugin.js.map +1 -1
- package/package.json +10 -9
- package/src/builder.ts +18 -5
- package/src/cli.ts +9 -1
- package/src/codegen/reference.ts +1 -0
- package/src/codegen/run-codegen.ts +17 -19
- package/src/codegen/store-resolver.ts +5 -3
- package/src/commands/build.ts +13 -2
- package/src/commands/codegen.ts +6 -5
- package/src/commands/deploy.ts +4 -2
- package/src/commands/dev.ts +38 -4
- package/src/commands/docs.ts +1 -0
- package/src/deploy/freedesktop/metainfo.ts +73 -21
- package/src/deploy/freedesktop/validate.ts +12 -4
- package/src/deploy/nfpm/config.ts +13 -4
- package/src/deploy/nfpm/contents.ts +8 -0
- package/src/deploy/node-runtime/elf.ts +43 -5
- package/src/deploy/node-runtime/index.ts +107 -6
- package/src/deploy/notices/node-runtime.ts +2 -2
- package/src/deploy/payload/launcher.ts +20 -1
- package/src/deploy/payload/stage.ts +1 -1
- package/src/deploy/run-deploy.ts +56 -16
- package/src/deploy/settings/build-manifest.ts +28 -3
- package/src/deploy/settings/extra-files.ts +26 -2
- package/src/deploy/settings/index.ts +3 -1
- package/src/deploy/settings/paths.ts +70 -5
- package/src/deploy/targets/flatpak-source.ts +13 -2
- package/src/deploy/targets/nfpm-target.ts +13 -6
- package/src/deploy/types.ts +1 -0
- package/src/dev/entry-env.ts +2 -1
- package/src/dev/headless.ts +40 -0
- package/src/dev/runner-deps.ts +3 -3
- package/src/dev/runner-main.ts +10 -3
- package/src/dev/supervisor.ts +6 -3
- package/src/i18n/catalogs.ts +1 -0
- package/src/i18n/source-messages.ts +1429 -28
- package/src/internal/build-manifest.ts +25 -1
- package/src/internal/build-output.ts +113 -0
- package/src/internal/docs-elements.ts +10 -4
- package/src/internal/entry-arg.ts +8 -1
- package/src/internal/errors.ts +1 -1
- package/src/internal/output-directory.ts +699 -0
- package/src/internal/parent-process.ts +110 -0
- package/src/internal/prepare-project.ts +5 -5
- package/src/internal/source-imports.ts +1 -1
- package/src/mcp/client.ts +2 -2
- package/src/vite-plugins/build-manifest.ts +7 -1
- package/src/vite-plugins/ensure-store.ts +2 -2
- package/src/vite-plugins/i18n.ts +83 -5
- package/src/vite-plugins/index.ts +14 -7
- package/src/vite-plugins/native.ts +0 -5
- package/src/vite-plugins/self-contained.ts +184 -185
- package/src/vite-plugins/settings-worker-env.ts +2 -2
- package/src/vitest-plugin.ts +6 -6
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
type ProcessIdentity = {
|
|
4
|
+
pid: number;
|
|
5
|
+
parentId: number;
|
|
6
|
+
processGroupId: number;
|
|
7
|
+
startTime: string;
|
|
8
|
+
state: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type ProcessGroupOwner = Pick<ProcessIdentity, "pid" | "startTime">;
|
|
12
|
+
type ProcessGroupOwnerCapture = { isCaptured: true; owner: ProcessGroupOwner | undefined } |
|
|
13
|
+
{ isCaptured: false; error: Error };
|
|
14
|
+
|
|
15
|
+
const initialParentId = process.ppid;
|
|
16
|
+
const STOPPED_PROCESS_STATES: Set<string> = new Set(["Z", "X", "x"]);
|
|
17
|
+
|
|
18
|
+
const processIdentity = (pid: number): ProcessIdentity => {
|
|
19
|
+
const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
|
|
20
|
+
const fields = stat.slice(stat.lastIndexOf(") ") + 2).split(" ");
|
|
21
|
+
const state = fields[0];
|
|
22
|
+
const parentId = Number(fields[1]);
|
|
23
|
+
const processGroupId = Number(fields[2]);
|
|
24
|
+
const startTime = fields[19];
|
|
25
|
+
|
|
26
|
+
if (
|
|
27
|
+
state === undefined ||
|
|
28
|
+
startTime === undefined ||
|
|
29
|
+
!Number.isSafeInteger(parentId) ||
|
|
30
|
+
!Number.isSafeInteger(processGroupId)
|
|
31
|
+
) {
|
|
32
|
+
throw new Error(`Failed to identify process ${String(pid)}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { pid, parentId, processGroupId, startTime, state };
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const ancestorFor = (process: ProcessIdentity, ancestorId: number): ProcessIdentity | undefined => {
|
|
39
|
+
let current = process;
|
|
40
|
+
|
|
41
|
+
while (current.parentId > 1) {
|
|
42
|
+
const parent = processIdentity(current.parentId);
|
|
43
|
+
|
|
44
|
+
if (parent.pid === ancestorId) {
|
|
45
|
+
return parent;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
current = parent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return undefined;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const processGroupOwner = (process: ProcessIdentity): ProcessGroupOwner => {
|
|
55
|
+
if (process.processGroupId !== process.pid || STOPPED_PROCESS_STATES.has(process.state)) {
|
|
56
|
+
throw new Error(`Failed to identify process group ${String(process.pid)}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { pid: process.pid, startTime: process.startTime };
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const processGroupOwnerFor = (process: ProcessIdentity): ProcessGroupOwner | undefined => {
|
|
63
|
+
if (process.processGroupId === process.pid) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const groupLeader = processGroupOwner(processIdentity(process.processGroupId));
|
|
68
|
+
const owner = ancestorFor(process, groupLeader.pid);
|
|
69
|
+
|
|
70
|
+
if (owner !== undefined) {
|
|
71
|
+
return groupLeader;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const currentGroupLeader = processGroupOwner(processIdentity(groupLeader.pid));
|
|
75
|
+
|
|
76
|
+
if (currentGroupLeader.startTime !== groupLeader.startTime) {
|
|
77
|
+
throw new Error(`Failed to identify process group ${String(groupLeader.pid)}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return undefined;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const captureProcessGroupOwner = (): ProcessGroupOwnerCapture => {
|
|
84
|
+
try {
|
|
85
|
+
const initialProcess = processIdentity(process.pid);
|
|
86
|
+
|
|
87
|
+
if (initialProcess.parentId !== initialParentId) {
|
|
88
|
+
throw new Error("The process that launched GTKX exited during startup");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { isCaptured: true, owner: processGroupOwnerFor(initialProcess) };
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
isCaptured: false,
|
|
95
|
+
error: error instanceof Error ? error : new Error("Failed to identify the process that launched GTKX"),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const capturedProcessGroupOwner = captureProcessGroupOwner();
|
|
101
|
+
|
|
102
|
+
const getInitialProcessGroupOwner = (): ProcessGroupOwner | undefined => {
|
|
103
|
+
if (!capturedProcessGroupOwner.isCaptured) {
|
|
104
|
+
throw capturedProcessGroupOwner.error;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return capturedProcessGroupOwner.owner;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export { getInitialProcessGroupOwner, initialParentId };
|
|
@@ -2,22 +2,22 @@ import { ensureGeneratedIn } from "../codegen/run-codegen.js";
|
|
|
2
2
|
import { type CodegenContext, resolveCodegenContext } from "../codegen/store-resolver.js";
|
|
3
3
|
import { resolveCwd, resolveEntry } from "./entry-arg.js";
|
|
4
4
|
|
|
5
|
-
type ProjectArgs = { entry?: string; cwd?: string };
|
|
6
|
-
type PreparedProject = { cwd: string; entry: string };
|
|
5
|
+
type ProjectArgs = { entry?: string; cwd?: string; config?: string };
|
|
6
|
+
type PreparedProject = { cwd: string; entry: string; configFile: string };
|
|
7
7
|
type ResolvedProject = PreparedProject & { context: CodegenContext };
|
|
8
8
|
|
|
9
9
|
const resolveProject = async (args: ProjectArgs, mode: string): Promise<ResolvedProject> => {
|
|
10
10
|
const cwd = resolveCwd(args);
|
|
11
|
-
const context = await resolveCodegenContext(cwd, mode);
|
|
11
|
+
const context = await resolveCodegenContext(cwd, mode, args.config);
|
|
12
12
|
|
|
13
|
-
return { cwd, entry: resolveEntry(cwd, args.entry), context };
|
|
13
|
+
return { cwd, entry: resolveEntry(cwd, args.entry), configFile: context.configFile, context };
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const prepareProject = async (args: ProjectArgs, mode: string): Promise<PreparedProject> => {
|
|
17
17
|
const { cwd, entry, context } = await resolveProject(args, mode);
|
|
18
18
|
await ensureGeneratedIn(context, { shouldAnnounce: true, mode });
|
|
19
19
|
|
|
20
|
-
return { cwd, entry };
|
|
20
|
+
return { cwd, entry, configFile: context.configFile };
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export { prepareProject, resolveProject };
|
|
@@ -33,7 +33,7 @@ const discoverSourceFiles = (dir: string): string[] =>
|
|
|
33
33
|
sortStringsBy(
|
|
34
34
|
globSync("**/{*,.*}", {
|
|
35
35
|
cwd: dir,
|
|
36
|
-
exclude: ["**/{build,coverage,dist,node_modules,out-tsc}/**"],
|
|
36
|
+
exclude: ["**/{build,coverage,dist,node_modules,out-tsc}/**", "**/.gtkx-output-*/**"],
|
|
37
37
|
withFileTypes: true,
|
|
38
38
|
})
|
|
39
39
|
.filter((entry) => entry.isFile())
|
package/src/mcp/client.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as Gio from "@gtkx/gi/gio";
|
|
2
2
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
3
|
import {
|
|
4
|
-
DEFAULT_SOCKET_PATH,
|
|
5
4
|
isConnectionClosedError,
|
|
6
5
|
type JSONRPCRequest,
|
|
7
6
|
ProtocolConnection,
|
|
7
|
+
resolveMcpSocketPath,
|
|
8
8
|
type Result,
|
|
9
9
|
} from "@gtkx/mcp/internal";
|
|
10
10
|
import { error, errorMessage, info, normalizeError } from "@gtkx/utils";
|
|
@@ -65,7 +65,7 @@ class McpClient {
|
|
|
65
65
|
private registry = new WidgetRegistry();
|
|
66
66
|
|
|
67
67
|
constructor(options: McpClientOptions) {
|
|
68
|
-
this.socketPath = options.socketPath
|
|
68
|
+
this.socketPath = resolveMcpSocketPath(options.socketPath);
|
|
69
69
|
this.applicationId = options.applicationId;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -21,6 +21,11 @@ type ManifestState = {
|
|
|
21
21
|
outDir: string;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
type BuildConfigIdentity = {
|
|
25
|
+
configFile: string;
|
|
26
|
+
configDigest: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
24
29
|
const PACKAGE_MANIFEST_FILENAME = "package.json";
|
|
25
30
|
const DEFAULT_OUT_DIR = "dist";
|
|
26
31
|
const JSON_INDENT = 4;
|
|
@@ -73,7 +78,7 @@ const packagesFor = (outDir: string, ids: string[]): RecordedPackage[] => {
|
|
|
73
78
|
|
|
74
79
|
const renderManifest = (manifest: BuildManifest): string => `${JSON.stringify(manifest, null, JSON_INDENT)}\n`;
|
|
75
80
|
|
|
76
|
-
function gtkxBuildManifest(root: string, collector: BuildManifestCollector): Plugin {
|
|
81
|
+
function gtkxBuildManifest(root: string, collector: BuildManifestCollector, identity: BuildConfigIdentity): Plugin {
|
|
77
82
|
const state: ManifestState = { outDir: join(root, DEFAULT_OUT_DIR) };
|
|
78
83
|
|
|
79
84
|
return {
|
|
@@ -90,6 +95,7 @@ function gtkxBuildManifest(root: string, collector: BuildManifestCollector): Plu
|
|
|
90
95
|
const manifest: BuildManifest = {
|
|
91
96
|
generator: BUILD_MANIFEST_GENERATOR,
|
|
92
97
|
formatVersion: BUILD_MANIFEST_FORMAT_VERSION,
|
|
98
|
+
...identity,
|
|
93
99
|
schemas: collector.schemas,
|
|
94
100
|
packages: packagesFor(state.outDir, ids),
|
|
95
101
|
};
|
|
@@ -3,11 +3,11 @@ import { ensureGenerated } from "../codegen/run-codegen.js";
|
|
|
3
3
|
|
|
4
4
|
const TEST_MODE = "test";
|
|
5
5
|
|
|
6
|
-
const gtkxEnsureStore = (): Plugin => ({
|
|
6
|
+
const gtkxEnsureStore = (configFile?: string): Plugin => ({
|
|
7
7
|
name: "gtkx:ensure-store",
|
|
8
8
|
|
|
9
9
|
async config() {
|
|
10
|
-
await ensureGenerated(process.cwd(), { shouldAnnounce: true, mode: TEST_MODE });
|
|
10
|
+
await ensureGenerated(process.cwd(), { shouldAnnounce: true, mode: TEST_MODE, configFile });
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
|
package/src/vite-plugins/i18n.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ConfigLoader } from "@gtkx/config";
|
|
2
2
|
import type { Plugin, ResolvedConfig } from "vite";
|
|
3
3
|
import { createConfigLoader } from "@gtkx/config/internal";
|
|
4
|
-
import { toPosixPath } from "@gtkx/utils";
|
|
4
|
+
import { isPathWithin, logger, toPosixPath } from "@gtkx/utils";
|
|
5
5
|
import { existsSync, mkdirSync } from "node:fs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { dirname, join, posix, relative, resolve } from "node:path";
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
synchronizeCatalogs,
|
|
14
14
|
} from "../i18n/catalogs.js";
|
|
15
15
|
import { extractSourceCatalog } from "../i18n/source-messages.js";
|
|
16
|
-
import {
|
|
16
|
+
import { emitI18nTypes } from "../i18n/types.js";
|
|
17
|
+
import { discoverSourceFiles, sourceLanguage } from "../internal/source-imports.js";
|
|
17
18
|
import { stripQuery } from "./strip-query.js";
|
|
18
19
|
|
|
19
20
|
type I18nState = {
|
|
@@ -21,6 +22,8 @@ type I18nState = {
|
|
|
21
22
|
i18nRoot: string;
|
|
22
23
|
outDir: string;
|
|
23
24
|
project: CatalogProject | null;
|
|
25
|
+
extraction: Promise<void>;
|
|
26
|
+
hotUpdateTimestamp: number | null;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
const BOOTSTRAP_SPECIFIER = "@gtkx/i18n/bootstrap";
|
|
@@ -94,6 +97,7 @@ const buildCatalogs = (state: I18nState): void => {
|
|
|
94
97
|
const extractProjectMessages = async (
|
|
95
98
|
state: I18nState,
|
|
96
99
|
shouldPreserveMetadataMessages: boolean,
|
|
100
|
+
shouldSynchronizeCatalogs: boolean,
|
|
97
101
|
): Promise<void> => {
|
|
98
102
|
const project = state.project;
|
|
99
103
|
|
|
@@ -104,7 +108,64 @@ const extractProjectMessages = async (
|
|
|
104
108
|
const srcDir = join(project.root, "src");
|
|
105
109
|
const sourceFiles = discoverSourceFiles(existsSync(srcDir) ? srcDir : project.root);
|
|
106
110
|
await extractSourceCatalog(project, sourceFiles, shouldPreserveMetadataMessages);
|
|
107
|
-
|
|
111
|
+
|
|
112
|
+
if (shouldSynchronizeCatalogs) {
|
|
113
|
+
synchronizeCatalogs(project);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
await emitI18nTypes(project.root);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const settleExtraction = async (pending: Promise<void>): Promise<void> => {
|
|
120
|
+
try {
|
|
121
|
+
await pending;
|
|
122
|
+
} catch {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const queueExtraction = (
|
|
128
|
+
state: I18nState,
|
|
129
|
+
shouldPreserveMetadataMessages: boolean,
|
|
130
|
+
shouldSynchronizeCatalogs: boolean,
|
|
131
|
+
): Promise<void> => {
|
|
132
|
+
const prior = state.extraction;
|
|
133
|
+
const pending = (async (): Promise<void> => {
|
|
134
|
+
await settleExtraction(prior);
|
|
135
|
+
await extractProjectMessages(
|
|
136
|
+
state,
|
|
137
|
+
shouldPreserveMetadataMessages,
|
|
138
|
+
shouldSynchronizeCatalogs,
|
|
139
|
+
);
|
|
140
|
+
})();
|
|
141
|
+
|
|
142
|
+
state.extraction = pending;
|
|
143
|
+
|
|
144
|
+
return pending;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const isProjectSource = (state: I18nState, path: string): boolean => {
|
|
148
|
+
const project = state.project;
|
|
149
|
+
|
|
150
|
+
if (project === null || sourceLanguage(path) === undefined) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const srcDir = join(project.root, "src");
|
|
155
|
+
const sourceRoot = existsSync(srcDir) ? srcDir : project.root;
|
|
156
|
+
|
|
157
|
+
return isPathWithin(sourceRoot, path);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const refreshProjectMessages = async (
|
|
161
|
+
state: I18nState,
|
|
162
|
+
shouldPreserveMetadataMessages: boolean,
|
|
163
|
+
): Promise<void> => {
|
|
164
|
+
try {
|
|
165
|
+
await queueExtraction(state, shouldPreserveMetadataMessages, false);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
168
|
+
}
|
|
108
169
|
};
|
|
109
170
|
|
|
110
171
|
const gtkxI18n = (
|
|
@@ -112,7 +173,14 @@ const gtkxI18n = (
|
|
|
112
173
|
loadConfig: ConfigLoader = createConfigLoader(),
|
|
113
174
|
shouldPreserveMetadataMessages = true,
|
|
114
175
|
): Plugin => {
|
|
115
|
-
const state: I18nState = {
|
|
176
|
+
const state: I18nState = {
|
|
177
|
+
entryPath,
|
|
178
|
+
extraction: Promise.resolve(),
|
|
179
|
+
hotUpdateTimestamp: null,
|
|
180
|
+
i18nRoot: "",
|
|
181
|
+
outDir: "",
|
|
182
|
+
project: null,
|
|
183
|
+
};
|
|
116
184
|
|
|
117
185
|
return {
|
|
118
186
|
name: "gtkx:i18n",
|
|
@@ -120,7 +188,17 @@ const gtkxI18n = (
|
|
|
120
188
|
|
|
121
189
|
configResolved: (config) => applyResolvedConfig(state, config, loadConfig),
|
|
122
190
|
|
|
123
|
-
buildStart: () =>
|
|
191
|
+
buildStart: () => queueExtraction(state, shouldPreserveMetadataMessages, true),
|
|
192
|
+
|
|
193
|
+
hotUpdate(options) {
|
|
194
|
+
if (!isProjectSource(state, options.file) || state.hotUpdateTimestamp === options.timestamp) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
state.hotUpdateTimestamp = options.timestamp;
|
|
199
|
+
|
|
200
|
+
return refreshProjectMessages(state, shouldPreserveMetadataMessages);
|
|
201
|
+
},
|
|
124
202
|
|
|
125
203
|
transform(code, id) {
|
|
126
204
|
if (isI18nLocaleModule(state, id)) {
|
|
@@ -13,13 +13,20 @@ import { gtkxSettings } from "./settings.js";
|
|
|
13
13
|
import { gtkxStoreLinks } from "./store-links.js";
|
|
14
14
|
import { gtkxUndeclaredLibrary } from "./undeclared-library.js";
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
type GtkxVitePluginOptions = {
|
|
17
|
+
buildManifest?: BuildManifestCollector | undefined;
|
|
18
|
+
configFile?: string | undefined;
|
|
19
|
+
entryPath?: string | undefined;
|
|
20
|
+
mode?: string | undefined;
|
|
21
|
+
shouldPreserveI18nMetadata?: boolean | undefined;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const gtkxVitePlugins = (options: GtkxVitePluginOptions = {}): Plugin[] => {
|
|
25
|
+
const { buildManifest, configFile, entryPath, mode, shouldPreserveI18nMetadata = true } = options;
|
|
26
|
+
const loadConfig = createConfigLoader({
|
|
27
|
+
...(mode !== undefined && { mode }),
|
|
28
|
+
...(configFile !== undefined && { configFile }),
|
|
29
|
+
});
|
|
23
30
|
|
|
24
31
|
return [
|
|
25
32
|
createConfigPlugin({ name: "gtkx:config", loadConfig }),
|
|
@@ -5,7 +5,6 @@ import { arch, platform } from "node:os";
|
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { stripQuery } from "./strip-query.js";
|
|
7
7
|
|
|
8
|
-
const EMITTED_BINDING_SPECIFIER = "./gtkx.node";
|
|
9
8
|
const BINDING_FILENAME = "gtkx.node";
|
|
10
9
|
|
|
11
10
|
function resolveBinaryPath(projectRequire: ReturnType<typeof createRequire>, currentArch: string): string {
|
|
@@ -97,10 +96,6 @@ function gtkxNative(root: string): Plugin {
|
|
|
97
96
|
});
|
|
98
97
|
},
|
|
99
98
|
|
|
100
|
-
resolveId(id) {
|
|
101
|
-
return id === EMITTED_BINDING_SPECIFIER ? { id, external: true } : null;
|
|
102
|
-
},
|
|
103
|
-
|
|
104
99
|
transform(code, id) {
|
|
105
100
|
return transformLoader(code, id, loaderPath(), bindingReferenceId);
|
|
106
101
|
},
|