@gjsify/node-gi 0.36.0 → 0.38.0
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/gi.js +143 -247
- package/gtk-runtime.d.ts +9 -1
- package/gtk-runtime.js +61 -7
- package/index.d.ts +3 -0
- package/index.js +93 -617
- package/package.json +1 -1
- 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 +68 -97
- package/src/addon.cc +1 -0
- package/src/common.h +1 -0
- package/src/repo.cc +26 -0
- package/system-gi.js +40 -0
package/gtk-runtime.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createRequire } from 'node:module';
|
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { dirname, join } from 'node:path';
|
|
13
13
|
import { existsSync } from 'node:fs';
|
|
14
|
-
import { pathCovers, splitSearchPath, systemGiLibraryDirs } from './system-gi.js';
|
|
14
|
+
import { composeDyldFallback, pathCovers, splitSearchPath, systemGiLibraryDirs } from './system-gi.js';
|
|
15
15
|
import { nativeCandidates, prebuildAddonPath } from './native-paths.js';
|
|
16
16
|
|
|
17
17
|
// NB: node:child_process is intentionally NOT imported at module top level. It is
|
|
@@ -309,9 +309,11 @@ export function maybeReexecForGtkRuntime() {
|
|
|
309
309
|
const env = {
|
|
310
310
|
...process.env,
|
|
311
311
|
[REEXEC_SENTINEL]: '1',
|
|
312
|
-
// Our dirs first, then whatever the host asked for
|
|
313
|
-
//
|
|
314
|
-
|
|
312
|
+
// Our dirs first, then whatever the host asked for, then dyld's own
|
|
313
|
+
// default list — setting the variable REPLACES that list, so carrying
|
|
314
|
+
// it is what keeps the re-exec'd child from searching LESS than the
|
|
315
|
+
// process that spawned it.
|
|
316
|
+
DYLD_FALLBACK_LIBRARY_PATH: composeDyldFallback(libDirs),
|
|
315
317
|
};
|
|
316
318
|
// Only a bundle relocates typelibs; a host GI stack's are already on GI's own
|
|
317
319
|
// search path, so the system branch deliberately leaves GI_TYPELIB_PATH alone.
|
|
@@ -457,6 +459,57 @@ function gstScannerLeaf() {
|
|
|
457
459
|
return process.platform === 'win32' ? 'gst-plugin-scanner.exe' : 'gst-plugin-scanner';
|
|
458
460
|
}
|
|
459
461
|
|
|
462
|
+
let libraryPathActivated = false;
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Tell GI where the shared libraries its typelibs name by BARE LEAF actually are
|
|
466
|
+
* — for whichever GTK the policy chose, and WITHOUT an environment variable.
|
|
467
|
+
*
|
|
468
|
+
* THE GAP THIS CLOSES. A typelib records its backer as `libgtk-4.1.dylib`, and on
|
|
469
|
+
* macOS neither a relocated bundle's `lib` dir nor Homebrew's `/usr/local/lib` is
|
|
470
|
+
* on dyld's search path. Node papers over it in {@link maybeReexecForGtkRuntime}
|
|
471
|
+
* by re-execing with `DYLD_FALLBACK_LIBRARY_PATH` set — a Node-shaped re-exec, so
|
|
472
|
+
* it returns early on bun and deno, which got NO loader repair and died at the
|
|
473
|
+
* first widget behind three errors that all point elsewhere (`GtkWidget is not
|
|
474
|
+
* registered…`, `Adw.Application has no property 'application-id'`, `Gtk.GLArea is
|
|
475
|
+
* not a subclassable GObject type`). Measured on the macOS 15.7.9 x86_64 VM.
|
|
476
|
+
*
|
|
477
|
+
* `gi_repository_prepend_library_path()` is GI's own answer, so nothing is
|
|
478
|
+
* captured at process launch: identical on node, bun and deno, no re-exec, and the
|
|
479
|
+
* environment is left alone. The env paths elsewhere in this module stay — they
|
|
480
|
+
* still cover a dylib pulled in by ANOTHER dylib's link closure, which never
|
|
481
|
+
* passes through GI.
|
|
482
|
+
*
|
|
483
|
+
* The dirs come from `gtkSource()`, not a second opinion: the bundle's `libDir`
|
|
484
|
+
* for `bundle`, `systemGiLibraryDirs()` for `system` — the pair the re-exec
|
|
485
|
+
* composes. Mixing them is the two-copies hazard #920 records. Idempotent, and
|
|
486
|
+
* never fatal: an addon predating the binding changes nothing.
|
|
487
|
+
* @param {{ prependLibraryPath?: (p: string) => void }} native the loaded addon
|
|
488
|
+
* @returns {string[]} the directories handed to GI (empty when there was nothing to add)
|
|
489
|
+
*/
|
|
490
|
+
export function activateGiLibraryPath(native) {
|
|
491
|
+
if (libraryPathActivated) return [];
|
|
492
|
+
libraryPathActivated = true;
|
|
493
|
+
if (typeof native?.prependLibraryPath !== 'function') return [];
|
|
494
|
+
|
|
495
|
+
const source = gtkSource();
|
|
496
|
+
const dirs =
|
|
497
|
+
source === 'bundle' ? [resolveGtkRuntimeBundle()?.libDir] : source === 'system' ? systemGiLibraryDirs() : [];
|
|
498
|
+
const applied = [];
|
|
499
|
+
// LAST wins with a prepend, so walking in reverse leaves the array's own
|
|
500
|
+
// order intact in GI's search path.
|
|
501
|
+
for (const dir of dirs.filter(Boolean).reverse()) {
|
|
502
|
+
native.prependLibraryPath(dir);
|
|
503
|
+
applied.unshift(dir);
|
|
504
|
+
}
|
|
505
|
+
return applied;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/** TEST-ONLY: allow a spec to run the activation again. */
|
|
509
|
+
export function resetGiLibraryPathForTests() {
|
|
510
|
+
libraryPathActivated = false;
|
|
511
|
+
}
|
|
512
|
+
|
|
460
513
|
let activated = null; // memoize: the activation result (idempotent)
|
|
461
514
|
|
|
462
515
|
/**
|
|
@@ -502,9 +555,10 @@ export function activateBundledGtkRuntime(native) {
|
|
|
502
555
|
} else {
|
|
503
556
|
const existing = process.env.DYLD_FALLBACK_LIBRARY_PATH;
|
|
504
557
|
if (!existing || !existing.split(':').includes(bundle.libDir)) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
558
|
+
// Same composition as the re-exec above: the bundle's libdir first,
|
|
559
|
+
// then the inherited value, then dyld's default list — which this
|
|
560
|
+
// variable REPLACES rather than extends.
|
|
561
|
+
process.env.DYLD_FALLBACK_LIBRARY_PATH = composeDyldFallback([bundle.libDir]);
|
|
508
562
|
}
|
|
509
563
|
}
|
|
510
564
|
|
package/index.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ export function setErrorBuilder(
|
|
|
65
65
|
|
|
66
66
|
/** Prepend a directory to the GIRepository typelib search path. */
|
|
67
67
|
export function prependSearchPath(path: string): void;
|
|
68
|
+
/** Prepend a directory GI searches for the SHARED LIBRARY a typelib names. */
|
|
69
|
+
export function prependLibraryPath(path: string): void;
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
72
|
* Invoke a namespace-level GObject-Introspection function (not an instance
|
|
@@ -519,6 +521,7 @@ declare const native: {
|
|
|
519
521
|
getErrorDomain: typeof getErrorDomain;
|
|
520
522
|
setErrorBuilder: typeof setErrorBuilder;
|
|
521
523
|
prependSearchPath: typeof prependSearchPath;
|
|
524
|
+
prependLibraryPath: typeof prependLibraryPath;
|
|
522
525
|
callFunction: typeof callFunction;
|
|
523
526
|
callMethod: typeof callMethod;
|
|
524
527
|
hasMethod: typeof hasMethod;
|