@gtkx/runtime 1.0.0-rc.1 → 1.0.0-rc.2

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 (116) hide show
  1. package/dist/arg.d.ts +6 -5
  2. package/dist/arg.d.ts.map +1 -1
  3. package/dist/arg.js +5 -4
  4. package/dist/arg.js.map +1 -1
  5. package/dist/bind.d.ts +3 -2
  6. package/dist/bind.d.ts.map +1 -1
  7. package/dist/bind.js +5 -3
  8. package/dist/bind.js.map +1 -1
  9. package/dist/callback.d.ts +3 -3
  10. package/dist/callback.d.ts.map +1 -1
  11. package/dist/callback.js +51 -33
  12. package/dist/callback.js.map +1 -1
  13. package/dist/descriptors.d.ts +67 -64
  14. package/dist/descriptors.d.ts.map +1 -1
  15. package/dist/descriptors.js +92 -60
  16. package/dist/descriptors.js.map +1 -1
  17. package/dist/error.d.ts +5 -6
  18. package/dist/error.d.ts.map +1 -1
  19. package/dist/error.js +10 -6
  20. package/dist/error.js.map +1 -1
  21. package/dist/exit-hook.d.ts +2 -0
  22. package/dist/exit-hook.d.ts.map +1 -0
  23. package/dist/exit-hook.js +3 -0
  24. package/dist/exit-hook.js.map +1 -0
  25. package/dist/fn.d.ts +2 -2
  26. package/dist/fn.d.ts.map +1 -1
  27. package/dist/fn.js +26 -15
  28. package/dist/fn.js.map +1 -1
  29. package/dist/index.d.ts +3 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/library.d.ts +6 -5
  34. package/dist/library.d.ts.map +1 -1
  35. package/dist/library.js +6 -5
  36. package/dist/library.js.map +1 -1
  37. package/dist/lifecycle.d.ts +10 -9
  38. package/dist/lifecycle.d.ts.map +1 -1
  39. package/dist/lifecycle.js +38 -23
  40. package/dist/lifecycle.js.map +1 -1
  41. package/dist/listeners.d.ts +8 -8
  42. package/dist/listeners.d.ts.map +1 -1
  43. package/dist/listeners.js +28 -15
  44. package/dist/listeners.js.map +1 -1
  45. package/dist/mixin.d.ts +5 -11
  46. package/dist/mixin.d.ts.map +1 -1
  47. package/dist/mixin.js +24 -14
  48. package/dist/mixin.js.map +1 -1
  49. package/dist/native-value.d.ts +3 -2
  50. package/dist/native-value.d.ts.map +1 -1
  51. package/dist/native-value.js +75 -42
  52. package/dist/native-value.js.map +1 -1
  53. package/dist/object.d.ts +4 -3
  54. package/dist/object.d.ts.map +1 -1
  55. package/dist/object.js +8 -5
  56. package/dist/object.js.map +1 -1
  57. package/dist/promisify.d.ts +9 -1
  58. package/dist/promisify.d.ts.map +1 -1
  59. package/dist/promisify.js +18 -15
  60. package/dist/promisify.js.map +1 -1
  61. package/dist/properties.d.ts +14 -0
  62. package/dist/properties.d.ts.map +1 -0
  63. package/dist/properties.js +79 -0
  64. package/dist/properties.js.map +1 -0
  65. package/dist/register-class.d.ts +10 -2
  66. package/dist/register-class.d.ts.map +1 -1
  67. package/dist/register-class.js +83 -29
  68. package/dist/register-class.js.map +1 -1
  69. package/dist/registry.d.ts +23 -21
  70. package/dist/registry.d.ts.map +1 -1
  71. package/dist/registry.js +54 -35
  72. package/dist/registry.js.map +1 -1
  73. package/dist/signal.d.ts +7 -6
  74. package/dist/signal.d.ts.map +1 -1
  75. package/dist/signal.js +19 -12
  76. package/dist/signal.js.map +1 -1
  77. package/dist/t.d.ts +2 -2
  78. package/dist/t.d.ts.map +1 -1
  79. package/dist/t.js +2 -1
  80. package/dist/t.js.map +1 -1
  81. package/dist/tuple.d.ts +3 -2
  82. package/dist/tuple.d.ts.map +1 -1
  83. package/dist/tuple.js +7 -4
  84. package/dist/tuple.js.map +1 -1
  85. package/dist/type.d.ts +48 -41
  86. package/dist/type.d.ts.map +1 -1
  87. package/dist/type.js +107 -87
  88. package/dist/type.js.map +1 -1
  89. package/dist/value.d.ts +19 -10
  90. package/dist/value.d.ts.map +1 -1
  91. package/dist/value.js +164 -99
  92. package/dist/value.js.map +1 -1
  93. package/package.json +4 -6
  94. package/src/arg.ts +7 -5
  95. package/src/bind.ts +13 -4
  96. package/src/callback.ts +97 -35
  97. package/src/descriptors.ts +227 -85
  98. package/src/error.ts +18 -9
  99. package/src/exit-hook.ts +3 -0
  100. package/src/fn.ts +53 -22
  101. package/src/index.ts +4 -2
  102. package/src/library.ts +7 -5
  103. package/src/lifecycle.ts +54 -26
  104. package/src/listeners.ts +46 -18
  105. package/src/mixin.ts +39 -14
  106. package/src/native-value.ts +103 -46
  107. package/src/object.ts +19 -7
  108. package/src/promisify.ts +42 -15
  109. package/src/properties.ts +115 -0
  110. package/src/register-class.ts +157 -30
  111. package/src/registry.ts +144 -54
  112. package/src/signal.ts +53 -13
  113. package/src/t.ts +3 -1
  114. package/src/tuple.ts +16 -4
  115. package/src/type.ts +183 -93
  116. package/src/value.ts +231 -108
