@gtkx/runtime 1.2.2 → 1.3.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.
Files changed (91) hide show
  1. package/README.md +2 -1
  2. package/dist/arg.d.ts +6 -1
  3. package/dist/arg.d.ts.map +1 -1
  4. package/dist/arg.js +2 -1
  5. package/dist/arg.js.map +1 -1
  6. package/dist/closure.d.ts.map +1 -1
  7. package/dist/closure.js +2 -11
  8. package/dist/closure.js.map +1 -1
  9. package/dist/descriptors.d.ts +21 -3
  10. package/dist/descriptors.d.ts.map +1 -1
  11. package/dist/descriptors.js +50 -21
  12. package/dist/descriptors.js.map +1 -1
  13. package/dist/fn.d.ts +2 -0
  14. package/dist/fn.d.ts.map +1 -1
  15. package/dist/fn.js +50 -10
  16. package/dist/fn.js.map +1 -1
  17. package/dist/index.d.ts +11 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +10 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/mixin.d.ts +2 -1
  22. package/dist/mixin.d.ts.map +1 -1
  23. package/dist/mixin.js +1 -1
  24. package/dist/mixin.js.map +1 -1
  25. package/dist/native-value.d.ts +9 -3
  26. package/dist/native-value.d.ts.map +1 -1
  27. package/dist/native-value.js +86 -9
  28. package/dist/native-value.js.map +1 -1
  29. package/dist/object.d.ts +14 -6
  30. package/dist/object.d.ts.map +1 -1
  31. package/dist/object.js +21 -10
  32. package/dist/object.js.map +1 -1
  33. package/dist/param-spec.d.ts +31 -1
  34. package/dist/param-spec.d.ts.map +1 -1
  35. package/dist/param-spec.js +66 -5
  36. package/dist/param-spec.js.map +1 -1
  37. package/dist/promisify.d.ts +13 -1
  38. package/dist/promisify.d.ts.map +1 -1
  39. package/dist/promisify.js +14 -1
  40. package/dist/promisify.js.map +1 -1
  41. package/dist/properties.d.ts +28 -1
  42. package/dist/properties.d.ts.map +1 -1
  43. package/dist/properties.js +139 -8
  44. package/dist/properties.js.map +1 -1
  45. package/dist/regex.d.ts +25 -0
  46. package/dist/regex.d.ts.map +1 -0
  47. package/dist/regex.js +59 -0
  48. package/dist/regex.js.map +1 -0
  49. package/dist/register-class.d.ts +154 -11
  50. package/dist/register-class.d.ts.map +1 -1
  51. package/dist/register-class.js +157 -19
  52. package/dist/register-class.js.map +1 -1
  53. package/dist/registry.d.ts +48 -4
  54. package/dist/registry.d.ts.map +1 -1
  55. package/dist/registry.js +147 -3
  56. package/dist/registry.js.map +1 -1
  57. package/dist/signal.d.ts +8 -1
  58. package/dist/signal.d.ts.map +1 -1
  59. package/dist/signal.js +41 -3
  60. package/dist/signal.js.map +1 -1
  61. package/dist/type.d.ts +2 -1
  62. package/dist/type.d.ts.map +1 -1
  63. package/dist/type.js +5 -1
  64. package/dist/type.js.map +1 -1
  65. package/dist/value.d.ts +48 -4
  66. package/dist/value.d.ts.map +1 -1
  67. package/dist/value.js +172 -16
  68. package/dist/value.js.map +1 -1
  69. package/dist/variant.d.ts +75 -26
  70. package/dist/variant.d.ts.map +1 -1
  71. package/dist/variant.js +44 -29
  72. package/dist/variant.js.map +1 -1
  73. package/package.json +4 -4
  74. package/src/arg.ts +6 -1
  75. package/src/closure.ts +2 -14
  76. package/src/descriptors.ts +74 -21
  77. package/src/fn.ts +73 -17
  78. package/src/index.ts +31 -4
  79. package/src/mixin.ts +1 -1
  80. package/src/native-value.ts +146 -14
  81. package/src/object.ts +23 -11
  82. package/src/param-spec.ts +94 -8
  83. package/src/promisify.ts +27 -1
  84. package/src/properties.ts +184 -5
  85. package/src/regex.ts +92 -0
  86. package/src/register-class.ts +446 -38
  87. package/src/registry.ts +219 -4
  88. package/src/signal.ts +77 -0
  89. package/src/type.ts +7 -0
  90. package/src/value.ts +268 -14
  91. package/src/variant.ts +184 -53
