@gjsify/node-gi 0.13.0 → 0.21.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/README.md +818 -5
- package/binding.gyp +55 -19
- package/cairo.d.ts +187 -0
- package/cairo.js +570 -0
- package/gettext.d.ts +65 -0
- package/gettext.js +128 -0
- package/gi.d.ts +178 -0
- package/gi.js +2113 -23
- package/globals.d.ts +7 -33
- package/globals.js +55 -50
- package/gtk-runtime.d.ts +17 -0
- package/gtk-runtime.js +245 -0
- package/index.d.ts +306 -12
- package/index.js +457 -14
- package/overrides/_signals.js +167 -0
- package/overrides/gio-dbus.js +749 -0
- package/overrides/mainloop.js +60 -0
- package/overrides/package.js +167 -0
- package/package.json +45 -4
- package/src/addon.cc +99 -2074
- package/src/cairo.cc +926 -0
- package/src/calls.cc +1425 -0
- package/src/class.cc +1303 -0
- package/src/common.h +645 -0
- package/src/loop.cc +766 -0
- package/src/marshal.cc +1738 -0
- package/src/object.cc +822 -0
- package/src/private.cc +351 -0
- package/src/repo.cc +298 -0
- package/src/signals.cc +535 -0
- package/src/template.cc +116 -0
- package/src/toggle.cc +718 -0
- package/src/variant.cc +587 -0
- package/system.d.ts +49 -0
- package/system.js +116 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
|
|
2
|
+
// SPDX-FileCopyrightText: 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
|
|
3
|
+
//
|
|
4
|
+
// Adapted from GJS (refs/gjs/modules/script/mainloop.js). Copyright (c) 2012
|
|
5
|
+
// Giovanni Campagna. MIT OR LGPL-2.0-or-later.
|
|
6
|
+
// Modifications: the legacy `imports.mainloop` — a thin convenience layer over
|
|
7
|
+
// GLib.MainLoop — ported to @gjsify/node-gi. GJS builds the idle/timeout sources
|
|
8
|
+
// via GObject.source_set_closure; this port routes through GLib.idle_add /
|
|
9
|
+
// GLib.timeout_add directly instead (equivalent behavior, one less indirection —
|
|
10
|
+
// the engine marshals JS functions both as GI callbacks and as GClosures, see
|
|
11
|
+
// test/gclosure-in-args.test.mjs), keeping the same `imports.mainloop.*` surface.
|
|
12
|
+
|
|
13
|
+
const DEFAULT_IDLE_PRIORITY = 200; // GLib.PRIORITY_DEFAULT_IDLE
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Build the `imports.mainloop` object bound to the L1 GLib namespace.
|
|
17
|
+
* @param {Record<string, any>} GLib
|
|
18
|
+
* @returns {{ run(name?: string): void, quit(name?: string): void, idle_add: Function, timeout_add: Function, timeout_add_seconds: Function, source_remove: Function }}
|
|
19
|
+
*/
|
|
20
|
+
export function createMainloop(GLib) {
|
|
21
|
+
const _mainLoops = Object.create(null);
|
|
22
|
+
|
|
23
|
+
function run(name = '') {
|
|
24
|
+
if (!_mainLoops[name]) _mainLoops[name] = GLib.MainLoop.new(null, false);
|
|
25
|
+
_mainLoops[name].run();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function quit(name = '') {
|
|
29
|
+
if (!_mainLoops[name]) throw new Error('No main loop with this id');
|
|
30
|
+
|
|
31
|
+
const loop = _mainLoops[name];
|
|
32
|
+
_mainLoops[name] = null;
|
|
33
|
+
|
|
34
|
+
if (!loop.is_running()) throw new Error('Main loop was stopped already');
|
|
35
|
+
|
|
36
|
+
loop.quit();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// GJS signature is `idle_add(handler, priority)` — handler first — whereas the
|
|
40
|
+
// introspected GLib.idle_add is `(priority, handler)`; bridge the argument order.
|
|
41
|
+
function idle_add(handler, priority = DEFAULT_IDLE_PRIORITY) {
|
|
42
|
+
return GLib.idle_add(priority, handler);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function timeout_add(timeout, handler, priority = GLib.PRIORITY_DEFAULT) {
|
|
46
|
+
return GLib.timeout_add(priority, timeout, handler);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function timeout_add_seconds(timeout, handler, priority = GLib.PRIORITY_DEFAULT) {
|
|
50
|
+
return GLib.timeout_add_seconds(priority, timeout, handler);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function source_remove(id) {
|
|
54
|
+
return GLib.source_remove(id);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { run, quit, idle_add, timeout_add, timeout_add_seconds, source_remove };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default createMainloop;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
|
|
2
|
+
// SPDX-FileCopyrightText: 2013 Giovanni Campagna <scampa.giovanni@gmail.com>
|
|
3
|
+
//
|
|
4
|
+
// Adapted from GJS (refs/gjs/modules/script/package.js). Copyright (c) 2013
|
|
5
|
+
// Giovanni Campagna. MIT OR LGPL-2.0-or-later.
|
|
6
|
+
// Modifications: the legacy `imports.package` — the GJS application bootstrap
|
|
7
|
+
// (`pkg.init` / `initGettext` / `initFormat`) — ported to @gjsify/node-gi. A GNOME
|
|
8
|
+
// app's entry point does `imports.package.init({ name, version, prefix, libdir })`
|
|
9
|
+
// then `pkg.initGettext()` / `pkg.initFormat()`. The GJS original's heavy
|
|
10
|
+
// source-tree detection + GResource registration + module-search machinery is NOT
|
|
11
|
+
// load-bearing for a node-gi consumer (the app carries its own dir constants and
|
|
12
|
+
// registers its own resources — see easy6502 app-gnome resources.ts), so this is
|
|
13
|
+
// the minimal, honest init: set `globalThis.pkg`, wire `_`/`C_`/`N_` and
|
|
14
|
+
// `String.prototype.format`, and keep `imports.searchPath` / `GLib.set_prgname`
|
|
15
|
+
// calls safe. Mirrors overrides/mainloop.js's `createX(deps)` shape.
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Build the `imports.package` object bound to the L1 backend.
|
|
19
|
+
* @param {{ requireGi: Function, gettext: any, imports: Record<string, any> }} deps
|
|
20
|
+
*/
|
|
21
|
+
export function createPackage({ requireGi, gettext, imports }) {
|
|
22
|
+
const pkg = {
|
|
23
|
+
// Public fields GJS source may read. Populated by init().
|
|
24
|
+
name: undefined,
|
|
25
|
+
version: undefined,
|
|
26
|
+
prefix: undefined,
|
|
27
|
+
libdir: undefined,
|
|
28
|
+
datadir: undefined,
|
|
29
|
+
pkgdatadir: undefined,
|
|
30
|
+
pkglibdir: undefined,
|
|
31
|
+
moduledir: undefined,
|
|
32
|
+
localedir: undefined,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {{ name?: string, version?: string, prefix?: string, libdir?: string, datadir?: string }} params
|
|
36
|
+
*/
|
|
37
|
+
init(params = {}) {
|
|
38
|
+
// The accessor GJS apps use right after: `pkg.initGettext()`.
|
|
39
|
+
globalThis.pkg = pkg;
|
|
40
|
+
|
|
41
|
+
pkg.name = params.name;
|
|
42
|
+
pkg.version = params.version;
|
|
43
|
+
pkg.prefix = params.prefix;
|
|
44
|
+
pkg.libdir = params.libdir;
|
|
45
|
+
pkg.datadir = params.datadir ?? (params.prefix ? `${params.prefix}/share` : undefined);
|
|
46
|
+
|
|
47
|
+
// Installed-layout dirs — NOT load-bearing on node-gi (apps carry their own
|
|
48
|
+
// constants + register their own resources), computed for source-compat only.
|
|
49
|
+
if (pkg.name) {
|
|
50
|
+
if (pkg.datadir) {
|
|
51
|
+
pkg.pkgdatadir = `${pkg.datadir}/${pkg.name}`;
|
|
52
|
+
pkg.moduledir = pkg.pkgdatadir;
|
|
53
|
+
pkg.localedir = `${pkg.datadir}/locale`;
|
|
54
|
+
}
|
|
55
|
+
if (pkg.libdir) pkg.pkglibdir = `${pkg.libdir}/${pkg.name}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Cheap + safe: keeps ARGV[0]/app-id semantics (window-manager grouping etc.).
|
|
59
|
+
try {
|
|
60
|
+
const GLib = requireGi('GLib', '2.0');
|
|
61
|
+
if (pkg.name && typeof GLib.set_prgname === 'function') GLib.set_prgname(pkg.name);
|
|
62
|
+
} catch {
|
|
63
|
+
/* GLib not loadable in this context — skip */
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// GJS unshifts moduledir onto imports.searchPath (script-import machinery).
|
|
67
|
+
// node-gi apps use ESM + gi://, so the search path is inert here — but keep
|
|
68
|
+
// the array present + the unshift safe so source that reads it doesn't throw.
|
|
69
|
+
if (!Array.isArray(imports.searchPath)) imports.searchPath = [];
|
|
70
|
+
if (pkg.moduledir) imports.searchPath.unshift(pkg.moduledir);
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
initGettext() {
|
|
74
|
+
if (pkg.name) {
|
|
75
|
+
try {
|
|
76
|
+
gettext.bindtextdomain?.(pkg.name, pkg.localedir ?? null);
|
|
77
|
+
gettext.textdomain?.(pkg.name);
|
|
78
|
+
} catch {
|
|
79
|
+
/* passthrough gettext — no catalog, ignore */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// The globals GJS apps + compiled Blueprint use pervasively.
|
|
83
|
+
globalThis._ = (msgid) => gettext.gettext(msgid);
|
|
84
|
+
globalThis.C_ = (context, msgid) => gettext.pgettext(context, msgid);
|
|
85
|
+
globalThis.N_ = (msgid) => msgid;
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
initFormat() {
|
|
89
|
+
// GJS sets `String.prototype.format = imports.format.format` (backed by the
|
|
90
|
+
// native `_format` vprintf). node-gi has no `imports.format`, so supply an
|
|
91
|
+
// equivalent JS vprintf here (see makeVprintf).
|
|
92
|
+
const vprintf = makeVprintf();
|
|
93
|
+
Object.defineProperty(String.prototype, 'format', {
|
|
94
|
+
configurable: true,
|
|
95
|
+
writable: true,
|
|
96
|
+
enumerable: false,
|
|
97
|
+
value: function format(...args) {
|
|
98
|
+
return vprintf(this, args);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// Script-import machinery is not ported — node-gi apps use ESM + gi://. These
|
|
104
|
+
// keep the surface present for source that references them (Learn6502 does not).
|
|
105
|
+
require() {
|
|
106
|
+
/* no-op: apps import via ESM / gi:// on node-gi */
|
|
107
|
+
},
|
|
108
|
+
requireSymbol() {
|
|
109
|
+
return true;
|
|
110
|
+
},
|
|
111
|
+
checkSymbol() {
|
|
112
|
+
return true;
|
|
113
|
+
},
|
|
114
|
+
start(params = {}) {
|
|
115
|
+
pkg.init(params);
|
|
116
|
+
if (typeof params.main === 'function') params.main(globalThis.ARGV ? ['', ...globalThis.ARGV] : []);
|
|
117
|
+
},
|
|
118
|
+
run() {
|
|
119
|
+
/* the app drives its own main() on node-gi */
|
|
120
|
+
},
|
|
121
|
+
initSubmodule() {
|
|
122
|
+
/* n/a on node-gi */
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return pkg;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// A small vprintf covering the GJS `String.prototype.format` spec
|
|
130
|
+
// (refs/gjs/modules/script/format.js): `%s %d %x %f`, `%.Nf` precision, `%Ns`/`%Nd`
|
|
131
|
+
// width, `0`-padding for numerics, and `%%` → literal `%`. Positional `%N$s` is
|
|
132
|
+
// supported (GJS honours it). Learn6502 only uses `%s`; the rest is fidelity.
|
|
133
|
+
function makeVprintf() {
|
|
134
|
+
return function vprintf(fmt, args) {
|
|
135
|
+
let auto = 0;
|
|
136
|
+
return String(fmt).replace(
|
|
137
|
+
/%(?:(\d+)\$)?(0)?(\d+)?(?:\.(\d+))?([%sdxf])/g,
|
|
138
|
+
(match, pos, zero, width, prec, spec) => {
|
|
139
|
+
if (spec === '%') return '%';
|
|
140
|
+
const arg = pos !== undefined ? args[Number(pos) - 1] : args[auto++];
|
|
141
|
+
let str;
|
|
142
|
+
switch (spec) {
|
|
143
|
+
case 's':
|
|
144
|
+
str = String(arg);
|
|
145
|
+
break;
|
|
146
|
+
case 'd':
|
|
147
|
+
str = String(Math.trunc(Number(arg)));
|
|
148
|
+
break;
|
|
149
|
+
case 'x':
|
|
150
|
+
str = Math.trunc(Number(arg)).toString(16);
|
|
151
|
+
break;
|
|
152
|
+
case 'f':
|
|
153
|
+
str = prec !== undefined ? Number(arg).toFixed(Number(prec)) : String(Number(arg));
|
|
154
|
+
break;
|
|
155
|
+
default:
|
|
156
|
+
return match;
|
|
157
|
+
}
|
|
158
|
+
if (width !== undefined) {
|
|
159
|
+
const w = Number(width);
|
|
160
|
+
const pad = zero && spec !== 's' ? '0' : ' ';
|
|
161
|
+
while (str.length < w) str = pad + str;
|
|
162
|
+
}
|
|
163
|
+
return str;
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/node-gi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "GObject-Introspection runtime for Node.js — load gi:// namespaces (GLib/GObject/Gio/…) with GJS-compatible semantics. Vendored + rewritten from node-gtk under MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,6 +19,22 @@
|
|
|
19
19
|
"./globals": {
|
|
20
20
|
"types": "./globals.d.ts",
|
|
21
21
|
"default": "./globals.js"
|
|
22
|
+
},
|
|
23
|
+
"./system": {
|
|
24
|
+
"types": "./system.d.ts",
|
|
25
|
+
"default": "./system.js"
|
|
26
|
+
},
|
|
27
|
+
"./gettext": {
|
|
28
|
+
"types": "./gettext.d.ts",
|
|
29
|
+
"default": "./gettext.js"
|
|
30
|
+
},
|
|
31
|
+
"./cairo": {
|
|
32
|
+
"types": "./cairo.d.ts",
|
|
33
|
+
"default": "./cairo.js"
|
|
34
|
+
},
|
|
35
|
+
"./gtk-runtime": {
|
|
36
|
+
"types": "./gtk-runtime.d.ts",
|
|
37
|
+
"default": "./gtk-runtime.js"
|
|
22
38
|
}
|
|
23
39
|
},
|
|
24
40
|
"files": [
|
|
@@ -26,8 +42,17 @@
|
|
|
26
42
|
"index.d.ts",
|
|
27
43
|
"gi.js",
|
|
28
44
|
"gi.d.ts",
|
|
45
|
+
"gtk-runtime.js",
|
|
46
|
+
"gtk-runtime.d.ts",
|
|
29
47
|
"globals.js",
|
|
30
48
|
"globals.d.ts",
|
|
49
|
+
"system.js",
|
|
50
|
+
"system.d.ts",
|
|
51
|
+
"gettext.js",
|
|
52
|
+
"gettext.d.ts",
|
|
53
|
+
"cairo.js",
|
|
54
|
+
"cairo.d.ts",
|
|
55
|
+
"overrides",
|
|
31
56
|
"src",
|
|
32
57
|
"binding.gyp",
|
|
33
58
|
"prebuilds"
|
|
@@ -38,16 +63,32 @@
|
|
|
38
63
|
"node": "polyfill",
|
|
39
64
|
"browser": "none",
|
|
40
65
|
"nativescript": "none"
|
|
41
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"tier": 2
|
|
42
68
|
},
|
|
43
69
|
"scripts": {
|
|
44
70
|
"install": "node-gyp rebuild",
|
|
45
71
|
"build": "node-gyp rebuild",
|
|
46
72
|
"build:native": "node-gyp rebuild",
|
|
73
|
+
"build:prebuild": "node-gyp rebuild && node scripts/stage-prebuild.mjs",
|
|
47
74
|
"rebuild": "node-gyp rebuild",
|
|
48
75
|
"clean": "node-gyp clean",
|
|
49
|
-
"test": "node --test",
|
|
50
|
-
"test:node": "node --test"
|
|
76
|
+
"test": "NODE_GI_NATIVE=build node --test",
|
|
77
|
+
"test:node": "NODE_GI_NATIVE=build node --test",
|
|
78
|
+
"test:gc": "NODE_GI_NATIVE=build node --test --expose-gc",
|
|
79
|
+
"test:dbus": "dbus-run-session -- env NODE_GI_NATIVE=build node --test --expose-gc test/dbus.test.mjs test/dbus-async.test.mjs",
|
|
80
|
+
"test:bun": "node scripts/cross-runtime.mjs bun",
|
|
81
|
+
"test:conformance": "node scripts/conformance.mjs",
|
|
82
|
+
"test:gimarshalling": "node scripts/gimarshalling.mjs",
|
|
83
|
+
"test:deno": "node scripts/cross-runtime.mjs deno",
|
|
84
|
+
"test:cairo": "NODE_GI_NATIVE=build node --test test/cairo.test.mjs",
|
|
85
|
+
"test:cairo-canvas2d": "NODE_GI_NATIVE=build node --test test/cairo-canvas2d.test.mjs",
|
|
86
|
+
"test:gtk": "NODE_GI_NATIVE=build node --test test/gtk-smoke.test.mjs",
|
|
87
|
+
"test:gtk-cairo": "NODE_GI_NATIVE=build node --test test/cairo-drawfunc.test.mjs",
|
|
88
|
+
"test:adw": "NODE_GI_NATIVE=build node --test test/adw-smoke.test.mjs",
|
|
89
|
+
"test:gtk-template": "NODE_GI_NATIVE=build node --test test/gtk-template.test.mjs",
|
|
90
|
+
"test:gtk-template-callbacks": "NODE_GI_NATIVE=build node --test test/gtk-template-callbacks.test.mjs",
|
|
91
|
+
"test:gtk-template-signals": "NODE_GI_NATIVE=build node --test test/gtk-template-signals.test.mjs"
|
|
51
92
|
},
|
|
52
93
|
"dependencies": {
|
|
53
94
|
"node-addon-api": "^8.0.0"
|