package/src/callback.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { copy, type Descriptor } from "@gtkx/native";
2
- import type { CallbackDescriptor } from "./descriptors.js";
2
+ import type { CallbackDescriptor, RefDescriptor } from "./descriptors.js";
3
3
  import { fromNative, toNative } from "./native-value.js";
4
4
  import { getHandle } from "./registry.js";
5
5
  import { splitTupleResult } from "./tuple.js";
@@ -15,18 +15,65 @@ type CallbackSpec = {
15
15
  userDataIndex?: number;
16
16
  };
17
17
 
18
+ type CallbackPlan = {
19
+ fn: Callback;
20
+ effectiveTypes: Descriptor[];
21
+ returnDescriptor: Descriptor;
22
+ start: number;
23
+ receiver: CallbackReceiver;
24
+ };
25
+
18
26
  const fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {
19
27
  if (descriptor.kind === "boxed" && descriptor.typeName === "GValue") {
20
28
  copyValue(getHandle(target), getHandle(source));
29
+
21
30
  return;
22
31
  }
32
+
23
33
  if ((descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.size !== undefined) {
24
34
  copy(getHandle(target), getHandle(source), descriptor.size);
35
+
25
36
  return;
26
37
  }
38
+
27
39
  throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);
28
40
  };
29
41
 
