@gtkx/runtime 1.0.0-rc.4 → 1.1.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 +5 -5
- package/dist/application-class.d.ts +37 -0
- package/dist/application-class.d.ts.map +1 -0
- package/dist/application-class.js +78 -0
- package/dist/application-class.js.map +1 -0
- package/dist/arg.d.ts +2 -1
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js +2 -1
- package/dist/arg.js.map +1 -1
- package/dist/bind.d.ts +11 -0
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +11 -0
- package/dist/bind.js.map +1 -1
- package/dist/callback.d.ts +4 -3
- package/dist/callback.d.ts.map +1 -1
- package/dist/callback.js +124 -29
- package/dist/callback.js.map +1 -1
- package/dist/closure.d.ts +26 -0
- package/dist/closure.d.ts.map +1 -0
- package/dist/closure.js +99 -0
- package/dist/closure.js.map +1 -0
- package/dist/default-application.d.ts +4 -0
- package/dist/default-application.d.ts.map +1 -0
- package/dist/default-application.js +17 -0
- package/dist/default-application.js.map +1 -0
- package/dist/descriptors.d.ts +98 -4
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +72 -6
- package/dist/descriptors.js.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/exit-hook.js +13 -0
- package/dist/exit-hook.js.map +1 -1
- package/dist/fn.d.ts +24 -2
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +67 -32
- package/dist/fn.js.map +1 -1
- package/dist/folded-lengths.d.ts +16 -0
- package/dist/folded-lengths.d.ts.map +1 -0
- package/dist/folded-lengths.js +38 -0
- package/dist/folded-lengths.js.map +1 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/library.d.ts +3 -1
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +3 -1
- package/dist/library.js.map +1 -1
- package/dist/lifecycle.d.ts +58 -11
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +95 -22
- package/dist/lifecycle.js.map +1 -1
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +19 -5
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +3 -2
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +13 -1
- package/dist/mixin.js.map +1 -1
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +4 -3
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +40 -7
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +95 -26
- package/dist/object.js.map +1 -1
- package/dist/param-spec.d.ts +11 -0
- package/dist/param-spec.d.ts.map +1 -0
- package/dist/param-spec.js +147 -0
- package/dist/param-spec.js.map +1 -0
- package/dist/promisify.d.ts.map +1 -1
- package/dist/promisify.js +3 -2
- package/dist/promisify.js.map +1 -1
- package/dist/properties.d.ts +39 -7
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +310 -43
- package/dist/properties.js.map +1 -1
- package/dist/register-class.d.ts +147 -12
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +129 -83
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +80 -21
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +86 -33
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts +11 -4
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +85 -25
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +2 -0
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js +1 -0
- package/dist/t.js.map +1 -1
- package/dist/tuple.d.ts +6 -3
- package/dist/tuple.d.ts.map +1 -1
- package/dist/tuple.js +9 -7
- package/dist/tuple.js.map +1 -1
- package/dist/type.d.ts +2 -1
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +2 -0
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +10 -1
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +99 -24
- package/dist/value.js.map +1 -1
- package/dist/vfunc-call.d.ts +37 -0
- package/dist/vfunc-call.d.ts.map +1 -0
- package/dist/vfunc-call.js +172 -0
- package/dist/vfunc-call.js.map +1 -0
- package/dist/vfunc-seeds.d.ts +12 -0
- package/dist/vfunc-seeds.d.ts.map +1 -0
- package/dist/vfunc-seeds.js +19 -0
- package/dist/vfunc-seeds.js.map +1 -0
- package/dist/vfunc.d.ts +8 -0
- package/dist/vfunc.d.ts.map +1 -0
- package/dist/vfunc.js +29 -0
- package/dist/vfunc.js.map +1 -0
- package/package.json +14 -4
- package/src/application-class.ts +126 -0
- package/src/arg.ts +2 -1
- package/src/bind.ts +11 -0
- package/src/callback.ts +178 -34
- package/src/closure.ts +136 -0
- package/src/default-application.ts +21 -0
- package/src/descriptors.ts +150 -34
- package/src/error.ts +1 -0
- package/src/exit-hook.ts +18 -0
- package/src/fn.ts +107 -36
- package/src/folded-lengths.ts +64 -0
- package/src/index.ts +21 -6
- package/src/internal.ts +2 -0
- package/src/library.ts +3 -1
- package/src/lifecycle.ts +138 -25
- package/src/listeners.ts +25 -6
- package/src/mixin.ts +15 -2
- package/src/native-value.ts +5 -3
- package/src/object.ts +134 -35
- package/src/param-spec.ts +234 -0
- package/src/promisify.ts +4 -2
- package/src/properties.ts +473 -46
- package/src/register-class.ts +386 -114
- package/src/registry.ts +169 -49
- package/src/signal.ts +116 -42
- package/src/t.ts +3 -0
- package/src/tuple.ts +18 -12
- package/src/type.ts +3 -1
- package/src/value.ts +143 -23
- package/src/vfunc-call.ts +247 -0
- package/src/vfunc-seeds.ts +36 -0
- package/src/vfunc.ts +38 -0
package/src/closure.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { type ExternalObject, type Handle, read } from "@gtkx/native";
|
|
2
|
+
import { type AnyClass } from "@gtkx/utils";
|
|
3
|
+
import { bind } from "./bind.js";
|
|
4
|
+
import { boxedT, callbackT, sizedArrayT, structT, uint32T, uint64T, voidT } from "./descriptors.js";
|
|
5
|
+
import { CLOSURE_SIZE, LIB, VALUE_SIZE, VALUE_T } from "./library.js";
|
|
6
|
+
import { getClassType, getHandle, getWrapperClass, instanceClassName, wrapHandle } from "./registry.js";
|
|
7
|
+
import { resolveBoxedType, typeIsA } from "./type.js";
|
|
8
|
+
import { fromValue, getValueType, intoValue } from "./value.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Handler backing a `GClosure`. It receives the closure's parameters already converted from their
|
|
12
|
+
* `GValue`s, and its result is written back into the closure's return `GValue` when it has one.
|
|
13
|
+
*
|
|
14
|
+
* A parameter that is itself a `GValue`, such as the target a property binding transform fills in,
|
|
15
|
+
* arrives as the caller's own `GObject.Value` rather than a copy, so writing to it is how the
|
|
16
|
+
* handler produces that parameter's value. It stops being valid once the handler returns.
|
|
17
|
+
*/
|
|
18
|
+
type ClosureCallback = (...args: never[]) => unknown;
|
|
19
|
+
|
|
20
|
+
const CCLOSURE_CALLBACK_OFFSET = CLOSURE_SIZE;
|
|
21
|
+
const N_PARAM_VALUES_INDEX = 2;
|
|
22
|
+
const MARSHAL_DATA_INDEX = 5;
|
|
23
|
+
const CLOSURE_T = boxedT("GClosure", { sharedLibrary: LIB, getTypeFnName: "g_closure_get_type" });
|
|
24
|
+
|
|
25
|
+
const OWNED_CLOSURE_T = boxedT("GClosure", {
|
|
26
|
+
ownership: "full",
|
|
27
|
+
sharedLibrary: LIB,
|
|
28
|
+
getTypeFnName: "g_closure_get_type",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const MARSHAL_VALUE_T = boxedT("GValue", {
|
|
32
|
+
sharedLibrary: LIB,
|
|
33
|
+
getTypeFnName: "g_value_get_type",
|
|
34
|
+
size: VALUE_SIZE,
|
|
35
|
+
isCallerAllocated: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const MARSHAL_T = callbackT(
|
|
39
|
+
[
|
|
40
|
+
CLOSURE_T,
|
|
41
|
+
MARSHAL_VALUE_T,
|
|
42
|
+
uint32T,
|
|
43
|
+
sizedArrayT(MARSHAL_VALUE_T, N_PARAM_VALUES_INDEX, "borrowed", VALUE_SIZE),
|
|
44
|
+
uint64T,
|
|
45
|
+
uint64T,
|
|
46
|
+
],
|
|
47
|
+
voidT,
|
|
48
|
+
{
|
|
49
|
+
hasUserData: true,
|
|
50
|
+
userDataIndex: MARSHAL_DATA_INDEX,
|
|
51
|
+
hasDestroy: true,
|
|
52
|
+
destroyKind: "closureNotify",
|
|
53
|
+
scope: "notified",
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const NESTED_VALUE_T = structT("borrowed");
|
|
58
|
+
const gCclosureNew = bind(LIB, "g_cclosure_new", [MARSHAL_T], OWNED_CLOSURE_T);
|
|
59
|
+
const gValueGetBoxed = bind(LIB, "g_value_get_boxed", [VALUE_T], NESTED_VALUE_T);
|
|
60
|
+
const gClosureRef = bind(LIB, "g_closure_ref", [CLOSURE_T], uint64T);
|
|
61
|
+
const gClosureSink = bind(LIB, "g_closure_sink", [CLOSURE_T], voidT);
|
|
62
|
+
const gClosureSetMarshal = bind(LIB, "g_closure_set_marshal", [CLOSURE_T, uint64T], voidT);
|
|
63
|
+
|
|
64
|
+
const isClosureInstance = (value: object): boolean =>
|
|
65
|
+
typeIsA(getClassType(value.constructor as AnyClass), resolveBoxedType(CLOSURE_T));
|
|
66
|
+
|
|
67
|
+
const getNestedValue = (param: ExternalObject<Handle>): object | null =>
|
|
68
|
+
wrapHandle(gValueGetBoxed(param) as ExternalObject<Handle> | null, getWrapperClass(resolveBoxedType(VALUE_T)));
|
|
69
|
+
|
|
70
|
+
const fromParamValue = (param: ExternalObject<Handle>): unknown =>
|
|
71
|
+
getValueType(param) === resolveBoxedType(VALUE_T) ? getNestedValue(param) : fromValue(param);
|
|
72
|
+
|
|
73
|
+
function describeValue(value: unknown): string {
|
|
74
|
+
if (value === null) {
|
|
75
|
+
return "null";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (typeof value !== "object") {
|
|
79
|
+
return typeof value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return instanceClassName(value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function marshalFor(callback: ClosureCallback): (...args: unknown[]) => void {
|
|
86
|
+
return (_closure: unknown, returnValue: unknown, _count: unknown, paramValues: unknown): void => {
|
|
87
|
+
const values = paramValues as ExternalObject<Handle>[];
|
|
88
|
+
const args = values.map((value) => fromParamValue(value));
|
|
89
|
+
const result = (callback as (...values: unknown[]) => unknown)(...(args as never[]));
|
|
90
|
+
|
|
91
|
+
if (returnValue !== null) {
|
|
92
|
+
intoValue(returnValue as ExternalObject<Handle>, result);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function newClosure(callback: ClosureCallback): ExternalObject<Handle> {
|
|
98
|
+
const handle = gCclosureNew(marshalFor(callback)) as ExternalObject<Handle>;
|
|
99
|
+
const marshal = read(handle, uint64T, CCLOSURE_CALLBACK_OFFSET);
|
|
100
|
+
gClosureRef(handle);
|
|
101
|
+
gClosureSink(handle);
|
|
102
|
+
gClosureSetMarshal(handle, marshal);
|
|
103
|
+
|
|
104
|
+
return handle;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Marshals a value passed where a `GObject.Closure` is expected into a closure handle: a function
|
|
109
|
+
* becomes a new `GClosure` dispatching into it, and an existing closure yields its own handle.
|
|
110
|
+
* @param value Function to wrap, or an already-built closure.
|
|
111
|
+
* @throws {ClosureMarshalError} When the value is neither.
|
|
112
|
+
*/
|
|
113
|
+
function toClosure(value: unknown): ExternalObject<Handle> {
|
|
114
|
+
if (typeof value === "function") {
|
|
115
|
+
return newClosure(value as ClosureCallback);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (typeof value === "object" && value !== null && isClosureInstance(value)) {
|
|
119
|
+
return getHandle(value);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
throw new ClosureMarshalError(`Cannot marshal ${describeValue(value)} into a GObject.Closure`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Same as {@link toClosure}, but passes a null or undefined value through as no closure at all. */
|
|
126
|
+
function tryToClosure(value: unknown): ExternalObject<Handle> | undefined {
|
|
127
|
+
return value == null ? undefined : toClosure(value);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Thrown when a value passed where a `GObject.Closure` is expected cannot be marshalled into one. */
|
|
131
|
+
class ClosureMarshalError extends TypeError {
|
|
132
|
+
/** Name callers match on when the error is caught as a plain `TypeError`. */
|
|
133
|
+
public override name = "ClosureMarshalError";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { type ClosureCallback, ClosureMarshalError, toClosure, tryToClosure };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { bind } from "./bind.js";
|
|
2
|
+
import { objectT, voidT } from "./descriptors.js";
|
|
3
|
+
import { GIO_LIB } from "./library.js";
|
|
4
|
+
import { getHandle } from "./registry.js";
|
|
5
|
+
|
|
6
|
+
const readDefaultApplication = bind(GIO_LIB, "g_application_get_default", [], objectT("borrowed"));
|
|
7
|
+
const writeDefaultApplication = bind(GIO_LIB, "g_application_set_default", [objectT("borrowed")], voidT);
|
|
8
|
+
|
|
9
|
+
const claimDefaultApplication = (application: object): void => {
|
|
10
|
+
writeDefaultApplication(getHandle(application));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const releaseDefaultApplication = (application: object): void => {
|
|
14
|
+
if (readDefaultApplication() !== application) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
writeDefaultApplication(null);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { claimDefaultApplication, releaseDefaultApplication };
|
package/src/descriptors.ts
CHANGED
|
@@ -1,43 +1,75 @@
|
|
|
1
1
|
import type { ArrayKind, Descriptor, Ownership } from "@gtkx/native";
|
|
2
2
|
import type { AnyClass } from "@gtkx/utils";
|
|
3
3
|
|
|
4
|
+
/** Descriptor variant for a `gint8`. */
|
|
4
5
|
type Int8Descriptor = Extract<Descriptor, { kind: "int8" }>;
|
|
6
|
+
/** Descriptor variant for a `guint8`. */
|
|
5
7
|
type Uint8Descriptor = Extract<Descriptor, { kind: "uint8" }>;
|
|
8
|
+
/** Descriptor variant for a `gint16`. */
|
|
6
9
|
type Int16Descriptor = Extract<Descriptor, { kind: "int16" }>;
|
|
10
|
+
/** Descriptor variant for a `guint16`. */
|
|
7
11
|
type Uint16Descriptor = Extract<Descriptor, { kind: "uint16" }>;
|
|
12
|
+
/** Descriptor variant for a `gint32`. */
|
|
8
13
|
type Int32Descriptor = Extract<Descriptor, { kind: "int32" }>;
|
|
14
|
+
/** Descriptor variant for a `guint32`. */
|
|
9
15
|
type Uint32Descriptor = Extract<Descriptor, { kind: "uint32" }>;
|
|
16
|
+
/** Descriptor variant for a `gint64` marshalled as a number. */
|
|
10
17
|
type Int64Descriptor = Extract<Descriptor, { kind: "int64" }>;
|
|
18
|
+
/** Descriptor variant for a `guint64` marshalled as a number. */
|
|
11
19
|
type Uint64Descriptor = Extract<Descriptor, { kind: "uint64" }>;
|
|
20
|
+
/** Descriptor variant for a `gint64` marshalled as a bigint. */
|
|
12
21
|
type BigInt64Descriptor = Extract<Descriptor, { kind: "bigint64" }>;
|
|
22
|
+
/** Descriptor variant for a `guint64` marshalled as a bigint. */
|
|
13
23
|
type BigUint64Descriptor = Extract<Descriptor, { kind: "biguint64" }>;
|
|
24
|
+
/** Descriptor variant for a `gfloat`. */
|
|
14
25
|
type Float32Descriptor = Extract<Descriptor, { kind: "float32" }>;
|
|
26
|
+
/** Descriptor variant for a `gdouble`. */
|
|
15
27
|
type Float64Descriptor = Extract<Descriptor, { kind: "float64" }>;
|
|
28
|
+
/** Descriptor variant for an enumeration, carrying the library and `get_type` symbol its GType comes from. */
|
|
16
29
|
type EnumDescriptor = Extract<Descriptor, { kind: "enum" }>;
|
|
30
|
+
/** Descriptor variant for a flags type, carrying the library and `get_type` symbol its GType comes from. */
|
|
17
31
|
type FlagsDescriptor = Extract<Descriptor, { kind: "flags" }>;
|
|
32
|
+
/** Descriptor variant for a `gboolean`. */
|
|
18
33
|
type BooleanDescriptor = Extract<Descriptor, { kind: "boolean" }>;
|
|
34
|
+
/** Descriptor variant for a C string. */
|
|
19
35
|
type StringDescriptor = Extract<Descriptor, { kind: "string" }>;
|
|
36
|
+
/** Descriptor variant for a `GObject`. */
|
|
20
37
|
type ObjectDescriptor = Extract<Descriptor, { kind: "object" }>;
|
|
38
|
+
/** Descriptor variant for a `gunichar`. */
|
|
21
39
|
type UnicharDescriptor = Extract<Descriptor, { kind: "unichar" }>;
|
|
40
|
+
/** Descriptor variant for the absence of a value. */
|
|
22
41
|
type VoidDescriptor = Extract<Descriptor, { kind: "void" }>;
|
|
42
|
+
/** Descriptor variant for an opaque `gpointer`. */
|
|
23
43
|
type BufferDescriptor = Extract<Descriptor, { kind: "buffer" }>;
|
|
44
|
+
/** Descriptor variant for a `GBoxed` value. */
|
|
24
45
|
type BoxedDescriptor = Extract<Descriptor, { kind: "boxed" }>;
|
|
25
46
|
|
|
47
|
+
/** Descriptor variant for a plain C struct, extended with the class its decoded value is wrapped in. */
|
|
26
48
|
type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & {
|
|
27
49
|
/** Class a decoded value is wrapped in; without it the wrapper comes from the value's own GType. */
|
|
28
50
|
wrapperClass?: AnyClass;
|
|
29
51
|
};
|
|
30
52
|
|
|
53
|
+
/** Descriptor variant for a ref-counted fundamental type, extended with the class its decoded value is wrapped in. */
|
|
31
54
|
type FundamentalDescriptor = Extract<Descriptor, { kind: "fundamental" }> & {
|
|
32
55
|
/** Class a decoded value is wrapped in; without it the wrapper comes from the type named by `typeName`. */
|
|
33
56
|
wrapperClass?: AnyClass;
|
|
34
57
|
};
|
|
35
58
|
|
|
59
|
+
/** Descriptor variant for an array of items in one of the supported container layouts. */
|
|
36
60
|
type ArrayDescriptor = Extract<Descriptor, { kind: "array" }>;
|
|
61
|
+
/** Descriptor variant for a `GHashTable`, marshalled as an array of key/value pairs. */
|
|
37
62
|
type HashTableDescriptor = Extract<Descriptor, { kind: "hashtable" }>;
|
|
63
|
+
/** Descriptor variant for a function pointer a JavaScript function is marshalled into. */
|
|
38
64
|
type CallbackDescriptor = Extract<Descriptor, { kind: "callback" }>;
|
|
65
|
+
/** Descriptor variant for a pointer to another descriptor's value, for an output or inout argument. */
|
|
39
66
|
type RefDescriptor = Extract<Descriptor, { kind: "ref" }>;
|
|
40
|
-
|
|
67
|
+
|
|
68
|
+
/** Descriptor for a `GType`: a `guint64` marked so it resolves to `G_TYPE_GTYPE` rather than an integer. */
|
|
69
|
+
type TypeDescriptor = BigUint64Descriptor & {
|
|
70
|
+
/** Distinguishes a GType from a plain `guint64` when the GLib type and the GValue type are resolved. */
|
|
71
|
+
type: true;
|
|
72
|
+
};
|
|
41
73
|
|
|
42
74
|
/** How a boxed value is stored, and where its GType and free function are resolved from. */
|
|
43
75
|
type BoxedOptions = {
|
|
@@ -57,11 +89,18 @@ type BoxedOptions = {
|
|
|
57
89
|
size?: number;
|
|
58
90
|
};
|
|
59
91
|
|
|
60
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* What the bindings do with a callback's return value, how the callee takes its closure, and how
|
|
94
|
+
* long that closure has to stay alive.
|
|
95
|
+
*/
|
|
61
96
|
type CallbackOptions = {
|
|
62
|
-
/** The callee also takes a
|
|
97
|
+
/** The callee also takes a destroy notify, which frees the closure once it is done with it. */
|
|
63
98
|
hasDestroy?: boolean;
|
|
64
|
-
/**
|
|
99
|
+
/** Signature of that destroy notify; defaults to `destroyNotify`, a one-argument `GDestroyNotify`. */
|
|
100
|
+
destroyKind?: CallbackDescriptor["destroyKind"];
|
|
101
|
+
/** The callee also takes a `user_data` pointer; without one the closure can never be freed. */
|
|
102
|
+
hasUserData?: boolean;
|
|
103
|
+
/** Position of `user_data` among the callback's own arguments, dropped before the closure is called. */
|
|
65
104
|
userDataIndex?: number;
|
|
66
105
|
/** Lifetime of the closure; defaults to `notified` when `hasDestroy` is set and `call` otherwise. */
|
|
67
106
|
scope?: CallbackDescriptor["scope"];
|
|
@@ -71,12 +110,22 @@ type CallbackOptions = {
|
|
|
71
110
|
type ArrayOptions = {
|
|
72
111
|
/** Stride in bytes between elements stored inline in the array. */
|
|
73
112
|
elementSize?: number | undefined;
|
|
113
|
+
/** Position of the argument whose buffer a cursor array points into. */
|
|
114
|
+
baseParamIndex?: number | undefined;
|
|
74
115
|
/** Position of the argument carrying the element count, for a length-bounded array. */
|
|
75
116
|
sizeParamIndex?: number | undefined;
|
|
76
117
|
/** Element count of a fixed-length array. */
|
|
77
118
|
fixedSize?: number | undefined;
|
|
78
119
|
};
|
|
79
120
|
|
|
121
|
+
/** Where a cursor array's base buffer and total length come from. */
|
|
122
|
+
type CursorBounds = {
|
|
123
|
+
/** Position of the argument holding the buffer the cursor points into. */
|
|
124
|
+
baseParamIndex: number;
|
|
125
|
+
/** Position of the argument carrying that buffer's element count. */
|
|
126
|
+
sizeParamIndex: number;
|
|
127
|
+
};
|
|
128
|
+
|
|
80
129
|
/** How a ref-counted fundamental value is named, wrapped and stored. */
|
|
81
130
|
type FundamentalOptions = {
|
|
82
131
|
/** Whether a decoded value is owned by the caller; defaults to `"borrowed"`. */
|
|
@@ -89,6 +138,12 @@ type FundamentalOptions = {
|
|
|
89
138
|
isInline?: boolean;
|
|
90
139
|
};
|
|
91
140
|
|
|
141
|
+
type FundamentalLifecycle = {
|
|
142
|
+
sharedLibrary: string;
|
|
143
|
+
refFnName: string;
|
|
144
|
+
unrefFnName: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
92
147
|
/** How a plain C struct is stored and wrapped. */
|
|
93
148
|
type StructOptions = {
|
|
94
149
|
/** The caller owns the storage the callee fills, so a decoded value is borrowed instead of copied. */
|
|
@@ -101,32 +156,57 @@ type StructOptions = {
|
|
|
101
156
|
wrapperClass?: AnyClass;
|
|
102
157
|
};
|
|
103
158
|
|
|
159
|
+
/** Descriptor for a `gint8`, marshalled as a number. */
|
|
104
160
|
const int8T: Int8Descriptor = { kind: "int8" };
|
|
161
|
+
/** Descriptor for a `guint8`, marshalled as a number. */
|
|
105
162
|
const uint8T: Uint8Descriptor = { kind: "uint8" };
|
|
163
|
+
/** Descriptor for a `gint16`, marshalled as a number. */
|
|
106
164
|
const int16T: Int16Descriptor = { kind: "int16" };
|
|
165
|
+
/** Descriptor for a `guint16`, marshalled as a number. */
|
|
107
166
|
const uint16T: Uint16Descriptor = { kind: "uint16" };
|
|
167
|
+
/** Descriptor for a `gint32`, marshalled as a number. */
|
|
108
168
|
const int32T: Int32Descriptor = { kind: "int32" };
|
|
169
|
+
/** Descriptor for a `guint32`, marshalled as a number. */
|
|
109
170
|
const uint32T: Uint32Descriptor = { kind: "uint32" };
|
|
171
|
+
/** Descriptor for a `gint64`, marshalled as a number and rejected outside the 2^53 safe range. */
|
|
110
172
|
const int64T: Int64Descriptor = { kind: "int64" };
|
|
173
|
+
/** Descriptor for a `guint64`, marshalled as a number and rejected outside the 2^53 safe range. */
|
|
111
174
|
const uint64T: Uint64Descriptor = { kind: "uint64" };
|
|
175
|
+
/** Descriptor for a `gint64`, marshalled as a bigint so the full 64-bit range survives. */
|
|
112
176
|
const bigint64T: BigInt64Descriptor = { kind: "bigint64" };
|
|
177
|
+
/** Descriptor for a `guint64`, marshalled as a bigint so the full 64-bit range survives. */
|
|
113
178
|
const biguint64T: BigUint64Descriptor = { kind: "biguint64" };
|
|
179
|
+
/** Descriptor for a `GType`, marshalled as a bigint and recognized as a GType by GValue conversion. */
|
|
114
180
|
const gtypeT: TypeDescriptor = { kind: "biguint64", type: true };
|
|
181
|
+
/** Descriptor for a `gfloat`. */
|
|
115
182
|
const float32T: Float32Descriptor = { kind: "float32" };
|
|
183
|
+
/** Descriptor for a `gdouble`. */
|
|
116
184
|
const float64T: Float64Descriptor = { kind: "float64" };
|
|
185
|
+
/** Descriptor for a `gboolean`, marshalled as a JavaScript boolean. */
|
|
117
186
|
const booleanT: BooleanDescriptor = { kind: "boolean" };
|
|
187
|
+
/** Descriptor for the absence of a value, used as the return descriptor of a `void` function. */
|
|
118
188
|
const voidT: VoidDescriptor = { kind: "void" };
|
|
189
|
+
/** Descriptor for a `gunichar`, marshalled as a single-character string or a codepoint number. */
|
|
119
190
|
const unicharT: UnicharDescriptor = { kind: "unichar" };
|
|
191
|
+
/** Descriptor for an opaque `gpointer`, taken from a typed array's memory or a numeric address. */
|
|
120
192
|
const bufferT: BufferDescriptor = { kind: "buffer" };
|
|
193
|
+
const fundamentalLifecycles: Map<string, FundamentalLifecycle> = new Map();
|
|
121
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Builds a descriptor for a C string, whose optional length sizes the caller-allocated buffer
|
|
197
|
+
* used when the string is passed by reference.
|
|
198
|
+
*/
|
|
122
199
|
const stringT = (ownership: Ownership = "borrowed", length?: number): StringDescriptor =>
|
|
123
200
|
length === undefined ? { kind: "string", ownership } : { kind: "string", ownership, length };
|
|
124
201
|
|
|
202
|
+
/** Builds a descriptor for a `GObject`, wrapped in the class registered for its runtime GType. */
|
|
125
203
|
const objectT = (ownership: Ownership = "borrowed"): ObjectDescriptor => ({ kind: "object", ownership });
|
|
126
204
|
|
|
205
|
+
/** Wraps a descriptor in a pointer to it, for an output or inout argument. */
|
|
127
206
|
const refT = (innerDescriptor: Descriptor, isInout = false): RefDescriptor =>
|
|
128
207
|
isInout ? { kind: "ref", innerDescriptor, inout: true } : { kind: "ref", innerDescriptor };
|
|
129
208
|
|
|
209
|
+
/** Builds a descriptor for a `GHashTable`, marshalled as an array of key/value pairs. */
|
|
130
210
|
const hashTableT = (
|
|
131
211
|
keyDescriptor: Descriptor,
|
|
132
212
|
valueDescriptor: Descriptor,
|
|
@@ -138,6 +218,7 @@ const hashTableT = (
|
|
|
138
218
|
ownership,
|
|
139
219
|
});
|
|
140
220
|
|
|
221
|
+
/** Builds a descriptor for an enumeration, resolving its GType from the named `get_type` function. */
|
|
141
222
|
const enumT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): EnumDescriptor => ({
|
|
142
223
|
kind: "enum",
|
|
143
224
|
sharedLibrary,
|
|
@@ -145,6 +226,7 @@ const enumT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): En
|
|
|
145
226
|
isSigned,
|
|
146
227
|
});
|
|
147
228
|
|
|
229
|
+
/** Builds a descriptor for a flags type, resolving its GType from the named `get_type` function. */
|
|
148
230
|
const flagsT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): FlagsDescriptor => ({
|
|
149
231
|
kind: "flags",
|
|
150
232
|
sharedLibrary,
|
|
@@ -182,6 +264,7 @@ const applyBoxedOptions = (result: BoxedDescriptor, options: BoxedOptions): void
|
|
|
182
264
|
}
|
|
183
265
|
};
|
|
184
266
|
|
|
267
|
+
/** Builds a descriptor for a `GBoxed` value of the named type. */
|
|
185
268
|
const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor => {
|
|
186
269
|
const result: BoxedDescriptor = {
|
|
187
270
|
kind: "boxed",
|
|
@@ -194,6 +277,7 @@ const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor =
|
|
|
194
277
|
return result;
|
|
195
278
|
};
|
|
196
279
|
|
|
280
|
+
/** Builds a descriptor for a plain C struct. */
|
|
197
281
|
const structT = (ownership: Ownership = "borrowed", options: StructOptions = {}): StructDescriptor => {
|
|
198
282
|
const result: StructDescriptor = { kind: "struct", ownership };
|
|
199
283
|
|
|
@@ -216,6 +300,16 @@ const structT = (ownership: Ownership = "borrowed", options: StructOptions = {})
|
|
|
216
300
|
return result;
|
|
217
301
|
};
|
|
218
302
|
|
|
303
|
+
const recordFundamentalLifecycle = (typeName: string, lifecycle: FundamentalLifecycle): void => {
|
|
304
|
+
if (!fundamentalLifecycles.has(typeName)) {
|
|
305
|
+
fundamentalLifecycles.set(typeName, lifecycle);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const fundamentalLifecycleFor = (typeName: string): FundamentalLifecycle | undefined =>
|
|
310
|
+
fundamentalLifecycles.get(typeName);
|
|
311
|
+
|
|
312
|
+
/** Builds a descriptor for a fundamental type whose lifetime is managed by named ref and unref functions. */
|
|
219
313
|
const fundamentalT = (
|
|
220
314
|
sharedLibrary: string,
|
|
221
315
|
refFnName: string,
|
|
@@ -227,6 +321,7 @@ const fundamentalT = (
|
|
|
227
321
|
|
|
228
322
|
if (options.typeName !== undefined) {
|
|
229
323
|
result.typeName = options.typeName;
|
|
324
|
+
recordFundamentalLifecycle(options.typeName, { sharedLibrary, refFnName, unrefFnName });
|
|
230
325
|
}
|
|
231
326
|
|
|
232
327
|
if (options.wrapperClass !== undefined) {
|
|
@@ -240,6 +335,7 @@ const fundamentalT = (
|
|
|
240
335
|
return result;
|
|
241
336
|
};
|
|
242
337
|
|
|
338
|
+
/** Builds a descriptor for an array of items in one of the supported container layouts. */
|
|
243
339
|
const arrayT = (
|
|
244
340
|
itemDescriptor: Descriptor,
|
|
245
341
|
arrayKind: ArrayKind = "array",
|
|
@@ -252,6 +348,10 @@ const arrayT = (
|
|
|
252
348
|
result.elementSize = options.elementSize;
|
|
253
349
|
}
|
|
254
350
|
|
|
351
|
+
if (options?.baseParamIndex !== undefined) {
|
|
352
|
+
result.baseParamIndex = options.baseParamIndex;
|
|
353
|
+
}
|
|
354
|
+
|
|
255
355
|
if (options?.sizeParamIndex !== undefined) {
|
|
256
356
|
result.sizeParamIndex = options.sizeParamIndex;
|
|
257
357
|
}
|
|
@@ -263,15 +363,19 @@ const arrayT = (
|
|
|
263
363
|
return result;
|
|
264
364
|
};
|
|
265
365
|
|
|
366
|
+
/** Builds a descriptor for a `GList` of items. */
|
|
266
367
|
const listT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
267
368
|
arrayT(itemDescriptor, "glist", ownership);
|
|
268
369
|
|
|
370
|
+
/** Builds a descriptor for a `GSList` of items. */
|
|
269
371
|
const slistT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
270
372
|
arrayT(itemDescriptor, "gslist", ownership);
|
|
271
373
|
|
|
374
|
+
/** Builds a descriptor for a `GPtrArray` of items. */
|
|
272
375
|
const ptrArrayT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
273
376
|
arrayT(itemDescriptor, "gptrarray", ownership);
|
|
274
377
|
|
|
378
|
+
/** Builds a descriptor for a `GArray` of items, optionally with an explicit element size. */
|
|
275
379
|
const gArrayT = (
|
|
276
380
|
itemDescriptor: Descriptor,
|
|
277
381
|
ownership: Ownership = "borrowed",
|
|
@@ -279,9 +383,11 @@ const gArrayT = (
|
|
|
279
383
|
): ArrayDescriptor =>
|
|
280
384
|
arrayT(itemDescriptor, "garray", ownership, elementSize === undefined ? undefined : { elementSize });
|
|
281
385
|
|
|
386
|
+
/** Builds a descriptor for a `GByteArray`. */
|
|
282
387
|
const byteArrayT = (ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
283
388
|
arrayT(uint8T, "gbytearray", ownership);
|
|
284
389
|
|
|
390
|
+
/** Builds a descriptor for a C array whose length is carried by another argument. */
|
|
285
391
|
const sizedArrayT = (
|
|
286
392
|
itemDescriptor: Descriptor,
|
|
287
393
|
sizeParamIndex: number,
|
|
@@ -289,6 +395,18 @@ const sizedArrayT = (
|
|
|
289
395
|
elementSize?: number,
|
|
290
396
|
): ArrayDescriptor => arrayT(itemDescriptor, "sized", ownership, { sizeParamIndex, elementSize });
|
|
291
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Builds a descriptor for an out pointer into the buffer another argument supplied, decoded as the
|
|
400
|
+
* elements from where it points to the end of that buffer.
|
|
401
|
+
*/
|
|
402
|
+
const cursorArrayT = (
|
|
403
|
+
itemDescriptor: Descriptor,
|
|
404
|
+
bounds: CursorBounds,
|
|
405
|
+
ownership: Ownership = "borrowed",
|
|
406
|
+
elementSize?: number,
|
|
407
|
+
): ArrayDescriptor => arrayT(itemDescriptor, "cursor", ownership, { ...bounds, elementSize });
|
|
408
|
+
|
|
409
|
+
/** Builds a descriptor for a C array of a fixed length. */
|
|
292
410
|
const fixedArrayT = (
|
|
293
411
|
itemDescriptor: Descriptor,
|
|
294
412
|
fixedSize: number,
|
|
@@ -296,6 +414,29 @@ const fixedArrayT = (
|
|
|
296
414
|
elementSize?: number,
|
|
297
415
|
): ArrayDescriptor => arrayT(itemDescriptor, "fixed", ownership, { fixedSize, elementSize });
|
|
298
416
|
|
|
417
|
+
const applyClosureOptions = (result: CallbackDescriptor, options: CallbackOptions): void => {
|
|
418
|
+
if (options.hasDestroy !== undefined) {
|
|
419
|
+
result.hasDestroy = options.hasDestroy;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (options.destroyKind !== undefined) {
|
|
423
|
+
result.destroyKind = options.destroyKind;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (options.hasUserData !== undefined) {
|
|
427
|
+
result.hasUserData = options.hasUserData;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (options.userDataIndex !== undefined) {
|
|
431
|
+
result.userDataIndex = options.userDataIndex;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (options.scope !== undefined) {
|
|
435
|
+
result.scope = options.scope;
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
/** Builds a descriptor for a function pointer, marshalling a JavaScript function into a native closure. */
|
|
299
440
|
const callbackT = (
|
|
300
441
|
argDescriptors: Descriptor[],
|
|
301
442
|
returnDescriptor: Descriptor,
|
|
@@ -303,17 +444,11 @@ const callbackT = (
|
|
|
303
444
|
): CallbackDescriptor => {
|
|
304
445
|
const result: CallbackDescriptor = { kind: "callback", argDescriptors, returnDescriptor };
|
|
305
446
|
|
|
306
|
-
if (options
|
|
307
|
-
result
|
|
447
|
+
if (options === undefined) {
|
|
448
|
+
return result;
|
|
308
449
|
}
|
|
309
450
|
|
|
310
|
-
|
|
311
|
-
result.userDataIndex = options.userDataIndex;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (options?.scope !== undefined) {
|
|
315
|
-
result.scope = options.scope;
|
|
316
|
-
}
|
|
451
|
+
applyClosureOptions(result, options);
|
|
317
452
|
|
|
318
453
|
return result;
|
|
319
454
|
};
|
|
@@ -344,6 +479,7 @@ export {
|
|
|
344
479
|
flagsT,
|
|
345
480
|
boxedT,
|
|
346
481
|
structT,
|
|
482
|
+
fundamentalLifecycleFor,
|
|
347
483
|
fundamentalT,
|
|
348
484
|
arrayT,
|
|
349
485
|
listT,
|
|
@@ -353,27 +489,8 @@ export {
|
|
|
353
489
|
byteArrayT,
|
|
354
490
|
sizedArrayT,
|
|
355
491
|
fixedArrayT,
|
|
492
|
+
cursorArrayT,
|
|
356
493
|
callbackT,
|
|
357
|
-
type Int8Descriptor,
|
|
358
|
-
type Uint8Descriptor,
|
|
359
|
-
type Int16Descriptor,
|
|
360
|
-
type Uint16Descriptor,
|
|
361
|
-
type Int32Descriptor,
|
|
362
|
-
type Uint32Descriptor,
|
|
363
|
-
type Int64Descriptor,
|
|
364
|
-
type Uint64Descriptor,
|
|
365
|
-
type BigInt64Descriptor,
|
|
366
|
-
type BigUint64Descriptor,
|
|
367
|
-
type Float32Descriptor,
|
|
368
|
-
type Float64Descriptor,
|
|
369
|
-
type EnumDescriptor,
|
|
370
|
-
type FlagsDescriptor,
|
|
371
|
-
type BooleanDescriptor,
|
|
372
|
-
type StringDescriptor,
|
|
373
|
-
type ObjectDescriptor,
|
|
374
|
-
type UnicharDescriptor,
|
|
375
|
-
type VoidDescriptor,
|
|
376
|
-
type BufferDescriptor,
|
|
377
494
|
type BoxedDescriptor,
|
|
378
495
|
type StructDescriptor,
|
|
379
496
|
type FundamentalDescriptor,
|
|
@@ -381,5 +498,4 @@ export {
|
|
|
381
498
|
type HashTableDescriptor,
|
|
382
499
|
type CallbackDescriptor,
|
|
383
500
|
type RefDescriptor,
|
|
384
|
-
type TypeDescriptor,
|
|
385
501
|
};
|
package/src/error.ts
CHANGED
|
@@ -18,6 +18,7 @@ type ErrorLike = Error & {
|
|
|
18
18
|
* matches wrapped GLib errors belonging to a specific error domain.
|
|
19
19
|
*/
|
|
20
20
|
type ErrorDomain<T extends Record<string, number>> = T & {
|
|
21
|
+
/** Backs `instanceof`, matching a wrapped GLib error whose domain is this one. */
|
|
21
22
|
[Symbol.hasInstance]: (value: unknown) => value is ErrorLike;
|
|
22
23
|
};
|
|
23
24
|
|
package/src/exit-hook.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
import { quit } from "./lifecycle.js";
|
|
2
2
|
|
|
3
|
+
const TERMINATION_SIGNALS: NodeJS.Signals[] = ["SIGHUP", "SIGINT", "SIGTERM"];
|
|
4
|
+
|
|
5
|
+
const isSoleHandler = (signal: NodeJS.Signals): boolean => process.listenerCount(signal) === 1;
|
|
6
|
+
|
|
7
|
+
const quitOnSignal = (signal: NodeJS.Signals): void => {
|
|
8
|
+
if (!isSoleHandler(signal)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
quit();
|
|
13
|
+
process.removeAllListeners(signal);
|
|
14
|
+
process.kill(process.pid, signal);
|
|
15
|
+
};
|
|
16
|
+
|
|
3
17
|
process.on("exit", quit);
|
|
18
|
+
|
|
19
|
+
for (const signal of TERMINATION_SIGNALS) {
|
|
20
|
+
process.on(signal, quitOnSignal);
|
|
21
|
+
}
|