@gtkx/runtime 1.2.2 → 1.4.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 +6 -4
- package/dist/arg.d.ts +6 -1
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js +2 -1
- package/dist/arg.js.map +1 -1
- package/dist/closure.d.ts.map +1 -1
- package/dist/closure.js +2 -11
- package/dist/closure.js.map +1 -1
- package/dist/descriptors.d.ts +21 -3
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +50 -21
- package/dist/descriptors.js.map +1 -1
- package/dist/field.d.ts +42 -0
- package/dist/field.d.ts.map +1 -0
- package/dist/field.js +41 -0
- package/dist/field.js.map +1 -0
- package/dist/fn.d.ts +2 -0
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +50 -10
- package/dist/fn.js.map +1 -1
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/mixin.d.ts +2 -1
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +1 -1
- package/dist/mixin.js.map +1 -1
- package/dist/native-value.d.ts +9 -3
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +86 -9
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +14 -6
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +21 -10
- package/dist/object.js.map +1 -1
- package/dist/param-spec.d.ts +32 -1
- package/dist/param-spec.d.ts.map +1 -1
- package/dist/param-spec.js +67 -5
- package/dist/param-spec.js.map +1 -1
- package/dist/promisify.d.ts +13 -1
- package/dist/promisify.d.ts.map +1 -1
- package/dist/promisify.js +14 -1
- package/dist/promisify.js.map +1 -1
- package/dist/properties.d.ts +48 -5
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +191 -20
- package/dist/properties.js.map +1 -1
- package/dist/regex.d.ts +25 -0
- package/dist/regex.d.ts.map +1 -0
- package/dist/regex.js +59 -0
- package/dist/regex.js.map +1 -0
- package/dist/register-class.d.ts +165 -15
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +175 -19
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +48 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +147 -3
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts +11 -1
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +66 -6
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +11 -0
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js +3 -0
- package/dist/t.js.map +1 -1
- package/dist/type.d.ts +2 -1
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +5 -1
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +48 -4
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +172 -16
- package/dist/value.js.map +1 -1
- package/dist/variant.d.ts +75 -26
- package/dist/variant.d.ts.map +1 -1
- package/dist/variant.js +44 -29
- package/dist/variant.js.map +1 -1
- package/package.json +5 -5
- package/src/arg.ts +6 -1
- package/src/closure.ts +2 -14
- package/src/descriptors.ts +74 -21
- package/src/field.ts +76 -0
- package/src/fn.ts +73 -17
- package/src/index.ts +46 -5
- package/src/mixin.ts +1 -1
- package/src/native-value.ts +146 -14
- package/src/object.ts +23 -11
- package/src/param-spec.ts +96 -8
- package/src/promisify.ts +27 -1
- package/src/properties.ts +280 -32
- package/src/regex.ts +92 -0
- package/src/register-class.ts +485 -42
- package/src/registry.ts +219 -4
- package/src/signal.ts +117 -4
- package/src/t.ts +13 -0
- package/src/type.ts +7 -0
- package/src/value.ts +268 -14
- package/src/variant.ts +184 -53
package/src/value.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
biguint64T,
|
|
8
8
|
booleanT,
|
|
9
9
|
boxedT,
|
|
10
|
+
byteArrayT,
|
|
10
11
|
float32T,
|
|
11
12
|
float64T,
|
|
12
13
|
type FundamentalDescriptor,
|
|
@@ -23,8 +24,27 @@ import {
|
|
|
23
24
|
} from "./descriptors.js";
|
|
24
25
|
import { LIB, PARAM_T, VALUE_SIZE, VALUE_T, VARIANT_T } from "./library.js";
|
|
25
26
|
import { toNative } from "./native-value.js";
|
|
26
|
-
import { getHandle, getWrapperClass, wrapHandle, wrapObject } from "./registry.js";
|
|
27
27
|
import {
|
|
28
|
+
INT32_MAXIMUM,
|
|
29
|
+
INT32_MINIMUM,
|
|
30
|
+
INT64_MAXIMUM,
|
|
31
|
+
INT64_MINIMUM,
|
|
32
|
+
isStringArray,
|
|
33
|
+
resolveGtype,
|
|
34
|
+
UINT64_MAXIMUM,
|
|
35
|
+
type ValueGuard,
|
|
36
|
+
} from "./param-spec.js";
|
|
37
|
+
import {
|
|
38
|
+
coerceGType,
|
|
39
|
+
describeValueKind,
|
|
40
|
+
getHandle,
|
|
41
|
+
getWrapperClass,
|
|
42
|
+
wrapFundamentalHandle,
|
|
43
|
+
wrapHandle,
|
|
44
|
+
wrapObject,
|
|
45
|
+
} from "./registry.js";
|
|
46
|
+
import {
|
|
47
|
+
getByteArrayType,
|
|
28
48
|
getStrvType,
|
|
29
49
|
isResolvableDescriptor,
|
|
30
50
|
resolveBoxedType,
|
|
@@ -53,7 +73,9 @@ import {
|
|
|
53
73
|
TYPE_UINT64,
|
|
54
74
|
TYPE_ULONG,
|
|
55
75
|
TYPE_VARIANT,
|
|
76
|
+
type TypedClass,
|
|
56
77
|
typeFundamental,
|
|
78
|
+
typeIsA,
|
|
57
79
|
typeName,
|
|
58
80
|
} from "./type.js";
|
|
59
81
|
|
|
@@ -65,6 +87,15 @@ type ValueType = {
|
|
|
65
87
|
type ValueGetter = (value: ExternalObject<Handle>) => unknown;
|
|
66
88
|
type ValueWriter = ValueType["set"];
|
|
67
89
|
type ValueNarrower = (jsValue: unknown) => unknown;
|
|
90
|
+
/**
|
|
91
|
+
* JavaScript value a `GObject.Value` can be built from without being told which GType to hold, for the
|
|
92
|
+
* parameters that take one. A string holds `gchararray`, a boolean `gboolean`, an integer within `gint`
|
|
93
|
+
* range `gint` and any other number `gdouble`, a `bigint` `gint64` or `guint64` past its range, an array
|
|
94
|
+
* of strings `GStrv`, a wrapper instance the GType it carries, and `null` a NULL `gpointer`, which is
|
|
95
|
+
* what GJS infers for it and which few callees accept. Reaching a GType inference cannot name, such as
|
|
96
|
+
* `guchar` or an enumeration, takes an explicitly initialized `GObject.Value` instead.
|
|
97
|
+
*/
|
|
98
|
+
type JsValue = string | number | bigint | boolean | string[] | TypedClass | null;
|
|
68
99
|
|
|
69
100
|
const setBoxedCache = createBindCache();
|
|
70
101
|
const setStaticBoxedCache = createBindCache();
|
|
@@ -74,7 +105,15 @@ const peekPointerCache = createBindCache();
|
|
|
74
105
|
const gValueInit = bind(LIB, "g_value_init", [VALUE_T, biguint64T], voidT);
|
|
75
106
|
const gValueCopy = bind(LIB, "g_value_copy", [VALUE_T, VALUE_T], voidT);
|
|
76
107
|
const booleanValueType = bindValueType("boolean", booleanT);
|
|
77
|
-
const
|
|
108
|
+
const boundTypeValueType = bindValueType("gtype", biguint64T);
|
|
109
|
+
|
|
110
|
+
const typeValueType: ValueType = {
|
|
111
|
+
set: (value, jsValue) => {
|
|
112
|
+
boundTypeValueType.set(value, coerceGType(jsValue));
|
|
113
|
+
},
|
|
114
|
+
get: boundTypeValueType.get,
|
|
115
|
+
};
|
|
116
|
+
|
|
78
117
|
const scharValueType = bindValueType("schar", int8T);
|
|
79
118
|
const ucharValueType = bindValueType("uchar", uint8T);
|
|
80
119
|
const intValueType = bindValueType("int", int32T);
|
|
@@ -99,6 +138,11 @@ const strvValueType: ValueType = {
|
|
|
99
138
|
get: bind(LIB, "g_value_get_boxed", [VALUE_T], arrayT(stringT("borrowed"))),
|
|
100
139
|
};
|
|
101
140
|
|
|
141
|
+
const setByteArrayBoxed = bind(LIB, "g_value_set_boxed", [VALUE_T, byteArrayT()], voidT);
|
|
142
|
+
const getBoxedPointer = bind(LIB, "g_value_get_boxed", [VALUE_T], uint64T);
|
|
143
|
+
const getBytesBoxed = bind(LIB, "g_value_get_boxed", [VALUE_T], byteArrayT());
|
|
144
|
+
const getByteItemsBoxed = bind(LIB, "g_value_get_boxed", [VALUE_T], arrayT(uint8T, "gbytearray"));
|
|
145
|
+
|
|
102
146
|
const PLAIN_VALUE_TYPES: Partial<Record<Descriptor["kind"], ValueType>> = {
|
|
103
147
|
boolean: booleanValueType,
|
|
104
148
|
string: stringValueType,
|
|
@@ -117,6 +161,19 @@ const PLAIN_VALUE_TYPES: Partial<Record<Descriptor["kind"], ValueType>> = {
|
|
|
117
161
|
object: objectValueType,
|
|
118
162
|
};
|
|
119
163
|
|
|
164
|
+
const WHOLE_NUMBER_KINDS: Set<Descriptor["kind"]> = new Set([
|
|
165
|
+
"int8",
|
|
166
|
+
"int16",
|
|
167
|
+
"int32",
|
|
168
|
+
"uint8",
|
|
169
|
+
"uint16",
|
|
170
|
+
"uint32",
|
|
171
|
+
"int64",
|
|
172
|
+
"uint64",
|
|
173
|
+
"enum",
|
|
174
|
+
"flags",
|
|
175
|
+
]);
|
|
176
|
+
|
|
120
177
|
const PLAIN_VALUE_GETTERS: Map<bigint, ValueGetter> = new Map([
|
|
121
178
|
[TYPE_BOOLEAN, booleanValueType.get],
|
|
122
179
|
[TYPE_CHAR, scharValueType.get],
|
|
@@ -184,6 +241,20 @@ const boxedValueType = (type: bigint): ValueType => {
|
|
|
184
241
|
return { set: setBoxedBind(name), get: dupBoxedBind(name) };
|
|
185
242
|
};
|
|
186
243
|
|
|
244
|
+
const byteArrayValueGetterFor = (isBytes: boolean): ValueGetter => {
|
|
245
|
+
const get = isBytes ? getBytesBoxed : getByteItemsBoxed;
|
|
246
|
+
|
|
247
|
+
return (value) => (getBoxedPointer(value) ? get(value) : null);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const byteArrayValueType = (descriptor: ArrayDescriptor): ValueType => ({
|
|
251
|
+
set: setByteArrayValue,
|
|
252
|
+
get: byteArrayValueGetterFor(descriptor.isBytes === true),
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const isByteArraySource = (jsValue: unknown): jsValue is Uint8Array | number[] =>
|
|
256
|
+
jsValue instanceof Uint8Array || Array.isArray(jsValue);
|
|
257
|
+
|
|
187
258
|
const enumOrFlagsValueType = (type: bigint): ValueType =>
|
|
188
259
|
typeFundamental(type) === TYPE_FLAGS ? flagsValueType : enumValueType;
|
|
189
260
|
|
|
@@ -277,7 +348,8 @@ const newBoxedValue = (
|
|
|
277
348
|
|
|
278
349
|
/**
|
|
279
350
|
* Duplicates the boxed value held by a GValue and returns the copy wrapped in the
|
|
280
|
-
* class
|
|
351
|
+
* class its GType resolves to, or null when the GValue holds no boxed type.
|
|
352
|
+
* A `GByteArray` payload is copied into a `Uint8Array` instead of being wrapped.
|
|
281
353
|
*/
|
|
282
354
|
function getBoxedValue(value: ExternalObject<Handle>): object | null {
|
|
283
355
|
const type = getValueType(value);
|
|
@@ -286,16 +358,54 @@ function getBoxedValue(value: ExternalObject<Handle>): object | null {
|
|
|
286
358
|
return null;
|
|
287
359
|
}
|
|
288
360
|
|
|
289
|
-
|
|
361
|
+
if (type === getByteArrayType()) {
|
|
362
|
+
return byteArrayValueGetterFor(true)(value) as Uint8Array | null;
|
|
363
|
+
}
|
|
364
|
+
|
|
290
365
|
const boxed = dupBoxedBind(getBoxedTypeName(type))(value) as ExternalObject<Handle> | null;
|
|
291
366
|
|
|
292
|
-
|
|
367
|
+
if (boxed === null) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return wrapHandle(boxed, getWrapperClass(type));
|
|
293
372
|
}
|
|
294
373
|
|
|
295
|
-
/**
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
374
|
+
/**
|
|
375
|
+
* Stores a boxed object, or null, into a GValue that holds a boxed type. A GValue holding
|
|
376
|
+
* `G_TYPE_VALUE` also takes any other {@link JsValue}, which is boxed into a nested `GObject.Value`
|
|
377
|
+
* of the GType inferred from it, and one holding a `GByteArray` also takes the bytes as a
|
|
378
|
+
* `Uint8Array` or an array of byte values.
|
|
379
|
+
* @param value Handle of an initialized value to write into.
|
|
380
|
+
* @param boxed The boxed instance, bytes, or {@link JsValue} to store.
|
|
381
|
+
* @throws {ValueMarshalError} When the value cannot hold what was passed.
|
|
382
|
+
*/
|
|
383
|
+
function setBoxedValue(value: ExternalObject<Handle>, boxed: JsValue | object): void {
|
|
384
|
+
const type = getValueType(value);
|
|
385
|
+
|
|
386
|
+
if (type === resolveBoxedType(VALUE_T)) {
|
|
387
|
+
setBoxedBind("GValue")(value, boxed === null ? null : toValueHandle(boxed));
|
|
388
|
+
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (type === getByteArrayType() && isByteArraySource(boxed)) {
|
|
393
|
+
setByteArrayBoxed(value, boxed);
|
|
394
|
+
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
setWrappedBoxedValue(value, type, boxed);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function setWrappedBoxedValue(value: ExternalObject<Handle>, type: bigint, boxed: JsValue | object): void {
|
|
402
|
+
if (boxed !== null && typeof boxed !== "object") {
|
|
403
|
+
throw new ValueMarshalError(
|
|
404
|
+
`Cannot marshal ${describeValueKind(boxed)} into a '${getBoxedTypeName(type)}' value`,
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
setBoxedBind(getBoxedTypeName(type))(value, boxed === null ? null : getHandle(boxed));
|
|
299
409
|
}
|
|
300
410
|
|
|
301
411
|
const arrayValueType = (descriptor: ArrayDescriptor): ValueType => {
|
|
@@ -303,6 +413,10 @@ const arrayValueType = (descriptor: ArrayDescriptor): ValueType => {
|
|
|
303
413
|
return strvValueType;
|
|
304
414
|
}
|
|
305
415
|
|
|
416
|
+
if (descriptor.arrayKind === "gbytearray") {
|
|
417
|
+
return byteArrayValueType(descriptor);
|
|
418
|
+
}
|
|
419
|
+
|
|
306
420
|
throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);
|
|
307
421
|
};
|
|
308
422
|
|
|
@@ -349,11 +463,17 @@ const wrappedValueGetter = (fundamental: bigint): ValueGetter | undefined => {
|
|
|
349
463
|
}
|
|
350
464
|
case TYPE_PARAM: {
|
|
351
465
|
return (value) =>
|
|
352
|
-
|
|
466
|
+
wrapFundamentalHandle(
|
|
467
|
+
paramValueType.get(value) as ExternalObject<Handle> | null,
|
|
468
|
+
getWrapperClass(TYPE_PARAM),
|
|
469
|
+
);
|
|
353
470
|
}
|
|
354
471
|
case TYPE_VARIANT: {
|
|
355
472
|
return (value) =>
|
|
356
|
-
|
|
473
|
+
wrapFundamentalHandle(
|
|
474
|
+
variantValueType.get(value) as ExternalObject<Handle> | null,
|
|
475
|
+
getWrapperClass(TYPE_VARIANT),
|
|
476
|
+
);
|
|
357
477
|
}
|
|
358
478
|
case TYPE_BOXED: {
|
|
359
479
|
return getBoxedValue;
|
|
@@ -381,6 +501,10 @@ function setStrvValue(value: ExternalObject<Handle>, nativeValue: unknown): void
|
|
|
381
501
|
setStrvBoxed(value, nativeValue ?? null);
|
|
382
502
|
}
|
|
383
503
|
|
|
504
|
+
function setByteArrayValue(value: ExternalObject<Handle>, nativeValue: unknown): void {
|
|
505
|
+
setByteArrayBoxed(value, nativeValue ?? null);
|
|
506
|
+
}
|
|
507
|
+
|
|
384
508
|
function setPointerValue(value: ExternalObject<Handle>, nativeValue: unknown): void {
|
|
385
509
|
if (nativeValue != null) {
|
|
386
510
|
throw new Error("G_TYPE_POINTER non-null values cannot be marshalled from JS");
|
|
@@ -406,7 +530,8 @@ const customFundamentalGetter = (type: bigint): ValueGetter | undefined => {
|
|
|
406
530
|
return undefined;
|
|
407
531
|
}
|
|
408
532
|
|
|
409
|
-
return (value) =>
|
|
533
|
+
return (value) =>
|
|
534
|
+
wrapFundamentalHandle(valueType.get(value) as ExternalObject<Handle> | null, getWrapperClass(type));
|
|
410
535
|
};
|
|
411
536
|
|
|
412
537
|
const customFundamentalSetter = (type: bigint): ValueType["set"] | undefined => {
|
|
@@ -456,6 +581,89 @@ function intoValue(value: ExternalObject<Handle>, jsValue: unknown): void {
|
|
|
456
581
|
valueWriterFor(getValueType(value))(value, jsValue);
|
|
457
582
|
}
|
|
458
583
|
|
|
584
|
+
const numberValueGType = (jsValue: number): bigint =>
|
|
585
|
+
Number.isSafeInteger(jsValue) && jsValue >= INT32_MINIMUM && jsValue <= INT32_MAXIMUM ? TYPE_INT : TYPE_DOUBLE;
|
|
586
|
+
|
|
587
|
+
const arrayValueGType = (jsValue: unknown[]): bigint => (isStringArray(jsValue) ? getStrvType() : TYPE_INVALID);
|
|
588
|
+
const wideValueGType = (jsValue: bigint): bigint => (jsValue > INT64_MAXIMUM ? TYPE_UINT64 : TYPE_INT64);
|
|
589
|
+
|
|
590
|
+
const bigintValueGType = (jsValue: bigint): bigint =>
|
|
591
|
+
jsValue < INT64_MINIMUM || jsValue > UINT64_MAXIMUM ? TYPE_INVALID : wideValueGType(jsValue);
|
|
592
|
+
|
|
593
|
+
const objectValueGType = (jsValue: object | null, wrapperType: bigint): bigint => {
|
|
594
|
+
if (jsValue === null) {
|
|
595
|
+
return TYPE_POINTER;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return Array.isArray(jsValue) ? arrayValueGType(jsValue) : wrapperType;
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
function inferValueGType(jsValue: unknown, wrapperType: bigint): bigint {
|
|
602
|
+
switch (typeof jsValue) {
|
|
603
|
+
case "string": {
|
|
604
|
+
return TYPE_STRING;
|
|
605
|
+
}
|
|
606
|
+
case "boolean": {
|
|
607
|
+
return TYPE_BOOLEAN;
|
|
608
|
+
}
|
|
609
|
+
case "number": {
|
|
610
|
+
return numberValueGType(jsValue);
|
|
611
|
+
}
|
|
612
|
+
case "bigint": {
|
|
613
|
+
return bigintValueGType(jsValue);
|
|
614
|
+
}
|
|
615
|
+
case "object": {
|
|
616
|
+
return objectValueGType(jsValue, wrapperType);
|
|
617
|
+
}
|
|
618
|
+
case "function":
|
|
619
|
+
case "symbol":
|
|
620
|
+
case "undefined": {
|
|
621
|
+
return TYPE_INVALID;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const marshalFailure = (jsValue: unknown): string =>
|
|
627
|
+
typeof jsValue === "bigint"
|
|
628
|
+
? `Cannot marshal ${String(jsValue)} into a GObject.Value: outside the range of gint64 and guint64`
|
|
629
|
+
: `Cannot marshal ${describeValueKind(jsValue)} into a GObject.Value`;
|
|
630
|
+
|
|
631
|
+
const wrapperGType = (jsValue: unknown): bigint =>
|
|
632
|
+
typeof jsValue === "object" && jsValue !== null ? resolveGtype(jsValue) : TYPE_INVALID;
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Marshals a value passed where a `GObject.Value` is expected into a value handle: an already-built
|
|
636
|
+
* value yields its own handle, and any other {@link JsValue} is stored in a new one initialized to the
|
|
637
|
+
* GType inferred from it.
|
|
638
|
+
* @param jsValue Value to store, or an already-built `GObject.Value`.
|
|
639
|
+
* @throws {ValueMarshalError} When no GType can be inferred from the value.
|
|
640
|
+
*/
|
|
641
|
+
function toValueHandle(jsValue: unknown): ExternalObject<Handle> {
|
|
642
|
+
const wrapperType = wrapperGType(jsValue);
|
|
643
|
+
|
|
644
|
+
if (typeIsA(wrapperType, resolveBoxedType(VALUE_T))) {
|
|
645
|
+
return getHandle(jsValue as object);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const type = inferValueGType(jsValue, wrapperType);
|
|
649
|
+
|
|
650
|
+
if (type === TYPE_INVALID) {
|
|
651
|
+
throw new ValueMarshalError(marshalFailure(jsValue));
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const value = newValueForType(type);
|
|
655
|
+
intoValue(value, jsValue);
|
|
656
|
+
|
|
657
|
+
return value;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/** Same as {@link toValueHandle}, but passes a null or undefined value through as no value at all. */
|
|
661
|
+
const tryToValueHandle = (jsValue: unknown): ExternalObject<Handle> | undefined =>
|
|
662
|
+
jsValue == null ? undefined : toValueHandle(jsValue);
|
|
663
|
+
|
|
664
|
+
const isValueDescriptor = (descriptor: Descriptor): boolean =>
|
|
665
|
+
descriptor.kind === "boxed" && descriptor.typeName === "GValue";
|
|
666
|
+
|
|
459
667
|
const resolveNativeValue = (descriptor: Descriptor, value: unknown): unknown => {
|
|
460
668
|
const isHandleKind = descriptor.kind === "object" || descriptor.kind === "boxed";
|
|
461
669
|
|
|
@@ -463,7 +671,11 @@ const resolveNativeValue = (descriptor: Descriptor, value: unknown): unknown =>
|
|
|
463
671
|
return toNative(descriptor, value);
|
|
464
672
|
}
|
|
465
673
|
|
|
466
|
-
|
|
674
|
+
if (value == null) {
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return isValueDescriptor(descriptor) ? toValueHandle(value) : getHandle(value);
|
|
467
679
|
};
|
|
468
680
|
|
|
469
681
|
const resolveValueGType = (descriptor: Descriptor, nativeValue: unknown): bigint => {
|
|
@@ -474,8 +686,13 @@ const resolveValueGType = (descriptor: Descriptor, nativeValue: unknown): bigint
|
|
|
474
686
|
return nativeValue == null ? TYPE_OBJECT : getType(nativeValue as ExternalObject<Handle>);
|
|
475
687
|
};
|
|
476
688
|
|
|
689
|
+
const toWholeNumber = (descriptor: Descriptor, value: unknown): unknown =>
|
|
690
|
+
typeof value === "number" && Number.isFinite(value) && WHOLE_NUMBER_KINDS.has(descriptor.kind)
|
|
691
|
+
? Math.trunc(value)
|
|
692
|
+
: value;
|
|
693
|
+
|
|
477
694
|
function toValue(descriptor: Descriptor, value: unknown): ExternalObject<Handle> {
|
|
478
|
-
const nativeValue = resolveNativeValue(descriptor, value);
|
|
695
|
+
const nativeValue = resolveNativeValue(descriptor, toWholeNumber(descriptor, value));
|
|
479
696
|
const type = resolveValueGType(descriptor, nativeValue);
|
|
480
697
|
const gValue = newValueForType(type);
|
|
481
698
|
resolveValueType(descriptor).set(gValue, nativeValue);
|
|
@@ -483,6 +700,13 @@ function toValue(descriptor: Descriptor, value: unknown): ExternalObject<Handle>
|
|
|
483
700
|
return gValue;
|
|
484
701
|
}
|
|
485
702
|
|
|
703
|
+
/**
|
|
704
|
+
* Reads what a `GObject.Value` holds as its JavaScript form, wrapping an object, boxed, param, variant,
|
|
705
|
+
* or fundamental payload in the class registered for its GType, and handing back a string, number,
|
|
706
|
+
* `bigint`, boolean, or array of strings for the rest.
|
|
707
|
+
* @param value Handle of an initialized value to read.
|
|
708
|
+
* @throws {Error} When the GType it holds has no JavaScript form, such as a non-null `gpointer`.
|
|
709
|
+
*/
|
|
486
710
|
function fromValue(value: ExternalObject<Handle>): unknown {
|
|
487
711
|
const type = getValueType(value);
|
|
488
712
|
const get = resolveValueGetter(type);
|
|
@@ -494,6 +718,24 @@ function fromValue(value: ExternalObject<Handle>): unknown {
|
|
|
494
718
|
return get(value);
|
|
495
719
|
}
|
|
496
720
|
|
|
721
|
+
const fromValueForDescriptor = (descriptor: Descriptor, value: ExternalObject<Handle>): unknown =>
|
|
722
|
+
descriptor.kind === "array" && descriptor.arrayKind === "gbytearray"
|
|
723
|
+
? byteArrayValueGetterFor(descriptor.isBytes === true)(value)
|
|
724
|
+
: fromValue(value);
|
|
725
|
+
|
|
726
|
+
const inferredValueGuard: ValueGuard = (jsValue) => inferValueGType(jsValue, wrapperGType(jsValue)) !== TYPE_INVALID;
|
|
727
|
+
|
|
728
|
+
const byteArrayValueGuard: ValueGuard = (jsValue) =>
|
|
729
|
+
jsValue == null || isByteArraySource(jsValue) || typeIsA(resolveGtype(jsValue), getByteArrayType());
|
|
730
|
+
|
|
731
|
+
const valueGuardOverrideFor = (valueType: bigint): ValueGuard | undefined => {
|
|
732
|
+
if (valueType === resolveBoxedType(VALUE_T)) {
|
|
733
|
+
return inferredValueGuard;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
return valueType === getByteArrayType() ? byteArrayValueGuard : undefined;
|
|
737
|
+
};
|
|
738
|
+
|
|
497
739
|
function newValueForDescriptor(descriptor: Descriptor): ExternalObject<Handle> {
|
|
498
740
|
return newValueForType(resolveDescriptorType(descriptor));
|
|
499
741
|
}
|
|
@@ -523,14 +765,26 @@ function inoutValueForBoxedDescriptor(descriptor: Descriptor, boxed: object): Ex
|
|
|
523
765
|
return newBoxedValue(descriptor, boxed, setStaticBoxedBind);
|
|
524
766
|
}
|
|
525
767
|
|
|
768
|
+
/** Thrown when a value passed where a `GObject.Value` is expected holds no GType one can be built from. */
|
|
769
|
+
class ValueMarshalError extends TypeError {
|
|
770
|
+
/** Name callers match on when the error is caught as a plain `TypeError`. */
|
|
771
|
+
public override name = "ValueMarshalError";
|
|
772
|
+
}
|
|
773
|
+
|
|
526
774
|
export {
|
|
527
775
|
getValueType,
|
|
528
776
|
intoValue,
|
|
529
777
|
copyValue,
|
|
530
778
|
getBoxedValue,
|
|
531
779
|
setBoxedValue,
|
|
780
|
+
type JsValue,
|
|
532
781
|
toValue,
|
|
782
|
+
toValueHandle,
|
|
783
|
+
tryToValueHandle,
|
|
784
|
+
ValueMarshalError,
|
|
533
785
|
fromValue,
|
|
786
|
+
fromValueForDescriptor,
|
|
787
|
+
valueGuardOverrideFor,
|
|
534
788
|
newValueForDescriptor,
|
|
535
789
|
newValueForType,
|
|
536
790
|
outValueForDescriptor,
|