42
+ const isCallerAllocatedOut = (descriptor: Descriptor): boolean =>
43
+ (descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.callerAllocated === true;
44
+
45
+ const collectRefArg = (
46
+ descriptor: RefDescriptor,
47
+ wrappedValue: unknown,
48
+ inputs: unknown[],
49
+ outParams: OutParam[],
50
+ ): void => {
51
+ if (descriptor.inout === true) {
52
+ inputs.push((wrappedValue as { value: unknown }).value);
53
+ }
54
+
55
+ outParams.push({ value: wrappedValue, descriptor });
56
+ };
57
+
58
+ const collectCallbackArg = (
59
+ descriptor: Descriptor | undefined,
60
+ wrappedValue: unknown,
61
+ inputs: unknown[],
62
+ outParams: OutParam[],
63
+ ): void => {
64
+ if (descriptor?.kind === "ref") {
65
+ collectRefArg(descriptor, wrappedValue, inputs, outParams);
66
+
67
+ return;
68
+ }
69
+
70
+ inputs.push(wrappedValue);
71
+
72
+ if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {
73
+ outParams.push({ value: wrappedValue, descriptor });
74
+ }
75
+ };
76
+
30
77
  const partitionCallbackArgs = (
31
78
  effectiveTypes: Descriptor[],
32
79
  wrapped: unknown[],
@@ -34,54 +81,69 @@ const partitionCallbackArgs = (
34
81
  ): { inputs: unknown[]; outParams: OutParam[] } => {
35
82
  const inputs: unknown[] = [];
36
83
  const outParams: OutParam[] = [];
84
+
37
85
  for (let i = start; i < effectiveTypes.length; i++) {
38
- const descriptor = effectiveTypes[i];
39
- if (descriptor !== undefined && descriptor.kind === "ref") {
40
- if (descriptor.inout === true) inputs.push((wrapped[i] as { value: unknown }).value);
41
- outParams.push({ value: wrapped[i], descriptor });
42
- } else if (
43
- descriptor !== undefined &&
44
- (descriptor.kind === "boxed" || descriptor.kind === "struct") &&
45
- descriptor.callerAllocated === true
46
- ) {
47
- inputs.push(wrapped[i]);
48
- outParams.push({ value: wrapped[i], descriptor });
49
- } else {
50
- inputs.push(wrapped[i]);
51
- }
86
+ collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, outParams);
52
87
  }
88
+
53
89
  return { inputs, outParams };
54
90
  };
55
91
 
56
92
  const writeOutParams = (outParams: OutParam[], outValues: unknown[]): void => {
57
- outParams.forEach((outParam, position) => {
93
+ for (const [position, outParam] of outParams.entries()) {
58
94
  const outValue = outValues[position];
95
+
59
96
  if (outParam.descriptor.kind === "ref") {
60
97
  (outParam.value as { value: unknown }).value = outValue;
61
98
  } else if (outValue != null && outParam.value != null) {
62
- fillCallerAllocatedBuffer(outParam.descriptor, outParam.value as object, outValue as object);
99
+ fillCallerAllocatedBuffer(outParam.descriptor, outParam.value, outValue);
63
100
  }
64
- });
101
+ }
102
+ };
103
+
104
+ const getThisArg = (receiver: CallbackReceiver, wrapped: unknown[]): unknown =>
105
+ receiver === "this" ? (wrapped[0] ?? null) : null;
106
+
107
+ const runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {
108
+ const { effectiveTypes, returnDescriptor } = plan;
109
+ const wrapped = effectiveTypes.map((descriptor, i) => fromNative(descriptor, rawArgs[i]));
110
+ const thisArg = getThisArg(plan.receiver, wrapped);
111
+ const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, wrapped, plan.start);
112
+ const result = plan.fn.apply(thisArg, inputs);
113
+
114
+ if (outParams.length === 0) {
115
+ return toNative(returnDescriptor, result);
116
+ }
117
+
118
+ const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== "void", outParams.length);
119
+ writeOutParams(outParams, outValues);
120
+
121
+ return toNative(returnDescriptor, primary);
122
+ };
123
+
124
+ const getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {
125
+ const { userDataIndex } = spec;
126
+
127
+ if (userDataIndex === undefined) {
128
+ return spec.argDescriptors;
129
+ }
130
+
131
+ return spec.argDescriptors.filter((_, i) => i !== userDataIndex);
65
132
  };
66
133
 
67
- export const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
134
+ const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
68
135
  callback == null ? callback : wrapCallback(callback as Callback, spec, "none");
69
136
 
70
- export function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {
71
- const { returnDescriptor, userDataIndex } = spec;
72
- const effectiveTypes =
73
- userDataIndex === undefined ? spec.argDescriptors : spec.argDescriptors.filter((_, i) => i !== userDataIndex);
74
- const start = receiver === "none" ? 0 : 1;
75
- return (...rawArgs: unknown[]): unknown => {
76
- const wrapped = effectiveTypes.map((descriptor, i) => fromNative(descriptor, rawArgs[i]));
77
- const thisArg = receiver === "this" ? (wrapped[0] ?? null) : null;
78
- const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, wrapped, start);
79
- const result = (fn as (this: unknown, ...args: unknown[]) => unknown).apply(thisArg, inputs);
80
- if (outParams.length === 0) {
81
- return toNative(returnDescriptor, result);
82
- }
83
- const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== "void", outParams.length);
84
- writeOutParams(outParams, outValues);
85
- return toNative(returnDescriptor, primary);
137
+ function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {
138
+ const plan: CallbackPlan = {
139
+ fn,
140
+ effectiveTypes: getEffectiveTypes(spec),
141
+ returnDescriptor: spec.returnDescriptor,
142
+ start: receiver === "none" ? 0 : 1,
143
+ receiver,
86
144
  };
145
+
146
+ return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);
87
147
  }
148
+
149
+ export { wrapCallbackValue, wrapCallback };
@@ -1,37 +1,38 @@
1
1
  import type { ArrayKind, Descriptor, Ownership } from "@gtkx/native";
2
2
  import type { AnyClass } from "@gtkx/utils";
3
3
 