package/src/registry.ts CHANGED
@@ -1,14 +1,25 @@
1
1
  import {
2
2
  type ExternalObject,
3
+ getFundamentalWrapper,
3
4
  getType,
5
+ getTypeClass,
4
6
  getWrapper,
5
7
  type Handle,
6
8
  type RegisterClassVfunc as NativeRegisterClassVfunc,
9
+ setFundamentalWrapper,
7
10
  setWrapper,
8
11
  } from "@gtkx/native";
9
12
  import { type AnyClass, walkClassChain } from "@gtkx/utils";
10
- import type { Mixin, MixinReceiver } from "./mixin.js";
11
- import { TYPE_INVALID, type TypedClass, typeInterfaces, typeIsA, typeName, typeParent } from "./type.js";
13
+ import { copyLayerMembers, type Mixin, type MixinReceiver } from "./mixin.js";
14
+ import {
15
+ TYPE_INVALID,
16
+ TYPE_OBJECT,
17
+ type TypedClass,
18
+ typeInterfaces,
19
+ typeIsA,
20
+ typeName,
21
+ typeParent,
22
+ } from "./type.js";
12
23
 
13
24
  /**
14
25
  * Static side of class `C` with its construct signature preserved but the members named `K`
@@ -58,6 +69,11 @@ type VfuncDescriptor = {
58
69
  */
59
70
  type VfuncRegistry = Record<string, VfuncDescriptor>;
60
71
  type WrapperBinding = (handle: ExternalObject<Handle>, instance: object) => void;
72
+ /**
73
+ * Picks the wrapper class for one handle of a registered type, such as a subclass keyed on a tag the
74
+ * handle carries.
75
+ */
76
+ type WrapperClassResolver = (handle: ExternalObject<Handle>) => AnyClass;
61
77
 
62
78
  /**
63
79
  * How one property an interface declares reaches the vtable, given as the interface's own accessor
@@ -88,6 +104,8 @@ type InterfaceLayout = {
88
104
  };
89
105
 
90
106
  const classRegistry: Map<bigint, AnyClass> = new Map();
107
+ const classStructRegistry: Map<bigint, AnyClass> = new Map();
108
+ const composedClassStructRegistry: Map<bigint, AnyClass> = new Map();
91
109
  const interfaceMixinRegistry: Map<bigint, Mixin> = new Map();
92
110
  const composedClassRegistry: Map<bigint, AnyClass> = new Map();
93
111
  const handleMap: WeakMap<object, ExternalObject<Handle>> = new WeakMap();
@@ -95,6 +113,8 @@ const vfuncRegistry: WeakMap<object, VfuncRegistry> = new WeakMap();
95
113
  const interfaceLayoutRegistry: Map<bigint, InterfaceLayout> = new Map();
96
114
  const wrapperClasses: WeakSet<AnyClass> = new WeakSet();
97
115
  const derivedClasses: WeakSet<AnyClass> = new WeakSet();
116
+ const typeClassHandles: Map<bigint, ExternalObject<Handle>> = new Map();
117
+ const wrapperClassResolvers: WeakMap<AnyClass, WrapperClassResolver> = new WeakMap();
98
118
 
99
119
  function setClassType(cls: AnyClass, type: bigint): void {
100
120
  (cls.prototype as { [K in keyof TypedClass]: TypedClass[K] }).__type__ = type;
@@ -127,6 +147,16 @@ function getInstanceType(instance: object): bigint {
127
147
  return handle === undefined ? TYPE_INVALID : getType(handle);
128
148
  }
129
149
 
150
+ function coerceGType(value: unknown): unknown {
151
+ if (typeof value !== "function") {
152
+ return value;
153
+ }
154
+
155
+ const type = getClassType(value as AnyClass);
156
+
157
+ return type === TYPE_INVALID ? value : type;
158
+ }
159
+
130
160
  function registerClassType(cls: AnyClass, type: bigint): void {
131
161
  if (type === TYPE_INVALID) {
132
162
  return;
@@ -156,10 +186,154 @@ function registerWrapperClass(cls: AnyClass, type: bigint, vfuncs?: VfuncRegistr
156
186
  }
157
187
  }
158
188
 
189
+ /**
190
+ * Lets a class registered with `registerWrapperClass` pick a subclass for each handle it wraps, for
191
+ * types whose one GType covers several C-level subtypes, the way a cairo surface reports image or
192
+ * recording through `cairo_surface_get_type`. The resolver runs when a handle is wrapped as that class
193
+ * explicitly, the way a boxed value a binding hands back is; a wrapper resolved from a handle's runtime
194
+ * GType never consults it, and a subclass passed to `wrapHandle` directly is used as given.
195
+ * @param cls Registered wrapper class whose handles the resolver classifies.
196
+ * @param resolver Returns the class to instantiate for one handle, `cls` itself included.
197
+ * @throws If `cls` is not a registered wrapper class.
198
+ */
199
+ function registerWrapperClassResolver(cls: AnyClass, resolver: WrapperClassResolver): void {
200
+ if (!wrapperClasses.has(cls)) {
201
+ throw new Error(
202
+ `Cannot register a wrapper class resolver for ${cls.name}: ` +
203
+ "register the class with registerWrapperClass first",
204
+ );
205
+ }
206
+
207
+ wrapperClassResolvers.set(cls, resolver);
208
+ }
209
+
159
210
  function markDerivedClass(cls: AnyClass): void {
160
211
  derivedClasses.add(cls);
161
212
  }
