@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
package/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
/** Result of requiring a GObject-Introspection namespace. */
|
|
5
5
|
export interface RequiredNamespace {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
/** The namespace name, e.g. "GLib". */
|
|
7
|
+
namespace: string;
|
|
8
|
+
/** The resolved typelib version, e.g. "2.0". */
|
|
9
|
+
version: string;
|
|
10
|
+
/** Number of top-level introspection infos in the namespace. */
|
|
11
|
+
infoCount: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -22,16 +22,16 @@ export function listInfoNames(namespace: string): string[];
|
|
|
22
22
|
|
|
23
23
|
/** The introspection kind of a top-level namespace member. */
|
|
24
24
|
export type InfoKind =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
| 'function'
|
|
26
|
+
| 'object'
|
|
27
|
+
| 'interface'
|
|
28
|
+
| 'struct'
|
|
29
|
+
| 'union'
|
|
30
|
+
| 'enum'
|
|
31
|
+
| 'flags'
|
|
32
|
+
| 'constant'
|
|
33
|
+
| 'callback'
|
|
34
|
+
| 'other';
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Classify a top-level namespace member so the L1 wrapper can decide how to
|
|
@@ -53,17 +53,14 @@ export function getEnumValues(namespace: string, name: string): Record<string, n
|
|
|
53
53
|
* For an enum type registered as a GError domain (e.g. `Gio.IOErrorEnum`), report
|
|
54
54
|
* its domain quark name + numeric quark; `null` for a plain enum.
|
|
55
55
|
*/
|
|
56
|
-
export function getErrorDomain(
|
|
57
|
-
namespace: string,
|
|
58
|
-
name: string,
|
|
59
|
-
): { name: string; quark: number } | null;
|
|
56
|
+
export function getErrorDomain(namespace: string, name: string): { name: string; quark: number } | null;
|
|
60
57
|
|
|
61
58
|
/**
|
|
62
59
|
* Register the L1 GLib.Error factory the engine calls when a GI invoke fails, so
|
|
63
60
|
* a failed sync call throws a real `GLib.Error` (instanceof, with `.matches()`).
|
|
64
61
|
*/
|
|
65
62
|
export function setErrorBuilder(
|
|
66
|
-
|
|
63
|
+
builder: (domainName: string, domainQuark: number, code: number, message: string) => Error,
|
|
67
64
|
): void;
|
|
68
65
|
|
|
69
66
|
/** Prepend a directory to the GIRepository typelib search path. */
|
|
@@ -106,12 +103,7 @@ export function hasMethod(handle: GObjectHandle, methodName: string): boolean;
|
|
|
106
103
|
* twin of `Ns.Class.method(...)`. OUT/INOUT params follow {@link callFunction}'s
|
|
107
104
|
* return-tuple convention.
|
|
108
105
|
*/
|
|
109
|
-
export function callStaticMethod(
|
|
110
|
-
namespace: string,
|
|
111
|
-
typeName: string,
|
|
112
|
-
methodName: string,
|
|
113
|
-
args?: unknown[],
|
|
114
|
-
): unknown;
|
|
106
|
+
export function callStaticMethod(namespace: string, typeName: string, methodName: string, args?: unknown[]): unknown;
|
|
115
107
|
|
|
116
108
|
/**
|
|
117
109
|
* Construct a boxed/plain struct instance — the `new <Struct>()` path (GJS
|
|
@@ -133,11 +125,7 @@ export type GObjectHandle = { readonly __nodeGiGObject: unique symbol };
|
|
|
133
125
|
* properties. Milestone 1: fundamental-typed properties (numbers, booleans,
|
|
134
126
|
* strings, enums/flags).
|
|
135
127
|
*/
|
|
136
|
-
export function newObject(
|
|
137
|
-
namespace: string,
|
|
138
|
-
typeName: string,
|
|
139
|
-
props?: Record<string, unknown>,
|
|
140
|
-
): GObjectHandle;
|
|
128
|
+
export function newObject(namespace: string, typeName: string, props?: Record<string, unknown>): GObjectHandle;
|
|
141
129
|
|
|
142
130
|
/**
|
|
143
131
|
* Opaque handle to a registered GType (from {@link registerClass}). Pass it to
|
|
@@ -147,30 +135,30 @@ export type TypeHandle = { readonly __nodeGiGType: unique symbol };
|
|
|
147
135
|
|
|
148
136
|
/** A custom GObject property declaration for {@link registerClass}. */
|
|
149
137
|
export interface PropertySpec {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
138
|
+
/** Property name (canonical, e.g. "my-prop"). */
|
|
139
|
+
name: string;
|
|
140
|
+
/** Value type. */
|
|
141
|
+
type: 'string' | 'boolean' | 'int' | 'uint' | 'int64' | 'uint64' | 'double' | 'float';
|
|
142
|
+
/** `GParamFlags` bitfield (default `G_PARAM_READWRITE`). */
|
|
143
|
+
flags?: number;
|
|
144
|
+
/** Default value (type-appropriate). */
|
|
145
|
+
default?: string | number | boolean;
|
|
146
|
+
/** Minimum (numeric types). */
|
|
147
|
+
minimum?: number;
|
|
148
|
+
/** Maximum (numeric types). */
|
|
149
|
+
maximum?: number;
|
|
162
150
|
}
|
|
163
151
|
|
|
164
152
|
/** A custom GObject signal declaration for {@link registerClass}. */
|
|
165
153
|
export interface SignalSpec {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
154
|
+
/** Signal name (e.g. "my-signal"). */
|
|
155
|
+
name: string;
|
|
156
|
+
/** Parameter types (same vocabulary as {@link PropertySpec.type}, plus "object"). */
|
|
157
|
+
paramTypes?: string[];
|
|
158
|
+
/** Return type ("void" by default). */
|
|
159
|
+
returnType?: string;
|
|
160
|
+
/** `GSignalFlags` bitfield (default `G_SIGNAL_RUN_LAST`). */
|
|
161
|
+
flags?: number;
|
|
174
162
|
}
|
|
175
163
|
|
|
176
164
|
/**
|
|
@@ -185,23 +173,23 @@ export type VFuncMap = Record<string, (this: GObjectHandle, ...args: unknown[])
|
|
|
185
173
|
|
|
186
174
|
/** Custom properties, signals + vfunc overrides installed on a {@link registerClass} subtype. */
|
|
187
175
|
export interface RegisterClassOptions {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
176
|
+
properties?: PropertySpec[];
|
|
177
|
+
signals?: SignalSpec[];
|
|
178
|
+
vfuncs?: VFuncMap;
|
|
179
|
+
/**
|
|
180
|
+
* A Gtk.Widget composite template. Either inline UI-XML (a `Uint8Array`/Buffer
|
|
181
|
+
* or a string) installed via `gtk_widget_class_set_template`, or a
|
|
182
|
+
* `"resource:///…"` path string installed via
|
|
183
|
+
* `gtk_widget_class_set_template_from_resource`. Installed in the subtype's
|
|
184
|
+
* `class_init`; `gtk_widget_init_template` runs at construction.
|
|
185
|
+
*/
|
|
186
|
+
template?: Uint8Array | string;
|
|
187
|
+
/** `gtk_widget_class_set_css_name` for the subtype (optional). */
|
|
188
|
+
cssName?: string;
|
|
189
|
+
/** Template child ids to bind + expose publicly (via `gtk_widget_get_template_child`). */
|
|
190
|
+
children?: string[];
|
|
191
|
+
/** Template child ids to bind as internal children + expose privately. */
|
|
192
|
+
internalChildren?: string[];
|
|
205
193
|
}
|
|
206
194
|
|
|
207
195
|
/**
|
|
@@ -214,10 +202,10 @@ export interface RegisterClassOptions {
|
|
|
214
202
|
* parent vtable pointer it displaces, so it can chain up via {@link callParentVfunc}.
|
|
215
203
|
*/
|
|
216
204
|
export function registerClass(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
205
|
+
name: string,
|
|
206
|
+
parentNamespace: string,
|
|
207
|
+
parentTypeName: string,
|
|
208
|
+
options?: RegisterClassOptions,
|
|
221
209
|
): TypeHandle;
|
|
222
210
|
|
|
223
211
|
/**
|
|
@@ -231,11 +219,7 @@ export function registerClass(
|
|
|
231
219
|
* OUT/INOUT argument (chain-up of those is not yet supported — a catchable throw,
|
|
232
220
|
* never a crash).
|
|
233
221
|
*/
|
|
234
|
-
export function callParentVfunc(
|
|
235
|
-
handle: GObjectHandle,
|
|
236
|
-
vfuncName: string,
|
|
237
|
-
args?: unknown[],
|
|
238
|
-
): unknown;
|
|
222
|
+
export function callParentVfunc(handle: GObjectHandle, vfuncName: string, args?: unknown[]): unknown;
|
|
239
223
|
|
|
240
224
|
/**
|
|
241
225
|
* Construct a GObject of a registered type handle (from {@link registerClass})
|
|
@@ -463,10 +447,10 @@ export function setMicrotaskDrain(drain: () => void): void;
|
|
|
463
447
|
* milestone).
|
|
464
448
|
*/
|
|
465
449
|
export function connectSignal(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
450
|
+
handle: GObjectHandle,
|
|
451
|
+
signalName: string,
|
|
452
|
+
callback: (...args: unknown[]) => unknown,
|
|
453
|
+
after?: boolean,
|
|
470
454
|
): number;
|
|
471
455
|
|
|
472
456
|
/** Emit a signal; returns the signal's return value (undefined for void signals). */
|
|
@@ -480,10 +464,7 @@ export function disconnectSignal(handle: GObjectHandle, handlerId: number): void
|
|
|
480
464
|
* name to the instance's bound JS method (engine template-callback scope).
|
|
481
465
|
*/
|
|
482
466
|
export function setTemplateCallbackResolver(
|
|
483
|
-
|
|
484
|
-
handle: GObjectHandle,
|
|
485
|
-
handlerName: string,
|
|
486
|
-
) => ((...args: unknown[]) => unknown) | undefined,
|
|
467
|
+
resolver: (handle: GObjectHandle, handlerName: string) => ((...args: unknown[]) => unknown) | undefined,
|
|
487
468
|
): void;
|
|
488
469
|
|
|
489
470
|
/**
|
|
@@ -494,7 +475,7 @@ export function setTemplateCallbackResolver(
|
|
|
494
475
|
* process (a second aborts in GLib).
|
|
495
476
|
*/
|
|
496
477
|
export function logSetWriterFunc(
|
|
497
|
-
|
|
478
|
+
writer: ((logLevel: number, fields: Record<string, Uint8Array | null>) => number) | null,
|
|
498
479
|
): void;
|
|
499
480
|
|
|
500
481
|
/** Route structured logs back to the default writer (GLib.log_set_writer_default). */
|
|
@@ -506,13 +487,13 @@ export function logSetWriterDefault(): void;
|
|
|
506
487
|
* `(binding, sourceValue) => [ok: boolean, targetValue]`. Returns the GBinding handle.
|
|
507
488
|
*/
|
|
508
489
|
export function bindPropertyFull(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
490
|
+
source: GObjectHandle,
|
|
491
|
+
sourceProperty: string,
|
|
492
|
+
target: GObjectHandle,
|
|
493
|
+
targetProperty: string,
|
|
494
|
+
flags: number,
|
|
495
|
+
transformTo: ((...args: unknown[]) => unknown) | null,
|
|
496
|
+
transformFrom: ((...args: unknown[]) => unknown) | null,
|
|
516
497
|
): GObjectHandle;
|
|
517
498
|
|
|
518
499
|
/**
|
|
@@ -520,66 +501,66 @@ export function bindPropertyFull(
|
|
|
520
501
|
* GObject.BindingGroup.bind_full). Same transform contract as {@link bindPropertyFull}.
|
|
521
502
|
*/
|
|
522
503
|
export function bindingGroupBindFull(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
504
|
+
group: GObjectHandle,
|
|
505
|
+
sourceProperty: string,
|
|
506
|
+
target: GObjectHandle,
|
|
507
|
+
targetProperty: string,
|
|
508
|
+
flags: number,
|
|
509
|
+
transformTo: ((...args: unknown[]) => unknown) | null,
|
|
510
|
+
transformFrom: ((...args: unknown[]) => unknown) | null,
|
|
530
511
|
): void;
|
|
531
512
|
|
|
532
513
|
declare const native: {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
514
|
+
requireNamespace: typeof requireNamespace;
|
|
515
|
+
listInfoNames: typeof listInfoNames;
|
|
516
|
+
findInfo: typeof findInfo;
|
|
517
|
+
getConstantValue: typeof getConstantValue;
|
|
518
|
+
getEnumValues: typeof getEnumValues;
|
|
519
|
+
getErrorDomain: typeof getErrorDomain;
|
|
520
|
+
setErrorBuilder: typeof setErrorBuilder;
|
|
521
|
+
prependSearchPath: typeof prependSearchPath;
|
|
522
|
+
callFunction: typeof callFunction;
|
|
523
|
+
callMethod: typeof callMethod;
|
|
524
|
+
hasMethod: typeof hasMethod;
|
|
525
|
+
callStaticMethod: typeof callStaticMethod;
|
|
526
|
+
constructStruct: typeof constructStruct;
|
|
527
|
+
newObject: typeof newObject;
|
|
528
|
+
registerClass: typeof registerClass;
|
|
529
|
+
constructType: typeof constructType;
|
|
530
|
+
getTemplateChild: typeof getTemplateChild;
|
|
531
|
+
getProperty: typeof getProperty;
|
|
532
|
+
setProperty: typeof setProperty;
|
|
533
|
+
hasProperty: typeof hasProperty;
|
|
534
|
+
getTypeName: typeof getTypeName;
|
|
535
|
+
getGType: typeof getGType;
|
|
536
|
+
isInstanceOf: typeof isInstanceOf;
|
|
537
|
+
isGObjectHandle: typeof isGObjectHandle;
|
|
538
|
+
newGValue: typeof newGValue;
|
|
539
|
+
callBoxedMethod: typeof callBoxedMethod;
|
|
540
|
+
isBoxedHandle: typeof isBoxedHandle;
|
|
541
|
+
boxedMemberKind: typeof boxedMemberKind;
|
|
542
|
+
getBoxedField: typeof getBoxedField;
|
|
543
|
+
setBoxedField: typeof setBoxedField;
|
|
544
|
+
boxedTypeName: typeof boxedTypeName;
|
|
545
|
+
isParamSpecHandle: typeof isParamSpecHandle;
|
|
546
|
+
paramSpecProp: typeof paramSpecProp;
|
|
547
|
+
variantNew: typeof variantNew;
|
|
548
|
+
variantUnpack: typeof variantUnpack;
|
|
549
|
+
variantGetTypeString: typeof variantGetTypeString;
|
|
550
|
+
isVariantHandle: typeof isVariantHandle;
|
|
551
|
+
startMainLoop: typeof startMainLoop;
|
|
552
|
+
iterateMainContext: typeof iterateMainContext;
|
|
553
|
+
mainContextHasPending: typeof mainContextHasPending;
|
|
554
|
+
makePumpPendingCount: typeof makePumpPendingCount;
|
|
555
|
+
pumpKick: typeof pumpKick;
|
|
556
|
+
setMicrotaskDrain: typeof setMicrotaskDrain;
|
|
557
|
+
connectSignal: typeof connectSignal;
|
|
558
|
+
emitSignal: typeof emitSignal;
|
|
559
|
+
disconnectSignal: typeof disconnectSignal;
|
|
560
|
+
setTemplateCallbackResolver: typeof setTemplateCallbackResolver;
|
|
561
|
+
logSetWriterFunc: typeof logSetWriterFunc;
|
|
562
|
+
logSetWriterDefault: typeof logSetWriterDefault;
|
|
563
|
+
bindPropertyFull: typeof bindPropertyFull;
|
|
564
|
+
bindingGroupBindFull: typeof bindingGroupBindFull;
|
|
584
565
|
};
|
|
585
566
|
export default native;
|
package/index.js
CHANGED
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
// Deno — the three runtimes that implement Node-API. Runtime-specific behaviour
|
|
12
12
|
// (the libuv main-loop bridge is Node-only) is gated in gi.js off RUNTIME below.
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
|
-
import { fileURLToPath } from 'node:url';
|
|
15
|
-
import { dirname, join } from 'node:path';
|
|
16
14
|
import { existsSync } from 'node:fs';
|
|
15
|
+
import { hostTarget, nativeCandidates, packageRoot } from './native-paths.js';
|
|
17
16
|
import {
|
|
18
17
|
activateBundledGtkRuntime,
|
|
19
18
|
maybePrependGtkRuntimeDllPath,
|
|
@@ -46,7 +45,7 @@ maybePrependGtkRuntimeDllPath();
|
|
|
46
45
|
maybeWireGtkWindowingEnv();
|
|
47
46
|
|
|
48
47
|
const require = createRequire(import.meta.url);
|
|
49
|
-
const here =
|
|
48
|
+
const here = packageRoot; // the package root, from the shared native-paths module
|
|
50
49
|
|
|
51
50
|
/**
|
|
52
51
|
* Which JS runtime we are on. The Node-API addon loads on all four: Node, Bun
|
|
@@ -61,35 +60,17 @@ const here = dirname(fileURLToPath(import.meta.url)); // package root
|
|
|
61
60
|
* @type {'bun' | 'deno' | 'gjs' | 'node'}
|
|
62
61
|
*/
|
|
63
62
|
export const RUNTIME =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
typeof globalThis.imports !== 'undefined' && typeof globalThis.print === 'function'
|
|
64
|
+
? 'gjs'
|
|
65
|
+
: typeof globalThis.Bun !== 'undefined'
|
|
66
|
+
? 'bun'
|
|
67
|
+
: typeof globalThis.Deno !== 'undefined'
|
|
68
|
+
? 'deno'
|
|
69
|
+
: 'node';
|
|
71
70
|
|
|
72
71
|
/** Whether we are on Node.js (the only runtime with the libuv main-loop bridge). */
|
|
73
72
|
export const isNodeRuntime = RUNTIME === 'node';
|
|
74
73
|
|
|
75
|
-
function nativeCandidates() {
|
|
76
|
-
const prebuild = join(here, 'prebuilds', `${process.platform}-${process.arch}`, 'node_gi.node');
|
|
77
|
-
const release = join(here, 'build', 'Release', 'node_gi.node');
|
|
78
|
-
const debug = join(here, 'build', 'Debug', 'node_gi.node');
|
|
79
|
-
// NODE_GI_NATIVE pins which binary loads. The package's own test scripts set
|
|
80
|
-
// `build` so local verification always exercises the JUST-BUILT addon — a stale
|
|
81
|
-
// staged prebuild would otherwise shadow build/Release and silently validate
|
|
82
|
-
// the wrong binary (the consumer-facing default below prefers the prebuild).
|
|
83
|
-
const prefer = process.env.NODE_GI_NATIVE;
|
|
84
|
-
if (prefer === 'build') return [release, debug, prebuild];
|
|
85
|
-
if (prefer === 'prebuild') return [prebuild];
|
|
86
|
-
if (prefer) return [prefer]; // an explicit path to a node_gi.node
|
|
87
|
-
// Default: prefer a shipped prebuild so a consumer needs no C toolchain and no
|
|
88
|
-
// node-gyp — the only install path Deno supports (it runs no postinstall build
|
|
89
|
-
// script). Fall back to a locally built addon (Release, then Debug).
|
|
90
|
-
return [prebuild, release, debug];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
74
|
// GJS host mode: the addon is loaded through the @gjsify/napi shim, not
|
|
94
75
|
// `require()`. The loader native is `globalThis.__gjsifyNapiLoadAddon`,
|
|
95
76
|
// installed by `GjsifyNapi.init()`; if another consumer (the @gjsify/napi L1)
|
|
@@ -97,40 +78,40 @@ function nativeCandidates() {
|
|
|
97
78
|
// GjsifyNapi typelib must be resolvable (GI_TYPELIB_PATH/LD_LIBRARY_PATH →
|
|
98
79
|
// the shim prebuild).
|
|
99
80
|
function gjsLoadAddon(path) {
|
|
100
|
-
|
|
101
|
-
if (typeof load !== 'function') {
|
|
102
|
-
const GjsifyNapi = globalThis.imports?.gi?.GjsifyNapi;
|
|
103
|
-
if (!GjsifyNapi || !GjsifyNapi.init()) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
'@gjsify/node-gi: GJS host mode needs the @gjsify/napi shim — the GjsifyNapi ' +
|
|
106
|
-
'typelib is not loadable (point GI_TYPELIB_PATH and LD_LIBRARY_PATH at its prebuild).',
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
load = globalThis.__gjsifyNapiLoadAddon;
|
|
81
|
+
let load = globalThis.__gjsifyNapiLoadAddon;
|
|
110
82
|
if (typeof load !== 'function') {
|
|
111
|
-
|
|
83
|
+
const GjsifyNapi = globalThis.imports?.gi?.GjsifyNapi;
|
|
84
|
+
if (!GjsifyNapi || !GjsifyNapi.init()) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
'@gjsify/node-gi: GJS host mode needs the @gjsify/napi shim — the GjsifyNapi ' +
|
|
87
|
+
'typelib is not loadable (point GI_TYPELIB_PATH and LD_LIBRARY_PATH at its prebuild).',
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
load = globalThis.__gjsifyNapiLoadAddon;
|
|
91
|
+
if (typeof load !== 'function') {
|
|
92
|
+
throw new Error('@gjsify/node-gi: GjsifyNapi.init() did not install the addon loader.');
|
|
93
|
+
}
|
|
94
|
+
// Capture-then-delete, the same no-side-channel discipline as the L1.
|
|
95
|
+
delete globalThis.__gjsifyNapiLoadAddon;
|
|
112
96
|
}
|
|
113
|
-
|
|
114
|
-
delete globalThis.__gjsifyNapiLoadAddon;
|
|
115
|
-
}
|
|
116
|
-
return load(path);
|
|
97
|
+
return load(path);
|
|
117
98
|
}
|
|
118
99
|
|
|
119
100
|
function loadNative() {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
101
|
+
for (const candidate of nativeCandidates()) {
|
|
102
|
+
if (existsSync(candidate)) {
|
|
103
|
+
return RUNTIME === 'gjs' ? gjsLoadAddon(candidate) : require(candidate);
|
|
104
|
+
}
|
|
123
105
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
);
|
|
106
|
+
throw new Error(
|
|
107
|
+
`@gjsify/node-gi: native addon not found for ${RUNTIME} on ${hostTarget()}. ` +
|
|
108
|
+
`Expected a prebuild at prebuilds/${hostTarget()}/node_gi.node or a local build. ` +
|
|
109
|
+
'Run `node-gyp rebuild` in ' +
|
|
110
|
+
here +
|
|
111
|
+
' (requires a C++ toolchain and the girepository-2.0 / glib-2.0 development headers), ' +
|
|
112
|
+
'or install a package build that ships a prebuild for your platform. ' +
|
|
113
|
+
'Under a bundled GJS app (import.meta anchors at the bundle), set NODE_GI_NATIVE to the addon path.',
|
|
114
|
+
);
|
|
134
115
|
}
|
|
135
116
|
|
|
136
117
|
const native = loadNative();
|
|
@@ -142,12 +123,13 @@ const native = loadNative();
|
|
|
142
123
|
// staged prebuilds/<platform>-<arch>/gtk/). This prepends the bundle's typelib
|
|
143
124
|
// dir to the GIRepository search path (env-free) so gi:// namespaces load with
|
|
144
125
|
// no Homebrew/system GTK. No-op on platforms without a bundle, and harmless when
|
|
145
|
-
// none is present (the addon then uses the host's GTK as before).
|
|
146
|
-
//
|
|
126
|
+
// none is present (the addon then uses the host's GTK as before). Scoped to
|
|
127
|
+
// darwin + win32 — see gtk-runtime.js + @gjsify/gtk-runtime-{darwin-arm64,
|
|
128
|
+
// darwin-x64,win32-x64}.
|
|
147
129
|
try {
|
|
148
|
-
|
|
130
|
+
activateBundledGtkRuntime(native);
|
|
149
131
|
} catch {
|
|
150
|
-
|
|
132
|
+
// Never fatal: a missing/partial bundle just leaves the host GTK in charge.
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
// ---- cross-runtime microtask checkpoint (Bun/Deno) --------------------------
|
|
@@ -172,47 +154,47 @@ try {
|
|
|
172
154
|
// own main-loop source whenever the last JS frame exits — the exact semantic
|
|
173
155
|
// this checkpoint recreates for Bun/Deno.
|
|
174
156
|
if (!isNodeRuntime && RUNTIME !== 'gjs') {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
157
|
+
try {
|
|
158
|
+
let drain = null;
|
|
159
|
+
if (RUNTIME === 'bun') {
|
|
160
|
+
// JSC: drains the VM's microtask queue; callable mid-stack by design
|
|
161
|
+
// (Bun's own processTicksAndRejections calls it from JS).
|
|
162
|
+
({ drainMicrotasks: drain } = require('bun:jsc'));
|
|
163
|
+
} else if (typeof globalThis.Deno?.internal === 'symbol') {
|
|
164
|
+
// V8: the checkpoint needs BOTH queues. core.runMicrotasks is only
|
|
165
|
+
// Isolate::PerformMicrotaskCheckpoint; Deno's node-compat
|
|
166
|
+
// process.nextTick queue is a SEPARATE deno_core queue
|
|
167
|
+
// (ext:deno_node/_next_tick.ts → core.queueNextTick) that only the
|
|
168
|
+
// runtime's own event loop drains — and that loop is paused for the
|
|
169
|
+
// whole lifetime of a blocking run(). node:stream delivers stream
|
|
170
|
+
// 'end' via process.nextTick (endReadableNT), so with a
|
|
171
|
+
// microtask-only drain any body consumption over a Readable
|
|
172
|
+
// (@gjsify/fetch consumeBody → XHR arrayBuffer/text) got its chunks
|
|
173
|
+
// (microtask-delivered) but never the end: every asset load hung at
|
|
174
|
+
// readyState 3 forever on Deno while the SAME bundle settled on Bun,
|
|
175
|
+
// whose nextTick rides JSC's microtask queue (bun:jsc
|
|
176
|
+
// drainMicrotasks covers it). core.runNextTicks mirrors node's
|
|
177
|
+
// task_queues.js runNextTicks: microtask checkpoint when no ticks
|
|
178
|
+
// are scheduled, full processTicksAndRejections (ticks + microtasks
|
|
179
|
+
// interleaved) when there are — one call, both queues. Regression:
|
|
180
|
+
// test/blocking-run-checkpoint.test.mjs.
|
|
181
|
+
const core = globalThis.Deno[globalThis.Deno.internal]?.core;
|
|
182
|
+
if (typeof core?.runNextTicks === 'function') {
|
|
183
|
+
drain = () => core.runNextTicks();
|
|
184
|
+
} else if (typeof core?.runMicrotasks === 'function') {
|
|
185
|
+
// Older deno_core without runNextTicks: microtask-only drain
|
|
186
|
+
// (pre-fix behaviour — promise continuations settle, nextTick
|
|
187
|
+
// consumers like node:stream 'end' still starve).
|
|
188
|
+
drain = () => core.runMicrotasks();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (typeof drain === 'function') native.setMicrotaskDrain(drain);
|
|
192
|
+
} catch {
|
|
193
|
+
// Unregistered ⇒ pre-fix behaviour on this runtime build: promise
|
|
194
|
+
// continuations drain only when the runtime's own loop runs
|
|
195
|
+
// (startMainContextPump); async DBus replies inside a BLOCKING run stay
|
|
196
|
+
// unavailable. Never fatal — the sync surface is unaffected.
|
|
208
197
|
}
|
|
209
|
-
if (typeof drain === 'function') native.setMicrotaskDrain(drain);
|
|
210
|
-
} catch {
|
|
211
|
-
// Unregistered ⇒ pre-fix behaviour on this runtime build: promise
|
|
212
|
-
// continuations drain only when the runtime's own loop runs
|
|
213
|
-
// (startMainContextPump); async DBus replies inside a BLOCKING run stay
|
|
214
|
-
// unavailable. Never fatal — the sync surface is unaffected.
|
|
215
|
-
}
|
|
216
198
|
}
|
|
217
199
|
|
|
218
200
|
/**
|