4
- export type Int8Descriptor = Extract<Descriptor, { kind: "int8" }>;
5
- export type Uint8Descriptor = Extract<Descriptor, { kind: "uint8" }>;
6
- export type Int16Descriptor = Extract<Descriptor, { kind: "int16" }>;
7
- export type Uint16Descriptor = Extract<Descriptor, { kind: "uint16" }>;
8
- export type Int32Descriptor = Extract<Descriptor, { kind: "int32" }>;
9
- export type Uint32Descriptor = Extract<Descriptor, { kind: "uint32" }>;
10
- export type Int64Descriptor = Extract<Descriptor, { kind: "int64" }>;
11
- export type Uint64Descriptor = Extract<Descriptor, { kind: "uint64" }>;
12
- export type BigInt64Descriptor = Extract<Descriptor, { kind: "bigint64" }>;
13
- export type BigUint64Descriptor = Extract<Descriptor, { kind: "biguint64" }>;
14
- export type Float32Descriptor = Extract<Descriptor, { kind: "float32" }>;
15
- export type Float64Descriptor = Extract<Descriptor, { kind: "float64" }>;
16
- export type EnumDescriptor = Extract<Descriptor, { kind: "enum" }>;
17
- export type FlagsDescriptor = Extract<Descriptor, { kind: "flags" }>;
18
- export type BooleanDescriptor = Extract<Descriptor, { kind: "boolean" }>;
19
- export type StringDescriptor = Extract<Descriptor, { kind: "string" }>;
20
- export type ObjectDescriptor = Extract<Descriptor, { kind: "object" }>;
21
- export type UnicharDescriptor = Extract<Descriptor, { kind: "unichar" }>;
22
- export type VoidDescriptor = Extract<Descriptor, { kind: "void" }>;
23
- export type BufferDescriptor = Extract<Descriptor, { kind: "buffer" }>;
24
- export type BoxedDescriptor = Extract<Descriptor, { kind: "boxed" }>;
25
- export type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & { wrapperClass?: AnyClass };
26
- export type FundamentalDescriptor = Extract<Descriptor, { kind: "fundamental" }> & { wrapperClass?: AnyClass };
27
- export type ArrayDescriptor = Extract<Descriptor, { kind: "array" }>;
28
- export type HashTableDescriptor = Extract<Descriptor, { kind: "hashtable" }>;
29
- export type CallbackDescriptor = Extract<Descriptor, { kind: "callback" }>;
30
- export type RefDescriptor = Extract<Descriptor, { kind: "ref" }>;
31
- export type TypeDescriptor = BigUint64Descriptor & { type: true };
4
+ type Int8Descriptor = Extract<Descriptor, { kind: "int8" }>;
5
+ type Uint8Descriptor = Extract<Descriptor, { kind: "uint8" }>;
6
+ type Int16Descriptor = Extract<Descriptor, { kind: "int16" }>;
7
+ type Uint16Descriptor = Extract<Descriptor, { kind: "uint16" }>;
8
+ type Int32Descriptor = Extract<Descriptor, { kind: "int32" }>;
9
+ type Uint32Descriptor = Extract<Descriptor, { kind: "uint32" }>;
10
+ type Int64Descriptor = Extract<Descriptor, { kind: "int64" }>;
11
+ type Uint64Descriptor = Extract<Descriptor, { kind: "uint64" }>;
12
+ type BigInt64Descriptor = Extract<Descriptor, { kind: "bigint64" }>;
13
+ type BigUint64Descriptor = Extract<Descriptor, { kind: "biguint64" }>;
14
+ type Float32Descriptor = Extract<Descriptor, { kind: "float32" }>;
15
+ type Float64Descriptor = Extract<Descriptor, { kind: "float64" }>;
16
+ type EnumDescriptor = Extract<Descriptor, { kind: "enum" }>;
17
+ type FlagsDescriptor = Extract<Descriptor, { kind: "flags" }>;
18
+ type BooleanDescriptor = Extract<Descriptor, { kind: "boolean" }>;
19
+ type StringDescriptor = Extract<Descriptor, { kind: "string" }>;
20
+ type ObjectDescriptor = Extract<Descriptor, { kind: "object" }>;
21
+ type UnicharDescriptor = Extract<Descriptor, { kind: "unichar" }>;
22
+ type VoidDescriptor = Extract<Descriptor, { kind: "void" }>;
23
+ type BufferDescriptor = Extract<Descriptor, { kind: "buffer" }>;
24
+ type BoxedDescriptor = Extract<Descriptor, { kind: "boxed" }>;
25
+ type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & { wrapperClass?: AnyClass };
26
+ type FundamentalDescriptor = Extract<Descriptor, { kind: "fundamental" }> & { wrapperClass?: AnyClass };
27
+ type ArrayDescriptor = Extract<Descriptor, { kind: "array" }>;
28
+ type HashTableDescriptor = Extract<Descriptor, { kind: "hashtable" }>;
29
+ type CallbackDescriptor = Extract<Descriptor, { kind: "callback" }>;
30
+ type RefDescriptor = Extract<Descriptor, { kind: "ref" }>;
31
+ type TypeDescriptor = BigUint64Descriptor & { type: true };
32
32
 
