@gjsify/node-gi 0.26.1 → 0.27.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 +96 -12
- package/cairo.d.ts +121 -121
- package/cairo.js +425 -426
- package/gettext.d.ts +24 -24
- package/gettext.js +42 -42
- package/gi.d.ts +170 -122
- package/gi.js +1514 -1464
- package/globals.d.ts +28 -28
- package/globals.js +103 -97
- package/gtk-runtime.js +64 -20
- package/index.d.ts +133 -152
- package/index.js +82 -100
- package/native-paths.js +104 -0
- package/overrides/_signals.js +108 -111
- package/overrides/byte-array.js +135 -135
- package/overrides/gio-dbus.js +681 -658
- package/overrides/mainloop.js +27 -27
- package/overrides/package.js +128 -128
- package/package.json +7 -2
- package/prebuilds/darwin-arm64/node_gi.node +0 -0
- package/prebuilds/darwin-x64/node_gi.node +0 -0
- package/prebuilds/linux-arm64/node_gi.node +0 -0
- package/prebuilds/linux-x64/node_gi.node +0 -0
- package/prebuilds/win32-x64/node_gi.node +0 -0
- package/scripts/install.mjs +238 -0
- package/scripts/win-gi-gyp-flags.mjs +2 -11
- package/src/template.cc +24 -6
- package/system-gi.d.ts +20 -0
- package/system-gi.js +209 -0
- package/system.d.ts +13 -13
- package/system.js +35 -35
|
@@ -108,8 +108,7 @@ if (mode === '--includes') {
|
|
|
108
108
|
// Last resort: locate ffi.h anywhere under the tree and add its dir.
|
|
109
109
|
if (!dirs.some((d) => existsSync(join(d, 'ffi.h')))) {
|
|
110
110
|
const ffiDir =
|
|
111
|
-
findHeaderDir(join(prefix, 'include'), 'ffi.h') ??
|
|
112
|
-
findHeaderDir(join(prefix, 'lib'), 'ffi.h');
|
|
111
|
+
findHeaderDir(join(prefix, 'include'), 'ffi.h') ?? findHeaderDir(join(prefix, 'lib'), 'ffi.h');
|
|
113
112
|
if (ffiDir) dirs.push(ffiDir);
|
|
114
113
|
}
|
|
115
114
|
}
|
|
@@ -127,15 +126,7 @@ if (mode === '--includes') {
|
|
|
127
126
|
// cairo the native cairo foreign-struct binding (src/cairo.cc)
|
|
128
127
|
// Pango/GdkPixbuf/Graphene are NOT linked — the conformance programs load their
|
|
129
128
|
// typelibs at RUNTIME (girepository dlopens the DLL by soname), not at link time.
|
|
130
|
-
const DIRECT_LIBS = [
|
|
131
|
-
'girepository-2.0',
|
|
132
|
-
'gio-2.0',
|
|
133
|
-
'gobject-2.0',
|
|
134
|
-
'gmodule-2.0',
|
|
135
|
-
'glib-2.0',
|
|
136
|
-
'ffi',
|
|
137
|
-
'cairo',
|
|
138
|
-
];
|
|
129
|
+
const DIRECT_LIBS = ['girepository-2.0', 'gio-2.0', 'gobject-2.0', 'gmodule-2.0', 'glib-2.0', 'ffi', 'cairo'];
|
|
139
130
|
// Locate the import-lib dir: GTK_PREFIX/lib, else pkg-config's -L.
|
|
140
131
|
const searchDirs = [];
|
|
141
132
|
if (process.env.GTK_PREFIX) searchDirs.push(join(process.env.GTK_PREFIX, 'lib'));
|
package/src/template.cc
CHANGED
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
namespace nodegi {
|
|
7
7
|
|
|
8
8
|
// Resolve the GTK template API once (C++11 function-local static init is
|
|
9
|
-
// thread-safe; node-gi calls these only on the main thread).
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// caller that never required Gtk through the typelib still resolves the symbols.
|
|
9
|
+
// thread-safe; node-gi calls these only on the main thread). How the library
|
|
10
|
+
// handle is obtained — and why the leaf name has to be per-OS — is documented at
|
|
11
|
+
// the dlopen below.
|
|
13
12
|
const GtkTemplateApi* GetGtkTemplateApi() {
|
|
14
13
|
static GtkTemplateApi api = {};
|
|
15
14
|
static bool initialised = false;
|
|
@@ -22,8 +21,27 @@ const GtkTemplateApi* GetGtkTemplateApi() {
|
|
|
22
21
|
// callers warn + no-op / throw a clear "template API unavailable" error.
|
|
23
22
|
return &api;
|
|
24
23
|
#else
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
// The library's LEAF NAME IS PER-OS, and hardcoding the ELF soname made the
|
|
25
|
+
// whole composite-template API unavailable on macOS: `libgtk-4.so.1` does not
|
|
26
|
+
// exist there, so every `registerClass({ Template })` widget failed with
|
|
27
|
+
// "the libgtk-4 template API is unavailable" on a host with GTK 4 correctly
|
|
28
|
+
// installed. Invisible until v0.27.0 shipped the first darwin-x64 addon.
|
|
29
|
+
//
|
|
30
|
+
// Candidates are the leaf names GTK 4 actually installs, newest ABI first.
|
|
31
|
+
#ifdef __APPLE__
|
|
32
|
+
static const char* const kGtkLeaves[] = {"libgtk-4.1.dylib", "libgtk-4.dylib"};
|
|
33
|
+
#else
|
|
34
|
+
static const char* const kGtkLeaves[] = {"libgtk-4.so.1", "libgtk-4.so"};
|
|
35
|
+
#endif
|
|
36
|
+
void* lib = nullptr;
|
|
37
|
+
for (const char* leaf : kGtkLeaves) {
|
|
38
|
+
// RTLD_NOLOAD first — requireGi('Gtk','4.0') already dlopened libgtk-4 via the
|
|
39
|
+
// typelib, so this only bumps the refcount; the plain dlopen behind it serves a
|
|
40
|
+
// caller that never required Gtk through the typelib.
|
|
41
|
+
lib = dlopen(leaf, RTLD_LAZY | RTLD_NOLOAD);
|
|
42
|
+
if (lib == nullptr) lib = dlopen(leaf, RTLD_LAZY);
|
|
43
|
+
if (lib != nullptr) break;
|
|
44
|
+
}
|
|
27
45
|
if (lib == nullptr) return &api; // api.ok stays false → callers warn + no-op
|
|
28
46
|
api.set_template = reinterpret_cast<decltype(api.set_template)>(
|
|
29
47
|
dlsym(lib, "gtk_widget_class_set_template"));
|
package/system-gi.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/** Injectable host facts for {@link systemGiLibraryDirs} — the darwin branch is testable from Linux. */
|
|
3
|
+
export interface SystemGiOptions {
|
|
4
|
+
/** `process.platform` value; defaults to the running process. */
|
|
5
|
+
platform?: string;
|
|
6
|
+
/** Environment to read `GI_TYPELIB_PATH` / `PKG_CONFIG_PATH` from; defaults to `process.env`. */
|
|
7
|
+
env?: NodeJS.ProcessEnv;
|
|
8
|
+
/** Directory-existence predicate; defaults to a `statSync` probe. */
|
|
9
|
+
existsDir?: (dir: string) => boolean;
|
|
10
|
+
/** `pkg-config`'s `.pc` search directories; defaults to {@link pkgConfigSearchDirs}. */
|
|
11
|
+
searchDirs?: (env: NodeJS.ProcessEnv) => string[];
|
|
12
|
+
}
|
|
13
|
+
/** Split an OS search-path variable, dropping empty segments. */
|
|
14
|
+
export function splitSearchPath(value: string | undefined, separator?: string): string[];
|
|
15
|
+
/** `$PKG_CONFIG_PATH` plus `pkg-config`'s own `pc_path`; memoized, absent pkg-config yields just the env. */
|
|
16
|
+
export function pkgConfigSearchDirs(env: NodeJS.ProcessEnv): string[];
|
|
17
|
+
/** Directories holding the host's system GI shared libraries, most specific first; `[]` off darwin. */
|
|
18
|
+
export function systemGiLibraryDirs(opts?: SystemGiOptions): string[];
|
|
19
|
+
/** Whether a split loader path already covers every wanted directory. */
|
|
20
|
+
export function pathCovers(wanted: readonly string[], current: readonly string[]): boolean;
|
package/system-gi.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// @gjsify/node-gi/system-gi — WHERE the host's GObject-Introspection stack keeps
|
|
3
|
+
// its shared libraries, so the dynamic loader can find the ones a typelib names
|
|
4
|
+
// by BARE LEAF (`libgtk-4.1.dylib`, `libgdk_pixbuf-2.0.0.dylib`, …).
|
|
5
|
+
//
|
|
6
|
+
// WHY THIS EXISTS — the failure it removes, measured on macOS 15.7.8 / Homebrew
|
|
7
|
+
// /usr/local / Node 24.18.1 / GTK 4.22.4, the first release that shipped a
|
|
8
|
+
// darwin-x64 addon:
|
|
9
|
+
//
|
|
10
|
+
// GLib-GIRepository-WARNING: Failed to load shared library 'libgtk-4.1.dylib'
|
|
11
|
+
// referenced by the typelib: dlopen(libgtk-4.1.dylib, 0x0009): tried:
|
|
12
|
+
// 'libgtk-4.1.dylib' (no such file), …, '/usr/lib/libgtk-4.1.dylib' (no such file)
|
|
13
|
+
// TypeError: Gtk.DrawingArea is not a subclassable GObject type
|
|
14
|
+
//
|
|
15
|
+
// Everything WAS installed: `/usr/local/lib/libgtk-4.1.dylib` exists and
|
|
16
|
+
// `/usr/local/lib/girepository-1.0/Gtk-4.0.typelib` names exactly that leaf. The
|
|
17
|
+
// gap is the LOADER, not the installation — modern dyld does not carry
|
|
18
|
+
// `/usr/local/lib` in its default fallback search path, and a plain `node` has no
|
|
19
|
+
// rpath there (Homebrew's own `gjs` binary does, which is why `--runtime gjs`
|
|
20
|
+
// never showed this and `--runtime node` did). `gi_repository_require` resolves
|
|
21
|
+
// the typelib, `g_module_open('libgtk-4.1.dylib')` then fails, no
|
|
22
|
+
// `gtk_drawing_area_get_type` is ever registered, and the failure surfaces one
|
|
23
|
+
// layer up as "not a subclassable GObject type".
|
|
24
|
+
//
|
|
25
|
+
// The value CANNOT come from `pkg-config --variable=libdir gtk4`. Measured on the
|
|
26
|
+
// same host: that answers `/usr/local/Cellar/gtk4/4.22.4/lib` — a PER-FORMULA
|
|
27
|
+
// directory that fixes GTK and leaves `libgdk_pixbuf-2.0.0.dylib` (a different
|
|
28
|
+
// formula, so a different Cellar libdir) still unresolvable. What works is the
|
|
29
|
+
// directory every keg is symlinked into, `<prefix>/lib`, because it is the UNION.
|
|
30
|
+
// So the question this module answers is "which directories hold the GI stack",
|
|
31
|
+
// never "where is one library".
|
|
32
|
+
//
|
|
33
|
+
// THE RULE — a typelib and the library it names are SIBLINGS by GI's own install
|
|
34
|
+
// layout: `<libdir>/girepository-1.0/Gtk-4.0.typelib` beside
|
|
35
|
+
// `<libdir>/libgtk-4.1.dylib`. A directory holding `girepository-1.0/` therefore
|
|
36
|
+
// IS a GI library directory. That convention is what makes this
|
|
37
|
+
// package-manager-agnostic: it lands on `/usr/local/lib` (Homebrew x64),
|
|
38
|
+
// `/opt/homebrew/lib` (Homebrew arm64), `/opt/local/lib` (MacPorts) or a custom
|
|
39
|
+
// prefix without needing to know that any of them exist.
|
|
40
|
+
//
|
|
41
|
+
// PURE FUNCTION of injected host facts (platform / env / fs / pkg-config), like
|
|
42
|
+
// `hostTarget()` beside it and the CLI's `resolvePrebuildDirName()` — so the
|
|
43
|
+
// darwin branch is unit-testable from a Linux host and the host values are read
|
|
44
|
+
// only at the outermost call site, as defaults.
|
|
45
|
+
import { statSync } from 'node:fs';
|
|
46
|
+
import { createRequire } from 'node:module';
|
|
47
|
+
import { basename, dirname, join } from 'node:path';
|
|
48
|
+
|
|
49
|
+
const require = createRequire(import.meta.url);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Prefixes a macOS GI stack is installed under in practice — probed, never
|
|
53
|
+
* assumed: each is accepted only when it actually holds a `girepository-1.0/`.
|
|
54
|
+
*
|
|
55
|
+
* This is the no-pkg-config safety net, and it is load-bearing rather than
|
|
56
|
+
* belt-and-braces: `brew install gtk4` installs RUNTIME dependencies only, so a
|
|
57
|
+
* user running a published showcase routinely has the entire GTK stack and no
|
|
58
|
+
* `pkg-config` at all (it is a BUILD dependency of those formulae). The
|
|
59
|
+
* pkg-config source below is the GENERAL mechanism — it is what finds a jhbuild
|
|
60
|
+
* or otherwise bespoke prefix — but it cannot be the only one.
|
|
61
|
+
* @type {Record<string, readonly string[]>}
|
|
62
|
+
*/
|
|
63
|
+
const PROBED_GI_LIBDIRS = {
|
|
64
|
+
darwin: ['/opt/homebrew/lib', '/usr/local/lib', '/opt/local/lib'],
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/** The subdir GI installs typelibs into — historically `1.0` even for the girepository-2.0 API. */
|
|
68
|
+
const TYPELIB_SUBDIR = 'girepository-1.0';
|
|
69
|
+
|
|
70
|
+
/** Memoized `pkg-config` answer: the spawn happens at most once per process. */
|
|
71
|
+
let pkgConfigDirsCache = null;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Split an OS search-path variable, dropping empty segments.
|
|
75
|
+
* @param {string | undefined} value
|
|
76
|
+
* @param {string} [separator]
|
|
77
|
+
* @returns {string[]}
|
|
78
|
+
*/
|
|
79
|
+
export function splitSearchPath(value, separator = ':') {
|
|
80
|
+
return (value ?? '').split(separator).filter(Boolean);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {string} dir
|
|
85
|
+
* @returns {boolean}
|
|
86
|
+
*/
|
|
87
|
+
function isDirectory(dir) {
|
|
88
|
+
try {
|
|
89
|
+
return statSync(dir).isDirectory();
|
|
90
|
+
} catch {
|
|
91
|
+
// Any stat failure means the same thing here — ENOENT on an uninstalled
|
|
92
|
+
// prefix, EACCES on a path this process may not read: not a usable libdir.
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* `pkg-config`'s OWN configured `.pc` search path plus `$PKG_CONFIG_PATH`. Every
|
|
99
|
+
* entry is a `<libdir>/pkgconfig` (or `<datadir>/pkgconfig`) directory, so its
|
|
100
|
+
* parent is a candidate libdir — which is how a prefix nobody hardcoded is
|
|
101
|
+
* found. Measured on the reported host: `pc_path` =
|
|
102
|
+
* `/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/pkgconfig:…`,
|
|
103
|
+
* whose first parent is exactly the `/usr/local/lib` that resolves every leaf.
|
|
104
|
+
*
|
|
105
|
+
* `spawnSync` reports a missing executable as `result.error`, not by throwing —
|
|
106
|
+
* an absent `pkg-config` is expected on a runtime-only GTK install, so it is a
|
|
107
|
+
* checked return value here and not an exception path.
|
|
108
|
+
* @param {NodeJS.ProcessEnv} env
|
|
109
|
+
* @returns {string[]}
|
|
110
|
+
*/
|
|
111
|
+
export function pkgConfigSearchDirs(env) {
|
|
112
|
+
if (pkgConfigDirsCache) return pkgConfigDirsCache;
|
|
113
|
+
const dirs = splitSearchPath(env.PKG_CONFIG_PATH);
|
|
114
|
+
// Lazily required, never imported at module top level: `index.js` deliberately
|
|
115
|
+
// keeps node:child_process out of non-darwin module graphs because an eager
|
|
116
|
+
// import tripped a Deno teardown regression on an unrelated conformance file.
|
|
117
|
+
const { spawnSync } = require('node:child_process');
|
|
118
|
+
const res = spawnSync('pkg-config', ['--variable=pc_path', 'pkg-config'], {
|
|
119
|
+
encoding: 'utf8',
|
|
120
|
+
timeout: 10_000,
|
|
121
|
+
});
|
|
122
|
+
if (!res.error && res.status === 0) dirs.push(...splitSearchPath(String(res.stdout).trim()));
|
|
123
|
+
pkgConfigDirsCache = dirs;
|
|
124
|
+
return dirs;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Directories holding the host's system GObject-Introspection shared libraries —
|
|
129
|
+
* most specific first, deduplicated, each verified on disk.
|
|
130
|
+
*
|
|
131
|
+
* Three sources, in precedence order:
|
|
132
|
+
* 1. `GI_TYPELIB_PATH` — the host stating outright where typelibs live; the
|
|
133
|
+
* libraries are the sibling `dirname()`. Accepted on directory existence
|
|
134
|
+
* alone: an explicit statement is not second-guessed.
|
|
135
|
+
* 2. `pkg-config`'s `.pc` search path → each `<dir>/pkgconfig`'s parent. The
|
|
136
|
+
* general mechanism (any prefix, including a custom one).
|
|
137
|
+
* 3. {@link PROBED_GI_LIBDIRS} — the standard macOS prefixes, for the common
|
|
138
|
+
* case where GTK is installed and pkg-config is not.
|
|
139
|
+
* Sources 2 and 3 are GUESSES at a prefix, so each must show the
|
|
140
|
+
* `girepository-1.0/` marker before it is believed.
|
|
141
|
+
*
|
|
142
|
+
* Empty off darwin, and that is a statement about LOADERS, not about GI. Linux
|
|
143
|
+
* resolves these leaves through `ld.so`'s system-wide configured cache
|
|
144
|
+
* (`/etc/ld.so.conf.d`), which a package install populates — nothing per-process
|
|
145
|
+
* is needed. dyld is the one loader that neither consults a system-wide config
|
|
146
|
+
* NOR re-reads its search path after launch, which is why darwin needs a re-exec
|
|
147
|
+
* and nobody else does.
|
|
148
|
+
*
|
|
149
|
+
* win32 is deliberately absent rather than proven unnecessary: `PATH` is the DLL
|
|
150
|
+
* search path, a Windows GTK distribution puts its `bin` there itself, and
|
|
151
|
+
* Windows re-reads that path at every `LoadLibrary` — so if a system GTK ever
|
|
152
|
+
* turns out not to be on it, the repair is an in-process `process.env.PATH`
|
|
153
|
+
* prepend (the shape `maybePrependGtkRuntimeDllPath()` already uses for the
|
|
154
|
+
* bundle), never this re-exec. Untested there, and node-gi's win32 GTK support is
|
|
155
|
+
* Phase 2 regardless.
|
|
156
|
+
* @param {object} [opts]
|
|
157
|
+
* @param {string} [opts.platform] defaults to `process.platform`
|
|
158
|
+
* @param {NodeJS.ProcessEnv} [opts.env] defaults to `process.env`
|
|
159
|
+
* @param {(dir: string) => boolean} [opts.existsDir] directory predicate (injectable for tests)
|
|
160
|
+
* @param {(env: NodeJS.ProcessEnv) => string[]} [opts.searchDirs] pkg-config `.pc` dirs (injectable)
|
|
161
|
+
* @returns {string[]} absolute directories, or `[]` when this platform's loader needs none
|
|
162
|
+
*/
|
|
163
|
+
export function systemGiLibraryDirs({
|
|
164
|
+
platform = process.platform,
|
|
165
|
+
env = process.env,
|
|
166
|
+
existsDir = isDirectory,
|
|
167
|
+
searchDirs = pkgConfigSearchDirs,
|
|
168
|
+
} = {}) {
|
|
169
|
+
const probed = PROBED_GI_LIBDIRS[platform];
|
|
170
|
+
if (!probed) return [];
|
|
171
|
+
|
|
172
|
+
/** @type {string[]} */
|
|
173
|
+
const out = [];
|
|
174
|
+
const add = (dir) => {
|
|
175
|
+
if (dir && dir !== '/' && !out.includes(dir)) out.push(dir);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// 1. Explicit: the typelib dir's sibling libdir.
|
|
179
|
+
for (const typelibDir of splitSearchPath(env.GI_TYPELIB_PATH)) {
|
|
180
|
+
const libDir = dirname(typelibDir);
|
|
181
|
+
if (existsDir(libDir)) add(libDir);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 2 + 3. Candidate prefixes, believed only on the girepository-1.0 marker.
|
|
185
|
+
/** @type {string[]} */
|
|
186
|
+
const candidates = [];
|
|
187
|
+
for (const pcDir of searchDirs(env)) {
|
|
188
|
+
if (basename(pcDir) === 'pkgconfig') candidates.push(dirname(pcDir));
|
|
189
|
+
}
|
|
190
|
+
candidates.push(...probed);
|
|
191
|
+
for (const libDir of candidates) {
|
|
192
|
+
if (existsDir(join(libDir, TYPELIB_SUBDIR))) add(libDir);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Whether `current` (a split `DYLD_FALLBACK_LIBRARY_PATH`) already covers every
|
|
200
|
+
* directory in `wanted` — the "nothing to do" test that keeps a correctly
|
|
201
|
+
* launched process (a CI job, or a launcher that exported the variable) from
|
|
202
|
+
* re-execing at all, and keeps a re-exec'd child from doing it twice.
|
|
203
|
+
* @param {readonly string[]} wanted
|
|
204
|
+
* @param {readonly string[]} current
|
|
205
|
+
* @returns {boolean}
|
|
206
|
+
*/
|
|
207
|
+
export function pathCovers(wanted, current) {
|
|
208
|
+
return wanted.every((dir) => current.includes(dir));
|
|
209
|
+
}
|
package/system.d.ts
CHANGED
|
@@ -30,19 +30,19 @@ export function dumpMemoryInfo(): void;
|
|
|
30
30
|
|
|
31
31
|
/** The GJS `System` module object (`import System from 'system'`). */
|
|
32
32
|
export interface SystemModule {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
exit(code?: number): void;
|
|
34
|
+
gc(): void;
|
|
35
|
+
version: number;
|
|
36
|
+
readonly programArgs: string[];
|
|
37
|
+
readonly programInvocationName: string;
|
|
38
|
+
readonly programPath: string | null;
|
|
39
|
+
addressOf(): string;
|
|
40
|
+
addressOfGObject(): string;
|
|
41
|
+
refcount(): number;
|
|
42
|
+
breakpoint(): void;
|
|
43
|
+
clearDateCaches(): void;
|
|
44
|
+
dumpHeap(): void;
|
|
45
|
+
dumpMemoryInfo(): void;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
declare const System: SystemModule;
|
package/system.js
CHANGED
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
// module is loaded from `@gjsify/node-gi/globals`, before any bundle body (and
|
|
36
36
|
// therefore before any register side effect) runs.
|
|
37
37
|
const runtimeProcess = (() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
const hostProcess = typeof process !== 'undefined' ? process : undefined;
|
|
39
|
+
try {
|
|
40
|
+
const builtin = hostProcess?.getBuiltinModule?.('node:process');
|
|
41
|
+
if (builtin && typeof builtin.exit === 'function') return builtin;
|
|
42
|
+
} catch {
|
|
43
|
+
// getBuiltinModule missing or refusing the specifier — use the captured one.
|
|
44
|
+
}
|
|
45
|
+
return hostProcess;
|
|
46
46
|
})();
|
|
47
47
|
|
|
48
48
|
const runtimeExit = typeof runtimeProcess?.exit === 'function' ? runtimeProcess.exit.bind(runtimeProcess) : undefined;
|
|
@@ -50,17 +50,17 @@ const runtimeExit = typeof runtimeProcess?.exit === 'function' ? runtimeProcess.
|
|
|
50
50
|
// `programArgs` mirrors GJS's ARGV: the script arguments, excluding the
|
|
51
51
|
// interpreter (argv[0]) and the script path (argv[1]).
|
|
52
52
|
function readProgramArgs() {
|
|
53
|
-
|
|
53
|
+
return Array.isArray(runtimeProcess?.argv) ? runtimeProcess.argv.slice(2) : [];
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// `programInvocationName` / `programPath` track the running script — Node's
|
|
57
57
|
// `process.argv[1]`.
|
|
58
58
|
function readProgramInvocationName() {
|
|
59
|
-
|
|
59
|
+
return runtimeProcess?.argv?.[1] || '';
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
function readProgramPath() {
|
|
63
|
-
|
|
63
|
+
return runtimeProcess?.argv?.[1] || null;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
@@ -74,12 +74,12 @@ function readProgramPath() {
|
|
|
74
74
|
* `conformance/programs/system-exit-lifetime.conf.mjs`).
|
|
75
75
|
*/
|
|
76
76
|
export function exit(code) {
|
|
77
|
-
|
|
77
|
+
if (runtimeExit !== undefined) runtimeExit(code ?? 0);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/** Trigger a garbage collection if the host exposed `globalThis.gc` (`--expose-gc`). */
|
|
81
81
|
export function gc() {
|
|
82
|
-
|
|
82
|
+
if (typeof globalThis.gc === 'function') globalThis.gc();
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/** The SpiderMonkey/mozjs version number — no equivalent on Node, reported as 0. */
|
|
@@ -96,17 +96,17 @@ export const programPath = readProgramPath();
|
|
|
96
96
|
|
|
97
97
|
/** Return the address of a JS object as a string. No Node equivalent — stub. */
|
|
98
98
|
export function addressOf() {
|
|
99
|
-
|
|
99
|
+
return '0x0';
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/** Return the address of a GObject as a string. No Node equivalent — stub. */
|
|
103
103
|
export function addressOfGObject() {
|
|
104
|
-
|
|
104
|
+
return '0x0';
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/** Return the refcount of a GObject. No Node equivalent — stub. */
|
|
108
108
|
export function refcount() {
|
|
109
|
-
|
|
109
|
+
return 0;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
/** Trigger a debugger breakpoint. No-op on Node. */
|
|
@@ -128,25 +128,25 @@ export function dumpMemoryInfo() {}
|
|
|
128
128
|
* track the running script.
|
|
129
129
|
*/
|
|
130
130
|
const System = {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
131
|
+
exit,
|
|
132
|
+
gc,
|
|
133
|
+
version,
|
|
134
|
+
addressOf,
|
|
135
|
+
addressOfGObject,
|
|
136
|
+
refcount,
|
|
137
|
+
breakpoint,
|
|
138
|
+
clearDateCaches,
|
|
139
|
+
dumpHeap,
|
|
140
|
+
dumpMemoryInfo,
|
|
141
|
+
get programArgs() {
|
|
142
|
+
return readProgramArgs();
|
|
143
|
+
},
|
|
144
|
+
get programInvocationName() {
|
|
145
|
+
return readProgramInvocationName();
|
|
146
|
+
},
|
|
147
|
+
get programPath() {
|
|
148
|
+
return readProgramPath();
|
|
149
|
+
},
|
|
150
150
|
};
|
|
151
151
|
|
|
152
152
|
export default System;
|