@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
@@ -1,8 +1,11 @@
1
1
  import { registerClass as nativeRegisterClass, } from "@gtkx/native";
2
2
  import { getParentClass, walkClassChain } from "@gtkx/utils";
3
3
  import { wrapCallback } from "./callback.js";
4
+ import { buildAccessors, makeGetProperty, makeSetProperty, toNativeProperties, } from "./properties.js";
4
5
  import { getClassType, getInterfaceVfuncRegistry, getVfuncRegistry, registerClassType, } from "./registry.js";
5
6
  import { TYPE_INVALID, typeInterfaces } from "./type.js";
7
+ const UNSUPPORTED_CONSTRUCT_VFUNCS = new Set(["constructed", "setProperty", "getProperty"]);
8
+ const VALUE_ARG_INDEX = 2;
6
9
  /**
7
10
  * Registers a subclass of a wrapper class as a new GType, wiring up any class and
8
11
  * inherited-interface virtual functions it overrides. Throws if the class does not
@@ -13,7 +16,7 @@ import { TYPE_INVALID, typeInterfaces } from "./type.js";
13
16
  * @param options Registration options, such as an explicit type name.
14
17
  * @returns The same class, now registered.
15
18
  */
16
- export function registerClass(klass, options = {}) {
19
+ function registerClass(klass, options = {}) {
17
20
  const parentType = resolveParentType(klass);
18
21
  if (parentType === TYPE_INVALID) {
19
22
  throw new TypeError(`registerClass: ${klass.name} must extend a registered wrapper class`);
@@ -22,10 +25,12 @@ export function registerClass(klass, options = {}) {
22
25
  if (!name) {
23
26
  throw new Error("registerClass: cannot derive a GType name (anonymous class with no typeName option)");
24
27
  }
25
- const classVfuncs = discoverClassVfuncs(klass);
28
+ const properties = options.properties ?? {};
29
+ const accessors = buildAccessors(klass, properties);
30
+ const classVfuncs = [...discoverClassVfuncs(klass), ...propertyVfuncs(klass, accessors)];
26
31
  const claimedMethodNames = new Set(classVfuncs.map((vfunc) => vfunc.methodName));
27
32
  const interfaceBindings = discoverInheritedInterfaceVfuncs(klass, parentType, claimedMethodNames);
28
- const nativeOptions = toNativeOptions(classVfuncs, interfaceBindings);
33
+ const nativeOptions = toNativeOptions(classVfuncs, interfaceBindings, properties);
29
34
  const newType = nativeRegisterClass(name, parentType, nativeOptions);
30
35
  registerClassType(klass, newType);
31
36
  return klass;
@@ -33,45 +38,57 @@ export function registerClass(klass, options = {}) {
33
38
  function resolveParentType(klass) {
34
39
  return (walkClassChain(getParentClass(klass), (cls) => {
35
40
  const gtype = getClassType(cls);
36
- return gtype !== TYPE_INVALID ? gtype : undefined;
41
+ return gtype === TYPE_INVALID ? undefined : gtype;
37
42
  }) ?? TYPE_INVALID);
38
43
  }
39
44
  function ownInstanceMethodNames(klass) {
40
45
  const proto = klass.prototype;
41
- if (!proto)
46
+ if (!proto) {
42
47
  return [];
48
+ }
43
49
  return Object.getOwnPropertyNames(proto).filter((name) => {
44
- if (name === "constructor")
50
+ if (name === "constructor") {
45
51
  return false;
46
- return typeof proto[name] === "function";
52
+ }
53
+ return typeof Object.getOwnPropertyDescriptor(proto, name)?.value === "function";
47
54
  });
48
55
  }
56
+ function buildDiscoveredVfunc(proto, methodName, resolveDescriptor, skip) {
57
+ if (skip?.has(methodName)) {
58
+ return undefined;
59
+ }
60
+ const descriptor = resolveDescriptor(methodName);
61
+ if (!descriptor) {
62
+ return undefined;
63
+ }
64
+ const fn = proto[methodName];
65
+ if (!fn) {
66
+ return undefined;
67
+ }
68
+ return {
69
+ ...descriptor,
70
+ methodName,
71
+ fn: wrapVfunc(fn, descriptor.argDescriptors, descriptor.returnDescriptor),
72
+ };
73
+ }
49
74
  function collectDiscoveredVfuncs(klass, resolveDescriptor, skip) {
50
75
  const proto = klass.prototype;
51
76
  const result = [];
52
77
  for (const methodName of ownInstanceMethodNames(klass)) {
53
- if (skip?.has(methodName))
54
- continue;
55
- const descriptor = resolveDescriptor(methodName);
56
- if (!descriptor)
57
- continue;
58
- const fn = proto[methodName];
59
- if (!fn)
60
- continue;
61
- result.push({
62
- ...descriptor,
63
- methodName,
64
- fn: wrapVfunc(fn, descriptor.argDescriptors, descriptor.returnDescriptor),
65
- });
78
+ const discovered = buildDiscoveredVfunc(proto, methodName, resolveDescriptor, skip);
79
+ if (discovered) {
80
+ result.push(discovered);
81
+ }
66
82
  }
67
83
  return result;
68
84
  }
69
- const UNSUPPORTED_CONSTRUCT_VFUNCS = new Set(["constructed", "setProperty", "getProperty"]);
70
85
  function discoverClassVfuncs(klass) {
71
86
  return collectDiscoveredVfuncs(klass, (methodName) => {
72
87
  const descriptor = findClassVfuncDescriptor(klass, methodName);
73
88
  if (descriptor && UNSUPPORTED_CONSTRUCT_VFUNCS.has(methodName)) {
74
- throw new Error(`registerClass: overriding the GObject construct-time vtable slot '${methodName}' is not supported; run construct-time initialization in the subclass constructor, after super(...), instead`);
89
+ throw new Error(`registerClass: overriding the GObject construct-time vtable slot '${methodName}' is not ` +
90
+ "supported; run construct-time initialization in the subclass constructor, after " +
91
+ "super(...), instead");
75
92
  }
76
93
  return descriptor ?? undefined;
77
94
  });
@@ -82,17 +99,18 @@ function wrapVfunc(fn, argDescriptors, returnDescriptor) {
82
99
  function discoverInheritedInterfaceVfuncs(klass, parentGtype, claimedMethodNames) {
83
100
  const bindings = [];
84
101
  for (const interfaceGtype of typeInterfaces(parentGtype)) {
85
- const vfuncs = discoverInterfaceVfuncs(klass, interfaceGtype, claimedMethodNames);
86
- if (vfuncs.length > 0) {
87
- bindings.push({ gtype: interfaceGtype, vfuncs });
102
+ const [first, ...rest] = discoverInterfaceVfuncs(klass, interfaceGtype, claimedMethodNames);
103
+ if (first !== undefined) {
104
+ bindings.push({ gtype: interfaceGtype, vtableSize: first.vtableSize, vfuncs: [first, ...rest] });
88
105
  }
89
106
  }
90
107
  return bindings;
91
108
  }
92
109
  function discoverInterfaceVfuncs(klass, interfaceGtype, claimedMethodNames) {
93
110
  const vfuncRegistry = getInterfaceVfuncRegistry(interfaceGtype);
94
- if (!vfuncRegistry)
111
+ if (!vfuncRegistry) {
95
112
  return [];
113
+ }
96
114
  return collectDiscoveredVfuncs(klass, (methodName) => {
97
115
  const entry = vfuncRegistry[methodName];
98
116
  return entry?.kind === "interface" ? entry : undefined;
@@ -104,21 +122,57 @@ function findClassVfuncDescriptor(klass, methodName) {
104
122
  return entry?.kind === "class" ? entry : undefined;
105
123
  }) ?? null);
106
124
  }
107
- function toNativeOptions(classVfuncs, interfaceBindings) {
125
+ function propertyVfuncs(klass, accessors) {
126
+ if (accessors.length === 0) {
127
+ return [];
128
+ }
129
+ return [
130
+ buildPropertyVfunc(klass, "getProperty", makeGetProperty(accessors), true),
131
+ buildPropertyVfunc(klass, "setProperty", makeSetProperty(accessors), false),
132
+ ];
133
+ }
134
+ // `get_property` fills a GValue the caller owns, so the marshalled copy handed to JavaScript has to
135
+ // be written back into it; `set_property` only reads its GValue and needs no copy back.
136
+ function markValueCallerAllocated(argDescriptors) {
137
+ return argDescriptors.map((arg, index) => index === VALUE_ARG_INDEX ? { ...arg, callerAllocated: true } : arg);
138
+ }
139
+ function buildPropertyVfunc(klass, methodName, fn, isValueOut) {
140
+ const descriptor = findClassVfuncDescriptor(klass, methodName);
141
+ if (!descriptor) {
142
+ throw new Error(`registerClass: the parent class exposes no '${methodName}' vtable slot`);
143
+ }
144
+ const argDescriptors = isValueOut
145
+ ? markValueCallerAllocated(descriptor.argDescriptors)
146
+ : descriptor.argDescriptors;
147
+ return {
148
+ ...descriptor,
149
+ methodName,
150
+ argDescriptors,
151
+ fn: wrapVfunc(fn, argDescriptors, descriptor.returnDescriptor),
152
+ };
153
+ }
154
+ function toNativeOptions(classVfuncs, interfaceBindings, properties) {
108
155
  const hasInterfaces = interfaceBindings.length > 0;
109
156
  const hasClassVfuncs = classVfuncs.length > 0;
110
- if (!hasClassVfuncs && !hasInterfaces) {
157
+ const hasProperties = Object.keys(properties).length > 0;
158
+ if (!hasClassVfuncs && !hasInterfaces && !hasProperties) {
111
159
  return undefined;
112
160
  }
113
161
  const options = {};
114
- if (hasClassVfuncs)
162
+ if (hasProperties) {
163
+ options.properties = toNativeProperties(properties);
164
+ }
165
+ if (hasClassVfuncs) {
115
166
  options.vfuncs = [...classVfuncs];
167
+ }
116
168
  if (hasInterfaces) {
117
169
  options.interfaces = interfaceBindings.map((binding) => ({
118
170
  type: binding.gtype,
171
+ vtableSize: binding.vtableSize,
119
172
  vfuncs: [...binding.vfuncs],
120
173
  }));
121
174
  }
122
175
  return options;
123
176
  }
177
+ export { registerClass };
124
178
  //# sourceMappingURL=register-class.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"register-class.js","sourceRoot":"","sources":["../src/register-class.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RegisterClassOptions as NativeRegisterClassOptions,\n type RegisterClassVfunc as NativeRegisterClassVfunc,\n registerClass as nativeRegisterClass,\n} from \"@gtkx/native\";\nimport { type AnyClass, getParentClass, walkClassChain } from \"@gtkx/utils\";\nimport { wrapCallback } from \"./callback.js\";\nimport {\n getClassType,\n getInterfaceVfuncRegistry,\n getVfuncRegistry,\n registerClassType,\n type VfuncDescriptor,\n} from \"./registry.js\";\nimport { TYPE_INVALID, typeInterfaces } from \"./type.js\";\n\ntype RegisterClassOptions = { typeName?: string };\ntype VfuncFn = NativeRegisterClassVfunc[\"fn\"];\ntype DiscoveredVfunc<K extends \"class\" | \"interface\"> = VfuncDescriptor<K> & { methodName: string; fn: VfuncFn };\ntype DiscoveredClassVfunc = DiscoveredVfunc<\"class\">;\ntype DiscoveredInterfaceVfunc = DiscoveredVfunc<\"interface\">;\ntype InterfaceVfuncBinding = { gtype: bigint; vfuncs: DiscoveredInterfaceVfunc[] };\n\n/**\n * Registers a subclass of a wrapper class as a new GType, wiring up any class and\n * inherited-interface virtual functions it overrides. Throws if the class does not\n * extend a registered wrapper class, has no derivable type name, or overrides an\n * unsupported construct-time vtable slot.\n *\n * @param klass The subclass to register.\n * @param options Registration options, such as an explicit type name.\n * @returns The same class, now registered.\n */\nexport function registerClass<T extends AnyClass>(klass: T, options: RegisterClassOptions = {}): T {\n const parentType = resolveParentType(klass);\n if (parentType === TYPE_INVALID) {\n throw new TypeError(`registerClass: ${klass.name} must extend a registered wrapper class`);\n }\n\n const name = options.typeName ?? klass.name;\n\n if (!name) {\n throw new Error(\"registerClass: cannot derive a GType name (anonymous class with no typeName option)\");\n }\n\n const classVfuncs = discoverClassVfuncs(klass);\n const claimedMethodNames = new Set(classVfuncs.map((vfunc) => vfunc.methodName));\n const interfaceBindings = discoverInheritedInterfaceVfuncs(klass, parentType, claimedMethodNames);\n\n const nativeOptions = toNativeOptions(classVfuncs, interfaceBindings);\n const newType: bigint = nativeRegisterClass(name, parentType, nativeOptions);\n registerClassType(klass, newType);\n\n return klass;\n}\n\nfunction resolveParentType(klass: AnyClass): bigint {\n return (\n walkClassChain(getParentClass(klass), (cls) => {\n const gtype = getClassType(cls);\n return gtype !== TYPE_INVALID ? gtype : undefined;\n }) ?? TYPE_INVALID\n );\n}\n\nfunction ownInstanceMethodNames(klass: AnyClass): string[] {\n const proto = (klass as { prototype?: object }).prototype;\n if (!proto) return [];\n return Object.getOwnPropertyNames(proto).filter((name) => {\n if (name === \"constructor\") return false;\n return typeof (proto as Record<string, unknown>)[name] === \"function\";\n });\n}\n\nfunction collectDiscoveredVfuncs<K extends \"class\" | \"interface\">(\n klass: AnyClass,\n resolveDescriptor: (methodName: string) => VfuncDescriptor<K> | undefined,\n skip?: Set<string>,\n): DiscoveredVfunc<K>[] {\n const proto = (klass as { prototype: Record<string, VfuncFn> }).prototype;\n const result: DiscoveredVfunc<K>[] = [];\n for (const methodName of ownInstanceMethodNames(klass)) {\n if (skip?.has(methodName)) continue;\n const descriptor = resolveDescriptor(methodName);\n if (!descriptor) continue;\n const fn = proto[methodName];\n if (!fn) continue;\n result.push({\n ...descriptor,\n methodName,\n fn: wrapVfunc(fn, descriptor.argDescriptors, descriptor.returnDescriptor),\n });\n }\n return result;\n}\n\nconst UNSUPPORTED_CONSTRUCT_VFUNCS: Set<string> = new Set([\"constructed\", \"setProperty\", \"getProperty\"]);\n\nfunction discoverClassVfuncs(klass: AnyClass): DiscoveredClassVfunc[] {\n return collectDiscoveredVfuncs(klass, (methodName) => {\n const descriptor = findClassVfuncDescriptor(klass, methodName);\n if (descriptor && UNSUPPORTED_CONSTRUCT_VFUNCS.has(methodName)) {\n throw new Error(\n `registerClass: overriding the GObject construct-time vtable slot '${methodName}' is not supported; run construct-time initialization in the subclass constructor, after super(...), instead`,\n );\n }\n return descriptor ?? undefined;\n });\n}\n\nfunction wrapVfunc(\n fn: VfuncFn,\n argDescriptors: NativeRegisterClassVfunc[\"argDescriptors\"],\n returnDescriptor: NativeRegisterClassVfunc[\"returnDescriptor\"],\n): VfuncFn {\n return wrapCallback(fn as (...args: unknown[]) => unknown, { argDescriptors, returnDescriptor }, \"this\");\n}\n\nfunction discoverInheritedInterfaceVfuncs(\n klass: AnyClass,\n parentGtype: bigint,\n claimedMethodNames: Set<string>,\n): InterfaceVfuncBinding[] {\n const bindings: InterfaceVfuncBinding[] = [];\n for (const interfaceGtype of typeInterfaces(parentGtype)) {\n const vfuncs = discoverInterfaceVfuncs(klass, interfaceGtype, claimedMethodNames);\n if (vfuncs.length > 0) {\n bindings.push({ gtype: interfaceGtype, vfuncs });\n }\n }\n return bindings;\n}\n\nfunction discoverInterfaceVfuncs(\n klass: AnyClass,\n interfaceGtype: bigint,\n claimedMethodNames: Set<string>,\n): DiscoveredInterfaceVfunc[] {\n const vfuncRegistry = getInterfaceVfuncRegistry(interfaceGtype);\n if (!vfuncRegistry) return [];\n return collectDiscoveredVfuncs(\n klass,\n (methodName) => {\n const entry = vfuncRegistry[methodName];\n return entry?.kind === \"interface\" ? entry : undefined;\n },\n claimedMethodNames,\n );\n}\n\nfunction findClassVfuncDescriptor(klass: AnyClass, methodName: string): VfuncDescriptor<\"class\"> | null {\n return (\n walkClassChain(getParentClass(klass), (cls) => {\n const entry = getVfuncRegistry(cls)?.[methodName];\n return entry?.kind === \"class\" ? entry : undefined;\n }) ?? null\n );\n}\n\nfunction toNativeOptions(\n classVfuncs: DiscoveredClassVfunc[],\n interfaceBindings: InterfaceVfuncBinding[],\n): NativeRegisterClassOptions | undefined {\n const hasInterfaces = interfaceBindings.length > 0;\n const hasClassVfuncs = classVfuncs.length > 0;\n if (!hasClassVfuncs && !hasInterfaces) {\n return undefined;\n }\n const options: NativeRegisterClassOptions = {};\n if (hasClassVfuncs) options.vfuncs = [...classVfuncs];\n if (hasInterfaces) {\n options.interfaces = interfaceBindings.map((binding) => ({\n type: binding.gtype,\n vfuncs: [...binding.vfuncs],\n }));\n }\n return options;\n}\n"]}
1
+ {"version":3,"file":"register-class.js","sourceRoot":"","sources":["../src/register-class.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Descriptor } from \"@gtkx/native\";\nimport {\n registerClass as nativeRegisterClass,\n type RegisterClassOptions as NativeRegisterClassOptions,\n type RegisterClassVfunc as NativeRegisterClassVfunc,\n} from \"@gtkx/native\";\nimport { type AnyClass, getParentClass, walkClassChain } from \"@gtkx/utils\";\nimport { wrapCallback } from \"./callback.js\";\nimport {\n buildAccessors,\n makeGetProperty,\n makeSetProperty,\n type PropertyAccessor,\n type PropertySpec,\n toNativeProperties,\n} from \"./properties.js\";\nimport {\n getClassType,\n getInterfaceVfuncRegistry,\n getVfuncRegistry,\n registerClassType,\n type VfuncDescriptor,\n} from \"./registry.js\";\nimport { TYPE_INVALID, typeInterfaces } from \"./type.js\";\n\ntype RegisterClassOptions = {\n typeName?: string;\n /**\n * Properties to install on the new type, keyed by canonical property name. Each value is the\n * `GObject.ParamSpec` describing it, for example `GObject.paramSpecString(...)`. Accessors are\n * generated on the prototype for the dashed, underscored and camelCased spellings of the name\n * unless the class already defines one, and writing through them emits `notify`.\n */\n properties?: Record<string, PropertySpec>;\n};\n\ntype VfuncFn = NativeRegisterClassVfunc[\"fn\"];\ntype DiscoveredVfunc<K extends \"class\" | \"interface\"> = VfuncDescriptor<K> & { methodName: string; fn: VfuncFn };\ntype DiscoveredClassVfunc = DiscoveredVfunc<\"class\">;\ntype DiscoveredInterfaceVfunc = DiscoveredVfunc<\"interface\">;\ntype InterfaceVfuncBinding = { gtype: bigint; vtableSize: number; vfuncs: DiscoveredInterfaceVfunc[] };\n\nconst UNSUPPORTED_CONSTRUCT_VFUNCS: Set<string> = new Set([\"constructed\", \"setProperty\", \"getProperty\"]);\nconst VALUE_ARG_INDEX = 2;\n\n/**\n * Registers a subclass of a wrapper class as a new GType, wiring up any class and\n * inherited-interface virtual functions it overrides. Throws if the class does not\n * extend a registered wrapper class, has no derivable type name, or overrides an\n * unsupported construct-time vtable slot.\n *\n * @param klass The subclass to register.\n * @param options Registration options, such as an explicit type name.\n * @returns The same class, now registered.\n */\nfunction registerClass<T extends AnyClass>(klass: T, options: RegisterClassOptions = {}): T {\n const parentType = resolveParentType(klass);\n\n if (parentType === TYPE_INVALID) {\n throw new TypeError(`registerClass: ${klass.name} must extend a registered wrapper class`);\n }\n\n const name = options.typeName ?? klass.name;\n\n if (!name) {\n throw new Error(\"registerClass: cannot derive a GType name (anonymous class with no typeName option)\");\n }\n\n const properties = options.properties ?? {};\n const accessors = buildAccessors(klass, properties);\n const classVfuncs = [...discoverClassVfuncs(klass), ...propertyVfuncs(klass, accessors)];\n const claimedMethodNames = new Set(classVfuncs.map((vfunc) => vfunc.methodName));\n const interfaceBindings = discoverInheritedInterfaceVfuncs(klass, parentType, claimedMethodNames);\n const nativeOptions = toNativeOptions(classVfuncs, interfaceBindings, properties);\n const newType: bigint = nativeRegisterClass(name, parentType, nativeOptions);\n registerClassType(klass, newType);\n\n return klass;\n}\n\nfunction resolveParentType(klass: AnyClass): bigint {\n return (\n walkClassChain(getParentClass(klass), (cls) => {\n const gtype = getClassType(cls);\n\n return gtype === TYPE_INVALID ? undefined : gtype;\n }) ?? TYPE_INVALID\n );\n}\n\nfunction ownInstanceMethodNames(klass: AnyClass): string[] {\n const proto = (klass as { prototype?: object }).prototype;\n\n if (!proto) {\n return [];\n }\n\n return Object.getOwnPropertyNames(proto).filter((name) => {\n if (name === \"constructor\") {\n return false;\n }\n\n return typeof Object.getOwnPropertyDescriptor(proto, name)?.value === \"function\";\n });\n}\n\nfunction buildDiscoveredVfunc<K extends \"class\" | \"interface\">(\n proto: Record<string, VfuncFn>,\n methodName: string,\n resolveDescriptor: (methodName: string) => VfuncDescriptor<K> | undefined,\n skip: Set<string> | undefined,\n): DiscoveredVfunc<K> | undefined {\n if (skip?.has(methodName)) {\n return undefined;\n }\n\n const descriptor = resolveDescriptor(methodName);\n\n if (!descriptor) {\n return undefined;\n }\n\n const fn = proto[methodName];\n\n if (!fn) {\n return undefined;\n }\n\n return {\n ...descriptor,\n methodName,\n fn: wrapVfunc(fn, descriptor.argDescriptors, descriptor.returnDescriptor),\n };\n}\n\nfunction collectDiscoveredVfuncs<K extends \"class\" | \"interface\">(\n klass: AnyClass,\n resolveDescriptor: (methodName: string) => VfuncDescriptor<K> | undefined,\n skip?: Set<string>,\n): DiscoveredVfunc<K>[] {\n const proto = (klass as { prototype: Record<string, VfuncFn> }).prototype;\n const result: DiscoveredVfunc<K>[] = [];\n\n for (const methodName of ownInstanceMethodNames(klass)) {\n const discovered = buildDiscoveredVfunc(proto, methodName, resolveDescriptor, skip);\n\n if (discovered) {\n result.push(discovered);\n }\n }\n\n return result;\n}\n\nfunction discoverClassVfuncs(klass: AnyClass): DiscoveredClassVfunc[] {\n return collectDiscoveredVfuncs(klass, (methodName) => {\n const descriptor = findClassVfuncDescriptor(klass, methodName);\n\n if (descriptor && UNSUPPORTED_CONSTRUCT_VFUNCS.has(methodName)) {\n throw new Error(\n `registerClass: overriding the GObject construct-time vtable slot '${methodName}' is not ` +\n \"supported; run construct-time initialization in the subclass constructor, after \" +\n \"super(...), instead\",\n );\n }\n\n return descriptor ?? undefined;\n });\n}\n\nfunction wrapVfunc(\n fn: VfuncFn,\n argDescriptors: NativeRegisterClassVfunc[\"argDescriptors\"],\n returnDescriptor: NativeRegisterClassVfunc[\"returnDescriptor\"],\n): VfuncFn {\n return wrapCallback(fn as (...args: unknown[]) => unknown, { argDescriptors, returnDescriptor }, \"this\");\n}\n\nfunction discoverInheritedInterfaceVfuncs(\n klass: AnyClass,\n parentGtype: bigint,\n claimedMethodNames: Set<string>,\n): InterfaceVfuncBinding[] {\n const bindings: InterfaceVfuncBinding[] = [];\n\n for (const interfaceGtype of typeInterfaces(parentGtype)) {\n const [first, ...rest] = discoverInterfaceVfuncs(klass, interfaceGtype, claimedMethodNames);\n\n if (first !== undefined) {\n bindings.push({ gtype: interfaceGtype, vtableSize: first.vtableSize, vfuncs: [first, ...rest] });\n }\n }\n\n return bindings;\n}\n\nfunction discoverInterfaceVfuncs(\n klass: AnyClass,\n interfaceGtype: bigint,\n claimedMethodNames: Set<string>,\n): DiscoveredInterfaceVfunc[] {\n const vfuncRegistry = getInterfaceVfuncRegistry(interfaceGtype);\n\n if (!vfuncRegistry) {\n return [];\n }\n\n return collectDiscoveredVfuncs(\n klass,\n (methodName) => {\n const entry = vfuncRegistry[methodName];\n\n return entry?.kind === \"interface\" ? entry : undefined;\n },\n claimedMethodNames,\n );\n}\n\nfunction findClassVfuncDescriptor(klass: AnyClass, methodName: string): VfuncDescriptor<\"class\"> | null {\n return (\n walkClassChain(getParentClass(klass), (cls) => {\n const entry = getVfuncRegistry(cls)?.[methodName];\n\n return entry?.kind === \"class\" ? entry : undefined;\n }) ?? null\n );\n}\n\nfunction propertyVfuncs(klass: AnyClass, accessors: PropertyAccessor[]): DiscoveredClassVfunc[] {\n if (accessors.length === 0) {\n return [];\n }\n\n return [\n buildPropertyVfunc(klass, \"getProperty\", makeGetProperty(accessors), true),\n buildPropertyVfunc(klass, \"setProperty\", makeSetProperty(accessors), false),\n ];\n}\n\n// `get_property` fills a GValue the caller owns, so the marshalled copy handed to JavaScript has to\n// be written back into it; `set_property` only reads its GValue and needs no copy back.\nfunction markValueCallerAllocated(argDescriptors: Descriptor[]): Descriptor[] {\n return argDescriptors.map((arg, index) =>\n index === VALUE_ARG_INDEX ? { ...arg, callerAllocated: true } : arg);\n}\n\nfunction buildPropertyVfunc(\n klass: AnyClass,\n methodName: string,\n fn: VfuncFn,\n isValueOut: boolean,\n): DiscoveredClassVfunc {\n const descriptor = findClassVfuncDescriptor(klass, methodName);\n\n if (!descriptor) {\n throw new Error(`registerClass: the parent class exposes no '${methodName}' vtable slot`);\n }\n\n const argDescriptors = isValueOut\n ? markValueCallerAllocated(descriptor.argDescriptors)\n : descriptor.argDescriptors;\n\n return {\n ...descriptor,\n methodName,\n argDescriptors,\n fn: wrapVfunc(fn, argDescriptors, descriptor.returnDescriptor),\n };\n}\n\nfunction toNativeOptions(\n classVfuncs: DiscoveredClassVfunc[],\n interfaceBindings: InterfaceVfuncBinding[],\n properties: Record<string, PropertySpec>,\n): NativeRegisterClassOptions | undefined {\n const hasInterfaces = interfaceBindings.length > 0;\n const hasClassVfuncs = classVfuncs.length > 0;\n const hasProperties = Object.keys(properties).length > 0;\n\n if (!hasClassVfuncs && !hasInterfaces && !hasProperties) {\n return undefined;\n }\n\n const options: NativeRegisterClassOptions = {};\n\n if (hasProperties) {\n options.properties = toNativeProperties(properties);\n }\n\n if (hasClassVfuncs) {\n options.vfuncs = [...classVfuncs];\n }\n\n if (hasInterfaces) {\n options.interfaces = interfaceBindings.map((binding) => ({\n type: binding.gtype,\n vtableSize: binding.vtableSize,\n vfuncs: [...binding.vfuncs],\n }));\n }\n\n return options;\n}\n\nexport { registerClass };\n"]}
@@ -1,25 +1,26 @@
1
- import { type ExternalObject, type Handle, type RegisterClassVfunc as NativeRegisterClassVfunc } from "@gtkx/native";
2
1
  import type { AnyClass } from "@gtkx/utils";
2
+ import { type ExternalObject, type Handle, type RegisterClassVfunc as NativeRegisterClassVfunc } from "@gtkx/native";
3
3
  import type { Mixin } from "./mixin.js";
4
4
  import { type TypedClass } from "./type.js";
5
5
  /**
6
6
  * Static side of class `C` with its construct signature preserved but the member
7
7
  * named `K` (default `"new"`) removed.
8
8
  */
9
- export type StaticBase<C, K extends PropertyKey = "new"> = Omit<C, K> & (C extends new (...args: infer A) => infer R ? new (...args: A) => R : never);
10
- export type VfuncDescriptor<K extends "class" | "interface"> = {
9
+ type StaticBase<C, K extends PropertyKey = "new"> = Omit<C, K> & (C extends new (...args: infer A) => infer R ? new (...args: A) => R : never);
10
+ type VfuncDescriptor<K extends "class" | "interface"> = {
11
11
  kind: K;
12
12
  className: string;
13
13
  vfuncName: string;
14
14
  byteOffset: number;
15
+ vtableSize: number;
15
16
  argDescriptors: NativeRegisterClassVfunc["argDescriptors"];
16
17
  returnDescriptor: NativeRegisterClassVfunc["returnDescriptor"];
17
18
  };
18
- export type VfuncRegistry = Record<string, VfuncDescriptor<"class"> | VfuncDescriptor<"interface">>;
19
- export declare function getClassType(cls: AnyClass): bigint;
19
+ type VfuncRegistry = Record<string, VfuncDescriptor<"class"> | VfuncDescriptor<"interface">>;
20
+ declare function getClassType(cls: AnyClass): bigint;
20
21
  /** Returns the GType tag of the given wrapper instance. */
21
- export declare function getInstanceType(instance: object): bigint;
22
- export declare function registerClassType(cls: AnyClass, type: bigint): void;
22
+ declare function getInstanceType(instance: object): bigint;
23
+ declare function registerClassType(cls: AnyClass, type: bigint): void;
23
24
  /**
24
25
  * Registers a wrapper class as the JS representation of a GType, optionally
25
26
  * installing a registry of virtual functions.
@@ -27,7 +28,7 @@ export declare function registerClassType(cls: AnyClass, type: bigint): void;
27
28
  * @param type GType the class wraps.
28
29
  * @param vfuncs Virtual functions the class overrides.
29
30
  */
30
- export declare function registerWrapperClass(cls: AnyClass, type: bigint, vfuncs?: VfuncRegistry): void;
31
+ declare function registerWrapperClass(cls: AnyClass, type: bigint, vfuncs?: VfuncRegistry): void;
31
32
  /**
32
33
  * Registers a GInterface, associating its GType with a mixin used to compose the
33
34
  * interface onto wrapper classes and an optional virtual function registry.
@@ -36,7 +37,7 @@ export declare function registerWrapperClass(cls: AnyClass, type: bigint, vfuncs
36
37
  * @param mixin Mixin that applies the interface to a wrapper class.
37
38
  * @param vfuncs Virtual functions the interface exposes.
38
39
  */
39
- export declare function registerInterface(cls: AnyClass, type: bigint, mixin: Mixin, vfuncs?: VfuncRegistry): void;
40
+ declare function registerInterface(cls: AnyClass, type: bigint, mixin: Mixin, vfuncs?: VfuncRegistry): void;
40
41
  /**
41
42
  * Wraps a native handle in a JS wrapper instance. With no class, resolves and
42
43
  * reuses the wrapper for the handle's runtime GType (composing interface mixins);
@@ -45,23 +46,24 @@ export declare function registerInterface(cls: AnyClass, type: bigint, mixin: Mi
45
46
  * @param handle Native handle to wrap.
46
47
  * @param cls Wrapper class to instantiate, or omitted to resolve it from the runtime type.
47
48
  */
48
- export declare function wrapHandle(handle: null | undefined, cls?: AnyClass): null;
49
- export declare function wrapHandle<T extends object>(handle: ExternalObject<Handle>, cls: AnyClass<T>): T;
50
- export declare function wrapHandle<T extends object>(handle: ExternalObject<Handle> | null | undefined, cls: AnyClass<T>): T | null;
51
- export declare function wrapHandle<T extends object = TypedClass>(handle: ExternalObject<Handle>, cls?: AnyClass): T;
52
- export declare function wrapHandle<T extends object = TypedClass>(handle: ExternalObject<Handle> | null | undefined, cls?: AnyClass): T | null;
49
+ declare function wrapHandle(handle: null | undefined, cls?: AnyClass): null;
50
+ declare function wrapHandle<T extends object>(handle: ExternalObject<Handle>, cls: AnyClass<T>): T;
51
+ declare function wrapHandle<T extends object>(handle: ExternalObject<Handle> | null | undefined, cls: AnyClass<T>): T | null;
52
+ declare function wrapHandle(handle: ExternalObject<Handle>, cls?: AnyClass): TypedClass;
53
+ declare function wrapHandle(handle: ExternalObject<Handle> | null | undefined, cls?: AnyClass): TypedClass | null;
53
54
  /**
54
55
  * Returns the wrapper class registered for a GType, walking up to ancestor types,
55
56
  * and throws if none is registered.
56
57
  */
57
- export declare function getWrapperClass(type: bigint): AnyClass;
58
- export declare function resolveWrapperClass(type: bigint): AnyClass | null;
58
+ declare function getWrapperClass(type: bigint): AnyClass;
59
+ declare function resolveWrapperClass(type: bigint): AnyClass | null;
59
60
  /** Returns the native handle bound to a wrapper instance, throwing if none is set. */
60
- export declare function getHandle(instance: object): ExternalObject<Handle>;
61
+ declare function getHandle(instance: object): ExternalObject<Handle>;
61
62
  /** Returns the native handle bound to an instance, or undefined when there is none or the instance is null. */
62
- export declare function tryGetHandle(instance: object | null | undefined): ExternalObject<Handle> | undefined;
63
+ declare function tryGetHandle(instance: object | null | undefined): ExternalObject<Handle> | undefined;
63
64
  /** Associates a native handle with a wrapper instance. */
64
- export declare function setHandle(instance: object, handle: ExternalObject<Handle>): void;
65
- export declare function getVfuncRegistry(cls: object): VfuncRegistry | undefined;
66
- export declare function getInterfaceVfuncRegistry(type: bigint): VfuncRegistry | undefined;
65
+ declare function setHandle(instance: object, handle: ExternalObject<Handle>): void;
66
+ declare function getVfuncRegistry(cls: object): VfuncRegistry | undefined;
67
+ declare function getInterfaceVfuncRegistry(type: bigint): VfuncRegistry | undefined;
68
+ export { getClassType, getInstanceType, registerClassType, registerWrapperClass, registerInterface, wrapHandle, getWrapperClass, resolveWrapperClass, getHandle, tryGetHandle, setHandle, getVfuncRegistry, getInterfaceVfuncRegistry, type StaticBase, type VfuncDescriptor, type VfuncRegistry, };
67
69
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/registry.js CHANGED
@@ -9,19 +9,20 @@ const interfaceVfuncRegistry = new Map();
9
9
  function setClassType(cls, type) {
10
10
  cls.prototype.__type__ = type;
11
11
  }
12
- export function getClassType(cls) {
12
+ function getClassType(cls) {
13
13
  const proto = cls.prototype;
14
14
  return Object.hasOwn(proto, "__type__") ? proto.__type__ : TYPE_INVALID;
15
15
  }
16
16
  /** Returns the GType tag of the given wrapper instance. */
17
- export function getInstanceType(instance) {
17
+ function getInstanceType(instance) {
18
18
  return getClassType(instance.constructor);
19
19
  }
20
- export function registerClassType(cls, type) {
21
- if (type !== TYPE_INVALID) {
22
- classRegistry.set(type, cls);
23
- setClassType(cls, type);
20
+ function registerClassType(cls, type) {
21
+ if (type === TYPE_INVALID) {
22
+ return;
24
23
  }
24
+ classRegistry.set(type, cls);
25
+ setClassType(cls, type);
25
26
  }
26
27
  /**
27
28
  * Registers a wrapper class as the JS representation of a GType, optionally
@@ -30,10 +31,11 @@ export function registerClassType(cls, type) {
30
31
  * @param type GType the class wraps.
31
32
  * @param vfuncs Virtual functions the class overrides.
32
33
  */
33
- export function registerWrapperClass(cls, type, vfuncs) {
34
+ function registerWrapperClass(cls, type, vfuncs) {
34
35
  registerClassType(cls, type);
35
- if (vfuncs)
36
+ if (vfuncs) {
36
37
  registerVfuncRegistry(cls, vfuncs);
38
+ }
37
39
  }
38
40
  /**
39
41
  * Registers a GInterface, associating its GType with a mixin used to compose the
@@ -43,17 +45,20 @@ export function registerWrapperClass(cls, type, vfuncs) {
43
45
  * @param mixin Mixin that applies the interface to a wrapper class.
44
46
  * @param vfuncs Virtual functions the interface exposes.
45
47
  */
46
- export function registerInterface(cls, type, mixin, vfuncs) {
47
- if (type === TYPE_INVALID)
48
+ function registerInterface(cls, type, mixin, vfuncs) {
49
+ if (type === TYPE_INVALID) {
48
50
  return;
51
+ }
49
52
  setClassType(cls, type);
50
53
  interfaceMixinRegistry.set(type, mixin);
51
- if (vfuncs)
54
+ if (vfuncs) {
52
55
  registerInterfaceVfuncRegistry(type, vfuncs);
56
+ }
53
57
  }
54
- export function wrapHandle(handle, cls) {
55
- if (handle === null || handle === undefined)
58
+ function wrapHandle(handle, cls) {
59
+ if (handle === null || handle === undefined) {
56
60
  return null;
61
+ }
57
62
  if (cls === undefined) {
58
63
  return getOrCreateWrapper(handle);
59
64
  }
@@ -65,72 +70,84 @@ export function wrapHandle(handle, cls) {
65
70
  * Returns the wrapper class registered for a GType, walking up to ancestor types,
66
71
  * and throws if none is registered.
67
72
  */
68
- export function getWrapperClass(type) {
73
+ function getWrapperClass(type) {
69
74
  const cls = resolveWrapperClass(type);
70
75
  if (!cls) {
71
76
  throw new Error(`No registered wrapper class for type '${typeName(type) ?? String(type)}'`);
72
77
  }
73
78
  return cls;
74
79
  }
75
- export function resolveWrapperClass(type) {
80
+ function resolveWrapperClass(type) {
76
81
  let currentType = type;
77
82
  while (currentType !== TYPE_INVALID) {
78
83
  const cls = classRegistry.get(currentType);
79
- if (cls)
84
+ if (cls) {
80
85
  return cls;
86
+ }
81
87
  currentType = typeParent(currentType);
82
88
  }
83
89
  return null;
84
90
  }
91
+ function applyInterfaceMixin(cls, type, baseType, applied) {
92
+ if (applied.has(type) || typeIsA(baseType, type)) {
93
+ return cls;
94
+ }
95
+ const mixin = interfaceMixinRegistry.get(type);
96
+ if (mixin === undefined) {
97
+ return cls;
98
+ }
99
+ applied.add(type);
100
+ return mixin(cls);
101
+ }
85
102
  function createComposedClass(base, runtimeType) {
86
103
  const baseType = getClassType(base);
87
104
  const applied = new Set();
88
105
  let cls = base;
89
106
  for (const type of typeInterfaces(runtimeType)) {
90
- if (applied.has(type) || typeIsA(baseType, type))
91
- continue;
92
- const mixin = interfaceMixinRegistry.get(type);
93
- if (mixin === undefined)
94
- continue;
95
- applied.add(type);
96
- cls = mixin(cls);
107
+ cls = applyInterfaceMixin(cls, type, baseType, applied);
97
108
  }
98
109
  return applied.size === 0 ? base : cls;
99
110
  }
100
111
  function resolveComposedClass(runtimeType) {
101
112
  const exact = classRegistry.get(runtimeType);
102
- if (exact)
113
+ if (exact) {
103
114
  return exact;
115
+ }
104
116
  const cached = composedClassRegistry.get(runtimeType);
105
- if (cached)
117
+ if (cached) {
106
118
  return cached;
119
+ }
107
120
  const base = resolveWrapperClass(runtimeType);
108
- if (base === null)
121
+ if (base === null) {
109
122
  return null;
123
+ }
110
124
  const composed = createComposedClass(base, runtimeType);
111
- if (composed === base)
125
+ if (composed === base) {
112
126
  return base;
127
+ }
113
128
  setClassType(composed, runtimeType);
114
129
  composedClassRegistry.set(runtimeType, composed);
115
130
  return composed;
116
131
  }
117
132
  function getOrCreateWrapper(handle) {
118
133
  const existing = getWrapper(handle);
119
- if (existing)
134
+ if (existing) {
120
135
  return existing;
136
+ }
121
137
  const runtimeType = getType(handle);
122
138
  if (runtimeType === TYPE_INVALID) {
123
139
  throw new Error("Cannot resolve runtime GLib type from handle");
124
140
  }
125
141
  const cls = resolveComposedClass(runtimeType);
126
- if (!cls)
142
+ if (!cls) {
127
143
  throw new Error(`Expected registered GLib type, got type ${String(runtimeType)}`);
144
+ }
128
145
  const instance = Object.create(cls.prototype);
129
146
  registerWrapper(handle, instance);
130
147
  return instance;
131
148
  }
132
149
  /** Returns the native handle bound to a wrapper instance, throwing if none is set. */
133
- export function getHandle(instance) {
150
+ function getHandle(instance) {
134
151
  const handle = handleMap.get(instance);
135
152
  if (handle === undefined) {
136
153
  const name = instance.constructor?.name ?? "object";
@@ -139,11 +156,11 @@ export function getHandle(instance) {
139
156
  return handle;
140
157
  }
141
158
  /** Returns the native handle bound to an instance, or undefined when there is none or the instance is null. */
142
- export function tryGetHandle(instance) {
159
+ function tryGetHandle(instance) {
143
160
  return instance == null ? undefined : handleMap.get(instance);
144
161
  }
145
162
  /** Associates a native handle with a wrapper instance. */
146
- export function setHandle(instance, handle) {
163
+ function setHandle(instance, handle) {
147
164
  handleMap.set(instance, handle);
148
165
  }
149
166
  function registerWrapper(handle, instance) {
@@ -153,15 +170,17 @@ function registerWrapper(handle, instance) {
153
170
  function registerVfuncRegistry(cls, registry) {
154
171
  vfuncRegistry.set(cls, registry);
155
172
  }
156
- export function getVfuncRegistry(cls) {
173
+ function getVfuncRegistry(cls) {
157
174
  return vfuncRegistry.get(cls);
158
175
  }
159
176
  function registerInterfaceVfuncRegistry(type, registry) {
160
- if (type === TYPE_INVALID)
177
+ if (type === TYPE_INVALID) {
161
178
  return;
179
+ }
162
180
  interfaceVfuncRegistry.set(type, registry);
163
181
  }
164
- export function getInterfaceVfuncRegistry(type) {
182
+ function getInterfaceVfuncRegistry(type) {
165
183
  return interfaceVfuncRegistry.get(type);
166
184
  }
185
+ export { getClassType, getInstanceType, registerClassType, registerWrapperClass, registerInterface, wrapHandle, getWrapperClass, resolveWrapperClass, getHandle, tryGetHandle, setHandle, getVfuncRegistry, getInterfaceVfuncRegistry, };
167
186
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type ExternalObject,\n getType,\n getWrapper,\n type Handle,\n type RegisterClassVfunc as NativeRegisterClassVfunc,\n setWrapper,\n} from \"@gtkx/native\";\nimport type { AnyClass } from \"@gtkx/utils\";\nimport type { Mixin, MixinReceiver } from \"./mixin.js\";\nimport { TYPE_INVALID, type TypedClass, typeInterfaces, typeIsA, typeName, typeParent } from \"./type.js\";\n\n/**\n * Static side of class `C` with its construct signature preserved but the member\n * named `K` (default `\"new\"`) removed.\n */\nexport type StaticBase<C, K extends PropertyKey = \"new\"> = Omit<C, K> &\n (C extends new (...args: infer A) => infer R ? new (...args: A) => R : never);\n\nexport type VfuncDescriptor<K extends \"class\" | \"interface\"> = {\n kind: K;\n className: string;\n vfuncName: string;\n byteOffset: number;\n argDescriptors: NativeRegisterClassVfunc[\"argDescriptors\"];\n returnDescriptor: NativeRegisterClassVfunc[\"returnDescriptor\"];\n};\n\nexport type VfuncRegistry = Record<string, VfuncDescriptor<\"class\"> | VfuncDescriptor<\"interface\">>;\n\nconst classRegistry = new Map<bigint, AnyClass>();\nconst interfaceMixinRegistry = new Map<bigint, Mixin>();\nconst composedClassRegistry = new Map<bigint, AnyClass>();\nconst handleMap = new WeakMap<object, ExternalObject<Handle>>();\nconst vfuncRegistry = new WeakMap<object, VfuncRegistry>();\nconst interfaceVfuncRegistry = new Map<bigint, VfuncRegistry>();\n\nfunction setClassType(cls: AnyClass, type: bigint): void {\n (cls.prototype as { [K in keyof TypedClass]: TypedClass[K] }).__type__ = type;\n}\n\nexport function getClassType(cls: AnyClass): bigint {\n const proto: object = cls.prototype;\n return Object.hasOwn(proto, \"__type__\") ? (proto as TypedClass).__type__ : TYPE_INVALID;\n}\n\n/** Returns the GType tag of the given wrapper instance. */\nexport function getInstanceType(instance: object): bigint {\n return getClassType(instance.constructor as AnyClass);\n}\n\nexport function registerClassType(cls: AnyClass, type: bigint): void {\n if (type !== TYPE_INVALID) {\n classRegistry.set(type, cls);\n setClassType(cls, type);\n }\n}\n\n/**\n * Registers a wrapper class as the JS representation of a GType, optionally\n * installing a registry of virtual functions.\n * @param cls Wrapper class to associate with the type.\n * @param type GType the class wraps.\n * @param vfuncs Virtual functions the class overrides.\n */\nexport function registerWrapperClass(cls: AnyClass, type: bigint, vfuncs?: VfuncRegistry): void {\n registerClassType(cls, type);\n if (vfuncs) registerVfuncRegistry(cls, vfuncs);\n}\n\n/**\n * Registers a GInterface, associating its GType with a mixin used to compose the\n * interface onto wrapper classes and an optional virtual function registry.\n * @param cls Class carrying the interface's GType tag.\n * @param type GType of the interface.\n * @param mixin Mixin that applies the interface to a wrapper class.\n * @param vfuncs Virtual functions the interface exposes.\n */\nexport function registerInterface(cls: AnyClass, type: bigint, mixin: Mixin, vfuncs?: VfuncRegistry): void {\n if (type === TYPE_INVALID) return;\n setClassType(cls, type);\n interfaceMixinRegistry.set(type, mixin);\n if (vfuncs) registerInterfaceVfuncRegistry(type, vfuncs);\n}\n\n/**\n * Wraps a native handle in a JS wrapper instance. With no class, resolves and\n * reuses the wrapper for the handle's runtime GType (composing interface mixins);\n * with an explicit class, creates a bare instance backed by the handle. Returns\n * null for a null or undefined handle.\n * @param handle Native handle to wrap.\n * @param cls Wrapper class to instantiate, or omitted to resolve it from the runtime type.\n */\nexport function wrapHandle(handle: null | undefined, cls?: AnyClass): null;\nexport function wrapHandle<T extends object>(handle: ExternalObject<Handle>, cls: AnyClass<T>): T;\nexport function wrapHandle<T extends object>(\n handle: ExternalObject<Handle> | null | undefined,\n cls: AnyClass<T>,\n): T | null;\nexport function wrapHandle<T extends object = TypedClass>(handle: ExternalObject<Handle>, cls?: AnyClass): T;\nexport function wrapHandle<T extends object = TypedClass>(\n handle: ExternalObject<Handle> | null | undefined,\n cls?: AnyClass,\n): T | null;\nexport function wrapHandle(handle: ExternalObject<Handle> | null | undefined, cls?: AnyClass): object | null {\n if (handle === null || handle === undefined) return null;\n if (cls === undefined) {\n return getOrCreateWrapper(handle);\n }\n const instance: object = Object.create(cls.prototype);\n setHandle(instance, handle);\n return instance;\n}\n\n/**\n * Returns the wrapper class registered for a GType, walking up to ancestor types,\n * and throws if none is registered.\n */\nexport function getWrapperClass(type: bigint): AnyClass {\n const cls = resolveWrapperClass(type);\n if (!cls) {\n throw new Error(`No registered wrapper class for type '${typeName(type) ?? String(type)}'`);\n }\n return cls;\n}\n\nexport function resolveWrapperClass(type: bigint): AnyClass | null {\n let currentType = type;\n while (currentType !== TYPE_INVALID) {\n const cls = classRegistry.get(currentType);\n if (cls) return cls;\n currentType = typeParent(currentType);\n }\n return null;\n}\n\nfunction createComposedClass(base: AnyClass, runtimeType: bigint): AnyClass {\n const baseType = getClassType(base);\n const applied = new Set<bigint>();\n let cls: AnyClass = base;\n for (const type of typeInterfaces(runtimeType)) {\n if (applied.has(type) || typeIsA(baseType, type)) continue;\n const mixin = interfaceMixinRegistry.get(type);\n if (mixin === undefined) continue;\n applied.add(type);\n cls = mixin(cls as AnyClass<MixinReceiver>);\n }\n return applied.size === 0 ? base : cls;\n}\n\nfunction resolveComposedClass(runtimeType: bigint): AnyClass | null {\n const exact = classRegistry.get(runtimeType);\n if (exact) return exact;\n const cached = composedClassRegistry.get(runtimeType);\n if (cached) return cached;\n const base = resolveWrapperClass(runtimeType);\n if (base === null) return null;\n const composed = createComposedClass(base, runtimeType);\n if (composed === base) return base;\n setClassType(composed, runtimeType);\n composedClassRegistry.set(runtimeType, composed);\n return composed;\n}\n\nfunction getOrCreateWrapper(handle: ExternalObject<Handle>): object {\n const existing = getWrapper(handle);\n if (existing) return existing;\n\n const runtimeType: bigint = getType(handle);\n if (runtimeType === TYPE_INVALID) {\n throw new Error(\"Cannot resolve runtime GLib type from handle\");\n }\n\n const cls = resolveComposedClass(runtimeType);\n if (!cls) throw new Error(`Expected registered GLib type, got type ${String(runtimeType)}`);\n const instance: object = Object.create(cls.prototype);\n registerWrapper(handle, instance);\n return instance;\n}\n\n/** Returns the native handle bound to a wrapper instance, throwing if none is set. */\nexport function getHandle(instance: object): ExternalObject<Handle> {\n const handle = handleMap.get(instance);\n if (handle === undefined) {\n const name = (instance as { constructor?: { name?: string } }).constructor?.name ?? \"object\";\n throw new Error(`No native handle associated with ${name}`);\n }\n return handle;\n}\n\n/** Returns the native handle bound to an instance, or undefined when there is none or the instance is null. */\nexport function tryGetHandle(instance: object | null | undefined): ExternalObject<Handle> | undefined {\n return instance == null ? undefined : handleMap.get(instance);\n}\n\n/** Associates a native handle with a wrapper instance. */\nexport function setHandle(instance: object, handle: ExternalObject<Handle>): void {\n handleMap.set(instance, handle);\n}\n\nfunction registerWrapper(handle: ExternalObject<Handle>, instance: object): void {\n setHandle(instance, handle);\n setWrapper(handle, instance);\n}\n\nfunction registerVfuncRegistry(cls: object, registry: VfuncRegistry): void {\n vfuncRegistry.set(cls, registry);\n}\n\nexport function getVfuncRegistry(cls: object): VfuncRegistry | undefined {\n return vfuncRegistry.get(cls);\n}\n\nfunction registerInterfaceVfuncRegistry(type: bigint, registry: VfuncRegistry): void {\n if (type === TYPE_INVALID) return;\n interfaceVfuncRegistry.set(type, registry);\n}\n\nexport function getInterfaceVfuncRegistry(type: bigint): VfuncRegistry | undefined {\n return interfaceVfuncRegistry.get(type);\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyClass } from \"@gtkx/utils\";\nimport {\n type ExternalObject,\n getType,\n getWrapper,\n type Handle,\n type RegisterClassVfunc as NativeRegisterClassVfunc,\n setWrapper,\n} from \"@gtkx/native\";\nimport type { Mixin, MixinReceiver } from \"./mixin.js\";\nimport { TYPE_INVALID, type TypedClass, typeInterfaces, typeIsA, typeName, typeParent } from \"./type.js\";\n\n/**\n * Static side of class `C` with its construct signature preserved but the member\n * named `K` (default `\"new\"`) removed.\n */\ntype StaticBase<C, K extends PropertyKey = \"new\"> = Omit<C, K> &\n (C extends new (...args: infer A) => infer R ? new (...args: A) => R : never);\n\ntype VfuncDescriptor<K extends \"class\" | \"interface\"> = {\n kind: K;\n className: string;\n vfuncName: string;\n byteOffset: number;\n vtableSize: number;\n argDescriptors: NativeRegisterClassVfunc[\"argDescriptors\"];\n returnDescriptor: NativeRegisterClassVfunc[\"returnDescriptor\"];\n};\n\ntype VfuncRegistry = Record<string, VfuncDescriptor<\"class\"> | VfuncDescriptor<\"interface\">>;\n\nconst classRegistry: Map<bigint, AnyClass> = new Map();\nconst interfaceMixinRegistry: Map<bigint, Mixin> = new Map();\nconst composedClassRegistry: Map<bigint, AnyClass> = new Map();\nconst handleMap: WeakMap<object, ExternalObject<Handle>> = new WeakMap();\nconst vfuncRegistry: WeakMap<object, VfuncRegistry> = new WeakMap();\nconst interfaceVfuncRegistry: Map<bigint, VfuncRegistry> = new Map();\n\nfunction setClassType(cls: AnyClass, type: bigint): void {\n (cls.prototype as { [K in keyof TypedClass]: TypedClass[K] }).__type__ = type;\n}\n\nfunction getClassType(cls: AnyClass): bigint {\n const proto: object = cls.prototype;\n\n return Object.hasOwn(proto, \"__type__\") ? (proto as TypedClass).__type__ : TYPE_INVALID;\n}\n\n/** Returns the GType tag of the given wrapper instance. */\nfunction getInstanceType(instance: object): bigint {\n return getClassType(instance.constructor as AnyClass);\n}\n\nfunction registerClassType(cls: AnyClass, type: bigint): void {\n if (type === TYPE_INVALID) {\n return;\n }\n\n classRegistry.set(type, cls);\n setClassType(cls, type);\n}\n\n/**\n * Registers a wrapper class as the JS representation of a GType, optionally\n * installing a registry of virtual functions.\n * @param cls Wrapper class to associate with the type.\n * @param type GType the class wraps.\n * @param vfuncs Virtual functions the class overrides.\n */\nfunction registerWrapperClass(cls: AnyClass, type: bigint, vfuncs?: VfuncRegistry): void {\n registerClassType(cls, type);\n\n if (vfuncs) {\n registerVfuncRegistry(cls, vfuncs);\n }\n}\n\n/**\n * Registers a GInterface, associating its GType with a mixin used to compose the\n * interface onto wrapper classes and an optional virtual function registry.\n * @param cls Class carrying the interface's GType tag.\n * @param type GType of the interface.\n * @param mixin Mixin that applies the interface to a wrapper class.\n * @param vfuncs Virtual functions the interface exposes.\n */\nfunction registerInterface(cls: AnyClass, type: bigint, mixin: Mixin, vfuncs?: VfuncRegistry): void {\n if (type === TYPE_INVALID) {\n return;\n }\n\n setClassType(cls, type);\n interfaceMixinRegistry.set(type, mixin);\n\n if (vfuncs) {\n registerInterfaceVfuncRegistry(type, vfuncs);\n }\n}\n\n/**\n * Wraps a native handle in a JS wrapper instance. With no class, resolves and\n * reuses the wrapper for the handle's runtime GType (composing interface mixins);\n * with an explicit class, creates a bare instance backed by the handle. Returns\n * null for a null or undefined handle.\n * @param handle Native handle to wrap.\n * @param cls Wrapper class to instantiate, or omitted to resolve it from the runtime type.\n */\nfunction wrapHandle(handle: null | undefined, cls?: AnyClass): null;\nfunction wrapHandle<T extends object>(handle: ExternalObject<Handle>, cls: AnyClass<T>): T;\n\nfunction wrapHandle<T extends object>(\n handle: ExternalObject<Handle> | null | undefined,\n cls: AnyClass<T>,\n): T | null;\n\nfunction wrapHandle(handle: ExternalObject<Handle>, cls?: AnyClass): TypedClass;\nfunction wrapHandle(handle: ExternalObject<Handle> | null | undefined, cls?: AnyClass): TypedClass | null;\n\nfunction wrapHandle(handle: ExternalObject<Handle> | null | undefined, cls?: AnyClass): object | null {\n if (handle === null || handle === undefined) {\n return null;\n }\n\n if (cls === undefined) {\n return getOrCreateWrapper(handle);\n }\n\n const instance: object = Object.create(cls.prototype) as object;\n setHandle(instance, handle);\n\n return instance;\n}\n\n/**\n * Returns the wrapper class registered for a GType, walking up to ancestor types,\n * and throws if none is registered.\n */\nfunction getWrapperClass(type: bigint): AnyClass {\n const cls = resolveWrapperClass(type);\n\n if (!cls) {\n throw new Error(`No registered wrapper class for type '${typeName(type) ?? String(type)}'`);\n }\n\n return cls;\n}\n\nfunction resolveWrapperClass(type: bigint): AnyClass | null {\n let currentType = type;\n\n while (currentType !== TYPE_INVALID) {\n const cls = classRegistry.get(currentType);\n\n if (cls) {\n return cls;\n }\n\n currentType = typeParent(currentType);\n }\n\n return null;\n}\n\nfunction applyInterfaceMixin(cls: AnyClass, type: bigint, baseType: bigint, applied: Set<bigint>): AnyClass {\n if (applied.has(type) || typeIsA(baseType, type)) {\n return cls;\n }\n\n const mixin = interfaceMixinRegistry.get(type);\n\n if (mixin === undefined) {\n return cls;\n }\n\n applied.add(type);\n\n return mixin(cls as AnyClass<MixinReceiver>);\n}\n\nfunction createComposedClass(base: AnyClass, runtimeType: bigint): AnyClass {\n const baseType = getClassType(base);\n const applied: Set<bigint> = new Set();\n let cls: AnyClass = base;\n\n for (const type of typeInterfaces(runtimeType)) {\n cls = applyInterfaceMixin(cls, type, baseType, applied);\n }\n\n return applied.size === 0 ? base : cls;\n}\n\nfunction resolveComposedClass(runtimeType: bigint): AnyClass | null {\n const exact = classRegistry.get(runtimeType);\n\n if (exact) {\n return exact;\n }\n\n const cached = composedClassRegistry.get(runtimeType);\n\n if (cached) {\n return cached;\n }\n\n const base = resolveWrapperClass(runtimeType);\n\n if (base === null) {\n return null;\n }\n\n const composed = createComposedClass(base, runtimeType);\n\n if (composed === base) {\n return base;\n }\n\n setClassType(composed, runtimeType);\n composedClassRegistry.set(runtimeType, composed);\n\n return composed;\n}\n\nfunction getOrCreateWrapper(handle: ExternalObject<Handle>): object {\n const existing = getWrapper(handle);\n\n if (existing) {\n return existing;\n }\n\n const runtimeType: bigint = getType(handle);\n\n if (runtimeType === TYPE_INVALID) {\n throw new Error(\"Cannot resolve runtime GLib type from handle\");\n }\n\n const cls = resolveComposedClass(runtimeType);\n\n if (!cls) {\n throw new Error(`Expected registered GLib type, got type ${String(runtimeType)}`);\n }\n\n const instance: object = Object.create(cls.prototype) as object;\n registerWrapper(handle, instance);\n\n return instance;\n}\n\n/** Returns the native handle bound to a wrapper instance, throwing if none is set. */\nfunction getHandle(instance: object): ExternalObject<Handle> {\n const handle = handleMap.get(instance);\n\n if (handle === undefined) {\n const name = (instance as { constructor?: { name?: string } }).constructor?.name ?? \"object\";\n throw new Error(`No native handle associated with ${name}`);\n }\n\n return handle;\n}\n\n/** Returns the native handle bound to an instance, or undefined when there is none or the instance is null. */\nfunction tryGetHandle(instance: object | null | undefined): ExternalObject<Handle> | undefined {\n return instance == null ? undefined : handleMap.get(instance);\n}\n\n/** Associates a native handle with a wrapper instance. */\nfunction setHandle(instance: object, handle: ExternalObject<Handle>): void {\n handleMap.set(instance, handle);\n}\n\nfunction registerWrapper(handle: ExternalObject<Handle>, instance: object): void {\n setHandle(instance, handle);\n setWrapper(handle, instance);\n}\n\nfunction registerVfuncRegistry(cls: object, registry: VfuncRegistry): void {\n vfuncRegistry.set(cls, registry);\n}\n\nfunction getVfuncRegistry(cls: object): VfuncRegistry | undefined {\n return vfuncRegistry.get(cls);\n}\n\nfunction registerInterfaceVfuncRegistry(type: bigint, registry: VfuncRegistry): void {\n if (type === TYPE_INVALID) {\n return;\n }\n\n interfaceVfuncRegistry.set(type, registry);\n}\n\nfunction getInterfaceVfuncRegistry(type: bigint): VfuncRegistry | undefined {\n return interfaceVfuncRegistry.get(type);\n}\n\nexport {\n getClassType,\n getInstanceType,\n registerClassType,\n registerWrapperClass,\n registerInterface,\n wrapHandle,\n getWrapperClass,\n resolveWrapperClass,\n getHandle,\n tryGetHandle,\n setHandle,\n getVfuncRegistry,\n getInterfaceVfuncRegistry,\n type StaticBase,\n type VfuncDescriptor,\n type VfuncRegistry,\n};\n"]}