33
33
  type BoxedOptions = {
34
34
  callerAllocated?: boolean;
35
+ inline?: boolean;
35
36
  ownership?: Ownership;
36
37
  sharedLibrary?: string;
37
38
  getTypeFnName?: string;
@@ -55,41 +56,43 @@ type FundamentalOptions = {
55
56
  ownership?: Ownership;
56
57
  typeName?: string;
57
58
  wrapperClass?: AnyClass;
59
+ inline?: boolean;
58
60
  };
59
61
 
60
62
  type StructOptions = {
61
63
  callerAllocated?: boolean;
64
+ inline?: boolean;
62
65
  size?: number;
63
66
  wrapperClass?: AnyClass;
64
67
  };
65
68
 
66
- export const int8T: Int8Descriptor = { kind: "int8" };
67
- export const uint8T: Uint8Descriptor = { kind: "uint8" };
68
- export const int16T: Int16Descriptor = { kind: "int16" };
69
- export const uint16T: Uint16Descriptor = { kind: "uint16" };
70
- export const int32T: Int32Descriptor = { kind: "int32" };
71
- export const uint32T: Uint32Descriptor = { kind: "uint32" };
72
- export const int64T: Int64Descriptor = { kind: "int64" };
73
- export const uint64T: Uint64Descriptor = { kind: "uint64" };
74
- export const bigint64T: BigInt64Descriptor = { kind: "bigint64" };
75
- export const biguint64T: BigUint64Descriptor = { kind: "biguint64" };
76
- export const gtypeT: TypeDescriptor = { kind: "biguint64", type: true };
77
- export const float32T: Float32Descriptor = { kind: "float32" };
78
- export const float64T: Float64Descriptor = { kind: "float64" };
79
- export const booleanT: BooleanDescriptor = { kind: "boolean" };
80
- export const voidT: VoidDescriptor = { kind: "void" };
81
- export const unicharT: UnicharDescriptor = { kind: "unichar" };
82
- export const bufferT: BufferDescriptor = { kind: "buffer" };
83
-
84
- export const stringT = (ownership: Ownership = "borrowed", length?: number): StringDescriptor =>
69
+ const int8T: Int8Descriptor = { kind: "int8" };
70
+ const uint8T: Uint8Descriptor = { kind: "uint8" };
71
+ const int16T: Int16Descriptor = { kind: "int16" };
72
+ const uint16T: Uint16Descriptor = { kind: "uint16" };
73
+ const int32T: Int32Descriptor = { kind: "int32" };
74
+ const uint32T: Uint32Descriptor = { kind: "uint32" };
75
+ const int64T: Int64Descriptor = { kind: "int64" };
76
+ const uint64T: Uint64Descriptor = { kind: "uint64" };
77
+ const bigint64T: BigInt64Descriptor = { kind: "bigint64" };
78
+ const biguint64T: BigUint64Descriptor = { kind: "biguint64" };
79
+ const gtypeT: TypeDescriptor = { kind: "biguint64", type: true };
80
+ const float32T: Float32Descriptor = { kind: "float32" };
81
+ const float64T: Float64Descriptor = { kind: "float64" };
82
+ const booleanT: BooleanDescriptor = { kind: "boolean" };
83
+ const voidT: VoidDescriptor = { kind: "void" };
84
+ const unicharT: UnicharDescriptor = { kind: "unichar" };
85
+ const bufferT: BufferDescriptor = { kind: "buffer" };
86
+
87
+ const stringT = (ownership: Ownership = "borrowed", length?: number): StringDescriptor =>
85
88
  length === undefined ? { kind: "string", ownership } : { kind: "string", ownership, length };
86
89
 
87
- export const objectT = (ownership: Ownership = "borrowed"): ObjectDescriptor => ({ kind: "object", ownership });
90
+ const objectT = (ownership: Ownership = "borrowed"): ObjectDescriptor => ({ kind: "object", ownership });
88
91
 
89
- export const refT = (innerDescriptor: Descriptor, inout = false): RefDescriptor =>
90
- inout ? { kind: "ref", innerDescriptor, inout: true } : { kind: "ref", innerDescriptor };
92
+ const refT = (innerDescriptor: Descriptor, isInout = false): RefDescriptor =>
93
+ isInout ? { kind: "ref", innerDescriptor, inout: true } : { kind: "ref", innerDescriptor };
91
94
 
92
- export const hashTableT = (
95
+ const hashTableT = (
93
96
  keyDescriptor: Descriptor,
94
97
  valueDescriptor: Descriptor,
95
98
  ownership: Ownership = "borrowed",
@@ -100,43 +103,85 @@ export const hashTableT = (
100
103
  ownership,
101
104
  });
102
105
 
103
- export const enumT = (sharedLibrary: string, getTypeFnName: string, signed: boolean): EnumDescriptor => ({
106
+ const enumT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): EnumDescriptor => ({
104
107
  kind: "enum",
105
108
  sharedLibrary,
106
- getTypeFnName,
107
- signed,
109
+ getTypeFnName: typeFnName,
110
+ signed: isSigned,
108
111
  });
109
112
 
110
- export const flagsT = (sharedLibrary: string, getTypeFnName: string, signed: boolean): FlagsDescriptor => ({
113
+ const flagsT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): FlagsDescriptor => ({
111
114
  kind: "flags",
112
115
  sharedLibrary,
113
- getTypeFnName,
114
- signed,
116
+ getTypeFnName: typeFnName,
117
+ signed: isSigned,
115
118
  });
116
119
 
117
- export const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor => {
120
+ const applyBoxedNames = (result: BoxedDescriptor, options: BoxedOptions): void => {
121
+ if (options.sharedLibrary !== undefined) {
122
+ result.sharedLibrary = options.sharedLibrary;
123
+ }
124
+
125
+ if (options.getTypeFnName !== undefined) {
126
+ result.getTypeFnName = options.getTypeFnName;
127
+ }
128
+
129
+ if (options.freeFnName !== undefined) {
130
+ result.freeFnName = options.freeFnName;
131
+ }
132
+ };
133
+
134
+ const applyBoxedOptions = (result: BoxedDescriptor, options: BoxedOptions): void => {
135
+ applyBoxedNames(result, options);
136
+
137
+ if (options.callerAllocated) {
138
+ result.callerAllocated = true;
139
+ }
140
+
141
+ if (options.inline) {
142
+ result.inline = true;
143
+ }
144
+
145
+ if (options.size !== undefined) {
146
+ result.size = options.size;
147
+ }
148
+ };
149
+
150
+ const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor => {
118
151
  const result: BoxedDescriptor = {
119
152
  kind: "boxed",
120
153
  ownership: options.ownership ?? "borrowed",
121
154
  typeName,
122
155
  };
123
- if (options.sharedLibrary !== undefined) result.sharedLibrary = options.sharedLibrary;
124
- if (options.getTypeFnName !== undefined) result.getTypeFnName = options.getTypeFnName;
125
- if (options.freeFnName !== undefined) result.freeFnName = options.freeFnName;
126
- if (options.callerAllocated) result.callerAllocated = true;
127
- if (options.size !== undefined) result.size = options.size;
156
+
157
+ applyBoxedOptions(result, options);
158
+
128
159
  return result;
129
160
  };
130
161
 
131
- export const structT = (ownership: Ownership = "borrowed", options: StructOptions = {}): StructDescriptor => {
162
+ const structT = (ownership: Ownership = "borrowed", options: StructOptions = {}): StructDescriptor => {
132
163
  const result: StructDescriptor = { kind: "struct", ownership };
133
- if (options.size !== undefined) result.size = options.size;
134
- if (options.wrapperClass !== undefined) result.wrapperClass = options.wrapperClass;
135
- if (options.callerAllocated) result.callerAllocated = true;
164
+
165
+ if (options.size !== undefined) {
166
+ result.size = options.size;
167
+ }
168
+
169
+ if (options.wrapperClass !== undefined) {
170
+ result.wrapperClass = options.wrapperClass;
171
+ }
172
+
173
+ if (options.callerAllocated) {
174
+ result.callerAllocated = true;
175
+ }
176
+
177
+ if (options.inline) {
178
+ result.inline = true;
179
+ }
180
+
136
181
  return result;
137
182
  };
138
183
 
139
- export const fundamentalT = (
184
+ const fundamentalT = (
140
185
  sharedLibrary: string,
141
186
  refFnName: string,
142
187
  unrefFnName: string,
@@ -144,65 +189,162 @@ export const fundamentalT = (
144
189
  ): FundamentalDescriptor => {
145
190
  const ownership = options.ownership ?? "borrowed";
146
191
  const result: FundamentalDescriptor = { kind: "fundamental", ownership, sharedLibrary, refFnName, unrefFnName };
147
- if (options.typeName !== undefined) result.typeName = options.typeName;
148
- if (options.wrapperClass !== undefined) result.wrapperClass = options.wrapperClass;
192
+
193
+ if (options.typeName !== undefined) {
194
+ result.typeName = options.typeName;
195
+ }
196
+
197
+ if (options.wrapperClass !== undefined) {
198
+ result.wrapperClass = options.wrapperClass;
199
+ }
200
+
201
+ if (options.inline) {
202
+ result.inline = true;
203
+ }
204
+
149
205
  return result;
150
206
  };
151
207
 
152
- export const arrayT = (
208
+ const arrayT = (
153
209
  itemDescriptor: Descriptor,
154
210
  arrayKind: ArrayKind = "array",
155
211
  ownership: Ownership = "borrowed",
156
212
  options?: ArrayOptions,
157
213
  ): ArrayDescriptor => {
158
214
  const result: ArrayDescriptor = { kind: "array", itemDescriptor, arrayKind, ownership };
159
- if (options?.elementSize !== undefined) result.elementSize = options.elementSize;
160
- if (options?.sizeParamIndex !== undefined) result.sizeParamIndex = options.sizeParamIndex;
161
- if (options?.fixedSize !== undefined) result.fixedSize = options.fixedSize;
215
+
216
+ if (options?.elementSize !== undefined) {
217
+ result.elementSize = options.elementSize;
218
+ }
219
+
220
+ if (options?.sizeParamIndex !== undefined) {
221
+ result.sizeParamIndex = options.sizeParamIndex;
222
+ }
223
+
224
+ if (options?.fixedSize !== undefined) {
225
+ result.fixedSize = options.fixedSize;
226
+ }
227
+
162
228
  return result;
163
229
  };
164
230
 
165
- export const listT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
231
+ const listT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
166
232
  arrayT(itemDescriptor, "glist", ownership);
167
233
 
168
- export const slistT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
234
+ const slistT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
169
235
  arrayT(itemDescriptor, "gslist", ownership);
170
236
 
171
- export const ptrArrayT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
237
+ const ptrArrayT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
172
238
  arrayT(itemDescriptor, "gptrarray", ownership);
173
239
 
174
- export const gArrayT = (
240
+ const gArrayT = (
175
241
  itemDescriptor: Descriptor,
176
242
  ownership: Ownership = "borrowed",
177
243
  elementSize?: number,
178
244
  ): ArrayDescriptor =>
179
245
  arrayT(itemDescriptor, "garray", ownership, elementSize === undefined ? undefined : { elementSize });
180
246
 
181
- export const byteArrayT = (ownership: Ownership = "borrowed"): ArrayDescriptor =>
247
+ const byteArrayT = (ownership: Ownership = "borrowed"): ArrayDescriptor =>
182
248
  arrayT(uint8T, "gbytearray", ownership);
183
249
 
184
- export const sizedArrayT = (
250
+ const sizedArrayT = (
185
251
  itemDescriptor: Descriptor,
186
252
  sizeParamIndex: number,
187
253
  ownership: Ownership = "borrowed",
188
254
  elementSize?: number,
189
255
  ): ArrayDescriptor => arrayT(itemDescriptor, "sized", ownership, { sizeParamIndex, elementSize });
190
256
 
191
- export const fixedArrayT = (
257
+ const fixedArrayT = (
192
258
  itemDescriptor: Descriptor,
193
259
  fixedSize: number,
194
260
  ownership: Ownership = "borrowed",
195
261
  elementSize?: number,
196
262
  ): ArrayDescriptor => arrayT(itemDescriptor, "fixed", ownership, { fixedSize, elementSize });
197
263
 
198
- export const callbackT = (
264
+ const callbackT = (
199
265
  argDescriptors: Descriptor[],
200
266
  returnDescriptor: Descriptor,
201
267
  options?: CallbackOptions,
202
268
  ): CallbackDescriptor => {
203
269
  const result: CallbackDescriptor = { kind: "callback", argDescriptors, returnDescriptor };
204
- if (options?.hasDestroy !== undefined) result.hasDestroy = options.hasDestroy;
205
- if (options?.userDataIndex !== undefined) result.userDataIndex = options.userDataIndex;
206
- if (options?.scope !== undefined) result.scope = options.scope;
270
+
271
+ if (options?.hasDestroy !== undefined) {
272
+ result.hasDestroy = options.hasDestroy;
273
+ }
274
+
275
+ if (options?.userDataIndex !== undefined) {
276
+ result.userDataIndex = options.userDataIndex;
277
+ }
278
+
279
+ if (options?.scope !== undefined) {
280
+ result.scope = options.scope;
281
+ }
282
+
207
283
  return result;
208
284
  };
285
+
286
+ export {
287
+ int8T,
288
+ uint8T,
289
+ int16T,
290
+ uint16T,
291
+ int32T,
292
+ uint32T,
293
+ int64T,
294
+ uint64T,
295
+ bigint64T,
296
+ biguint64T,
297
+ gtypeT,
298
+ float32T,
299
+ float64T,
300
+ booleanT,
301
+ voidT,
302
+ unicharT,
303
+ bufferT,
304
+ stringT,
305
+ objectT,
306
+ refT,
307
+ hashTableT,
308
+ enumT,
309
+ flagsT,
310
+ boxedT,
311
+ structT,
312
+ fundamentalT,
313
+ arrayT,
314
+ listT,
315
+ slistT,
316
+ ptrArrayT,
317
+ gArrayT,
318
+ byteArrayT,
319
+ sizedArrayT,
320
+ fixedArrayT,
321
+ callbackT,
322
+ type Int8Descriptor,
323
+ type Uint8Descriptor,
324
+ type Int16Descriptor,
325
+ type Uint16Descriptor,
326
+ type Int32Descriptor,
327
+ type Uint32Descriptor,
328
+ type Int64Descriptor,
329
+ type Uint64Descriptor,
330
+ type BigInt64Descriptor,
331
+ type BigUint64Descriptor,
332
+ type Float32Descriptor,
333
+ type Float64Descriptor,
334
+ type EnumDescriptor,
335
+ type FlagsDescriptor,
336
+ type BooleanDescriptor,
337
+ type StringDescriptor,
338
+ type ObjectDescriptor,
339
+ type UnicharDescriptor,
340
+ type VoidDescriptor,
341
+ type BufferDescriptor,
342
+ type BoxedDescriptor,
343
+ type StructDescriptor,
344
+ type FundamentalDescriptor,
345
+ type ArrayDescriptor,
346
+ type HashTableDescriptor,
347
+ type CallbackDescriptor,
348
+ type RefDescriptor,
349
+ type TypeDescriptor,
350
+ };
package/src/error.ts CHANGED
@@ -2,26 +2,29 @@ import type { ExternalObject, Handle, Ref } from "@gtkx/native";
2
2
  import { getWrapperClass, wrapHandle } from "./registry.js";
3
3
  import { getErrorType, isTypedClass } from "./type.js";
4
4
 
5
- type ErrorLike = {
5
+ type ErrorLike = Error & {
6
6
  domain: number;
7
7
  code: number;
8
- message: string;
9
8
  };
10
9
 
11
10
  /**
12
11
  * An error enum object carrying its member codes plus an `instanceof` check that
13
12
  * matches wrapped GLib errors belonging to a specific error domain.
14
13
  */
15
- export type ErrorDomain<T extends Record<string, number>> = T & {
14
+ type ErrorDomain<T extends Record<string, number>> = T & {
16
15
  [Symbol.hasInstance]: (value: unknown) => value is ErrorLike;
17
16
  };
18
17
 
19
- export function checkError(error: Ref): void {
20
- if (error.value !== null) {
21
- const gerror = wrapHandle<ErrorLike>(error.value as ExternalObject<Handle>, getWrapperClass(getErrorType()));
22
- Error.captureStackTrace(gerror, checkError);
23
- throw gerror;
18
+ function checkError(error: Ref): void {
19
+ if (error.value === null) {
20
+ return;
24
21
  }
22
+
23
+ const gerror = wrapHandle(error.value as ExternalObject<Handle>, getWrapperClass(getErrorType())) as ErrorLike;
24
+ const callSite = new Error("gtkx call site");
25
+ const callerFrames = (callSite.stack ?? "").split("\n").slice(2);
26
+ gerror.stack = [`${gerror.name}: ${gerror.message}`, ...callerFrames].join("\n");
27
+ throw gerror;
25
28
  }
26
29
 
27
30
  const isError = (value: unknown): value is ErrorLike => isTypedClass(value) && value.__type__ === getErrorType();
@@ -34,16 +37,22 @@ const isError = (value: unknown): value is ErrorLike => isTypedClass(value) && v
34
37
  * @param resolveDomain Called once, on first `instanceof` check, to obtain the domain quark.
35
38
  * @param members The error code enum members to expose on the returned object.
36
39
  */
37
- export function createErrorDomain<const T extends Record<string, number>>(
40
+ function createErrorDomain<const T extends Record<string, number>>(
38
41
  resolveDomain: () => number,
39
42
  members: T,
40
43
  ): ErrorDomain<T> {
41
44
  let domain: number | undefined;
45
+
42
46
  const hasInstance = (value: unknown): value is ErrorLike => {
43
47
  domain ??= resolveDomain();
48
+
44
49
  return isError(value) && value.domain === domain;
45
50
  };
51
+
46
52
  const enumObject: Record<string, unknown> = { ...members };
47
53
  Object.defineProperty(enumObject, Symbol.hasInstance, { value: hasInstance });
54
+
48
55
  return enumObject as ErrorDomain<T>;
49
56
  }
57
+
58
+ export { checkError, createErrorDomain, type ErrorDomain };
@@ -0,0 +1,3 @@
1
+ import { quit } from "./lifecycle.js";
2
+
3
+ process.on("exit", quit);