162
213
 
214
+ /**
215
+ * Registers the wrapper class of a type's class struct, such as `Gtk.WidgetClass` for `Gtk.Widget`,
216
+ * so `registerClass` can hand a `classInit` hook the new type's class struct wrapped in it.
217
+ * @param cls Wrapper class of the type's instances, already registered through
218
+ * `registerWrapperClass`.
219
+ * @param structClass Wrapper class of the type's class struct.
220
+ */
221
+ function registerClassStruct(cls: AnyClass, structClass: AnyClass): void {
222
+ const type = getClassType(cls);
223
+
224
+ if (type !== TYPE_INVALID) {
225
+ classStructRegistry.set(type, structClass);
226
+ }
227
+ }
228
+
229
+ function collectClassStructClasses(type: bigint): AnyClass[] {
230
+ const structs: AnyClass[] = [];
231
+ let current = type;
232
+
233
+ while (current !== TYPE_INVALID) {
234
+ const structClass = classStructRegistry.get(current);
235
+
236
+ if (structClass !== undefined) {
237
+ structs.push(structClass);
238
+ }
239
+
240
+ current = typeParent(current);
241
+ }
242
+
243
+ return structs;
244
+ }
245
+
246
+ function composeClassStructClass(structs: AnyClass[]): AnyClass | undefined {
247
+ const [nearest, ...ancestors] = structs;
248
+
249
+ if (nearest === undefined || ancestors.length === 0) {
250
+ return nearest;
251
+ }
252
+
253
+ const composed: AnyClass = class extends nearest {};
254
+ Object.defineProperty(composed, "name", { value: nearest.name });
255
+
256
+ for (const structClass of ancestors) {
257
+ copyLayerMembers(composed, structClass.prototype);
258
+ }
259
+
260
+ return composed;
261
+ }
262
+
263
+ function getClassStructClass(type: bigint): AnyClass | undefined {
264
+ const cached = composedClassStructRegistry.get(type);
265
+
266
+ if (cached !== undefined) {
267
+ return cached;
268
+ }
269
+
270
+ const composed = composeClassStructClass(collectClassStructClasses(type));
271
+
272
+ if (composed !== undefined) {
273
+ composedClassStructRegistry.set(type, composed);
274
+ }
275
+
276
+ return composed;
277
+ }
278
+
279
+ function peekedTypeLabel(type: bigint | AnyClass, gtype: bigint): string {
280
+ const name = typeName(gtype);
281
+
282
+ if (name !== null) {
283
+ return name;
284
+ }
285
+
286
+ return typeof type === "bigint" ? String(type) : type.name;
287
+ }
288
+
289
+ function getTypeClassHandle(gtype: bigint): ExternalObject<Handle> {
290
+ const cached = typeClassHandles.get(gtype);
291
+
292
+ if (cached !== undefined) {
293
+ return cached;
294
+ }
295
+
296
+ const handle = getTypeClass(gtype);
297
+ typeClassHandles.set(gtype, handle);
298
+
299
+ return handle;
300
+ }
301
+
302
+ /**
303
+ * Returns a GObject type's class struct, wrapped in the class-struct wrapper classes registered
304
+ * for the type's ancestry, such as `Gtk.WidgetClass` composed with `GObject.ObjectClass` for a
305
+ * widget type. The class is referenced so it exists even before the type's first instance, and
306
+ * the reference is deliberately never released: once created, a class struct lives for the rest
307
+ * of the process. Backs the `peek` statics of generated GTypeStruct wrappers, such as
308
+ * `GObject.ObjectClass.peek` and `Gtk.WidgetClass.peek`.
309
+ *
310
+ * @param type GType to peek the class struct of, or a registered wrapper class of the type.
311
+ * @param base When given, wrapper class of the type the peeked type must derive from; the peek
312
+ * throws for a type outside that lineage. Without it any GObject type is accepted.
313
+ * @returns The wrapped class struct.
314
+ */
315
+ function peekTypeClass(type: bigint | AnyClass, base?: AnyClass): object {
316
+ const gtype = typeof type === "bigint" ? type : getClassType(type);
317
+
318
+ if (!typeIsA(gtype, TYPE_OBJECT)) {
319
+ throw new TypeError(`peekTypeClass: '${peekedTypeLabel(type, gtype)}' is not a GObject type`);
320
+ }
321
+
322
+ if (base !== undefined && !typeIsA(gtype, getClassType(base))) {
323
+ throw new TypeError(`peekTypeClass: '${peekedTypeLabel(type, gtype)}' does not derive from '${base.name}'`);
324
+ }
325
+
326
+ const structClass = getClassStructClass(gtype);
327
+
328
+ if (structClass === undefined) {
329
+ throw new TypeError(
330
+ `peekTypeClass: no ancestor of '${peekedTypeLabel(type, gtype)}' registers a class struct wrapper`,
331
+ );
332
+ }
333
+
334
+ return wrapHandle(getTypeClassHandle(gtype), structClass);
335
+ }
336
+
163
337
  function resolveAncestorType(ancestor: AnyClass): bigint | undefined {
164
338
  if (derivedClasses.has(ancestor) || !wrapperClasses.has(ancestor)) {
165
339
  return undefined;
@@ -204,8 +378,9 @@ function registerInterface(cls: AnyClass, type: bigint, mixin: Mixin, layout?: I
204
378
  * Wraps a native handle in a JS wrapper instance. With no class, resolves and
205
379
  * reuses the wrapper for the handle's runtime GType (composing interface mixins),
206
380
  * and hands back an instance that already carries a handle unchanged; with an
207
- * explicit class, creates a bare instance backed by the handle. Returns null for
208
- * a null or undefined handle.
381
+ * explicit class, creates a bare instance backed by the handle, of the subclass the
382
+ * class's `registerWrapperClassResolver` resolver picks when it has one. Returns null
383
+ * for a null or undefined handle.
209
384
  * @param handle Native handle to wrap.
210
385
  * @param cls Wrapper class to instantiate, or omitted to resolve it from the runtime type.
211
386
  */
@@ -229,8 +404,27 @@ function wrapHandle(handle: ExternalObject<Handle> | null | undefined, cls?: Any
229
404
  return getOrCreateWrapper(handle);
230
405
  }
231
406
 
407
+ const resolver = wrapperClassResolvers.get(cls);
408
+ const instance: object = Object.create((resolver === undefined ? cls : resolver(handle)).prototype) as object;
409
+ setHandle(instance, handle);
410
+
411
+ return instance;
412
+ }
413
+
414
+ function wrapFundamentalHandle(handle: ExternalObject<Handle> | null | undefined, cls: AnyClass): object | null {
415
+ if (handle === null || handle === undefined) {
416
+ return null;
417
+ }
418
+
419
+ const existing = getFundamentalWrapper(handle);
420
+
421
+ if (existing) {
422
+ return existing;
423
+ }
424
+
232
425
  const instance: object = Object.create(cls.prototype) as object;
233
426
  setHandle(instance, handle);
427
+ setFundamentalWrapper(handle, instance);
234
428
 
235
429
  return instance;
236
430
  }
@@ -378,6 +572,18 @@ function instanceClassName(instance: object): string {
378
572
  return (instance as { constructor?: { name?: string } }).constructor?.name ?? "object";
379
573
  }
380
574
 
575
+ function describeValueKind(value: unknown): string {
576
+ if (value === null) {
577
+ return "null";
578
+ }
579
+
580
+ if (typeof value !== "object") {
581
+ return typeof value;
582
+ }
583
+
584
+ return instanceClassName(value);
585
+ }
586
+
381
587
  /** Returns the native handle bound to a wrapper instance, throwing if none is set. */
382
588
  function getHandle(instance: object): ExternalObject<Handle> {
383
589
  const handle = handleMap.get(instance);
@@ -420,12 +626,20 @@ function getInterfaceProperties(type: bigint): Record<string, InterfaceProperty>
420
626
  }
421
627
 
422
628
  export {
629
+ coerceGType,
630
+ describeValueKind,
631
+ getClassStructClass,
423
632
  getClassType,
424
633
  getInstanceType,
634
+ getTypeClassHandle,
425
635
  markDerivedClass,
636
+ peekTypeClass,
637
+ registerClassStruct,
426
638
  registerClassType,
427
639
  registerWrapperClass,
640
+ registerWrapperClassResolver,
428
641
  registerInterface,
642
+ wrapFundamentalHandle,
429
643
  wrapHandle,
430
644
  getWrapperClass,
431
645
  resolveWrapperClass,
@@ -443,4 +657,5 @@ export {
443
657
  type InterfaceProperty,
444
658
  type StaticBase,
445
659
  type VfuncDescriptor,
660
+ type WrapperClassResolver,
446
661
  };
package/src/signal.ts CHANGED
@@ -3,10 +3,12 @@ import type { TypedClass } from "./type.js";
3
3
  import { type Arg, isCallerAllocatedArg, isInoutArg, isOutputArg } from "./arg.js";
4
4
  import { bind, createBindCache } from "./bind.js";
5
5
  import { wrapCallback } from "./callback.js";
6
+ import { toClosure } from "./closure.js";
6
7
  import {
7
8
  arrayT,
8
9
  biguint64T,
9
10
  booleanT,
11
+ boxedT,
10
12
  type CallbackDescriptor,
11
13
  objectT,
12
14
  stringT,
@@ -21,7 +23,9 @@ import {
21
23
  fromValue,
22
24
  getBoxedValue,
23
25
  inoutValueForBoxedDescriptor,
26
+ intoValue,
24
27
  newValueForDescriptor,
28
+ newValueForType,
25
29
  outValueForBoxedDescriptor,
26
30
  outValueForDescriptor,
27
31
  toValue,
@@ -30,6 +34,11 @@ import {
30
34
  /** Function invoked when a connected GObject signal is emitted. */
31
35
  type SignalHandler = (...args: unknown[]) => unknown;
32
36
 
37
+ type DeclaredSignalTypes = {
38
+ paramTypes: bigint[];
39
+ returnType?: bigint;
40
+ };
41
+
33
42
  /** The marshalling and handler that make up a single signal connection. */
34
43
  type SignalConnectSpec = {
35
44
  /**
@@ -77,6 +86,21 @@ const gSignalHandlerIsConnected = bind(
77
86
  );
78
87
 
79
88
  const gSignalHandlerDisconnect = bind(LIB, "g_signal_handler_disconnect", [objectT("borrowed"), uint64T], voidT);
89
+ const CLOSURE_T = boxedT("GClosure", { sharedLibrary: LIB, getTypeFnName: "g_closure_get_type" });
90
+
91
+ const gSignalConnectClosure = bind(
92
+ LIB,
93
+ "g_signal_connect_closure",
94
+ [objectT("borrowed"), stringT("borrowed"), CLOSURE_T, booleanT],
95
+ uint64T,
96
+ );
97
+
98
+ const gSignalOverrideClassClosure = bind(
99
+ LIB,
100
+ "g_signal_override_class_closure",
101
+ [uint32T, biguint64T, CLOSURE_T],
102
+ voidT,
103
+ );
80
104
 
81
105
  /** Returns the signal name without its detail suffix (the part after `::`). */
82
106
  const getSignalBaseName = (signal: string): string => {
@@ -208,6 +232,55 @@ function connectSignal(instance: object, signal: string, spec: SignalConnectSpec
208
232
  return handlerId;
209
233
  }
210
234
 
235
+ function overrideSignalClassClosure(type: bigint, signal: string, handler: SignalHandler): void {
236
+ const signalId = gSignalLookup(signal, type) as number;
237
+
238
+ if (signalId === 0) {
239
+ return;
240
+ }
241
+
242
+ gSignalOverrideClassClosure(signalId, type, toClosure(handler));
243
+ }
244
+
245
+ function connectClosureSignal(instance: object, signal: string, handler: SignalHandler, isAfter: boolean): number {
246
+ const closure = toClosure((...args: unknown[]) => Reflect.apply(handler, null, args.slice(1)));
247
+ const handlerId = gSignalConnectClosure(getHandle(instance), signal, closure, isAfter) as number;
248
+ trackConnection(instance, getSignalBaseName(signal), handlerId);
249
+
250
+ return handlerId;
251
+ }
252
+
253
+ function emitDeclaredSignal(instance: object, signal: string, types: DeclaredSignalTypes, args: unknown[]): unknown {
254
+ const { paramTypes, returnType } = types;
255
+
256
+ if (args.length !== paramTypes.length) {
257
+ throw new TypeError(
258
+ `emit: signal '${signal}' takes ${String(paramTypes.length)} arguments, got ${String(args.length)}`,
259
+ );
260
+ }
261
+
262
+ const signalId = getSignalId(instance, signal);
263
+ const detail = getSignalDetailQuark(signal);
264
+ const values = [toValue(objectT("full"), instance)];
265
+
266
+ for (const [index, paramType] of paramTypes.entries()) {
267
+ const value = newValueForType(paramType);
268
+ intoValue(value, args[index]);
269
+ values.push(value);
270
+ }
271
+
272
+ if (returnType === undefined) {
273
+ gSignalEmitv(values, signalId, detail, undefined);
274
+
275
+ return undefined;
276
+ }
277
+
278
+ const returnValue = newValueForType(returnType);
279
+ gSignalEmitv(values, signalId, detail, returnValue);
280
+
281
+ return fromValue(returnValue);
282
+ }
283
+
211
284
  const createEmitValue = (arg: EmitArg): { value: ExternalObject<Handle>; read?: () => unknown } => {
212
285
  if (!isOutputArg(arg)) {
213
286
  return { value: toValue(arg.type, arg.value) };
@@ -270,11 +343,15 @@ function emitSignal(instance: object, signal: string, args: EmitArg[], returns?:
270
343
 
271
344
  export {
272
345
  getSignalBaseName,
346
+ connectClosureSignal,
273
347
  connectSignal,
348
+ type DeclaredSignalTypes,
274
349
  disconnectSignal,
350
+ emitDeclaredSignal,
275
351
  emitSignal,
276
352
  hasSignalListener,
277
353
  isSignalHandlerConnected,
354
+ overrideSignalClassClosure,
278
355
  untrackConnection,
279
356
  type SignalHandler,
280
357
  };
package/src/type.ts CHANGED
@@ -203,11 +203,17 @@ const resolveFundamentalType = (descriptor: FundamentalDescriptor): bigint => {
203
203
  throw new Error("Cannot resolve gtype for fundamental type without a typeName");
204
204
  };
205
205
 
206
+ const getByteArrayType = (): bigint => resolveType(LIB, "g_byte_array_get_type");
207
+
206
208
  function resolveArrayType(descriptor: ArrayDescriptor): bigint {
207
209
  if (descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array") {
208
210
  return getStrvType();
209
211
  }
210
212
 
213
+ if (descriptor.arrayKind === "gbytearray") {
214
+ return getByteArrayType();
215
+ }
216
+
211
217
  throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);
212
218
  }
213
219
 
@@ -272,6 +278,7 @@ export {
272
278
  TYPE_GTYPE,
273
279
  TYPE_VARIANT,
274
280
  TYPE_UNICHAR,
281
+ getByteArrayType,
275
282
  getErrorType,
276
283
  getStrvType,
277
284
  isResolvableDescriptor,