@gtkx/runtime 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +1 -1
  2. package/dist/application-class.d.ts +5 -0
  3. package/dist/application-class.d.ts.map +1 -1
  4. package/dist/application-class.js +11 -1
  5. package/dist/application-class.js.map +1 -1
  6. package/dist/callback.d.ts +2 -2
  7. package/dist/callback.d.ts.map +1 -1
  8. package/dist/callback.js +51 -54
  9. package/dist/callback.js.map +1 -1
  10. package/dist/closure.js +1 -1
  11. package/dist/closure.js.map +1 -1
  12. package/dist/default-application.d.ts +4 -0
  13. package/dist/default-application.d.ts.map +1 -0
  14. package/dist/default-application.js +17 -0
  15. package/dist/default-application.js.map +1 -0
  16. package/dist/descriptors.d.ts +34 -9
  17. package/dist/descriptors.d.ts.map +1 -1
  18. package/dist/descriptors.js +42 -17
  19. package/dist/descriptors.js.map +1 -1
  20. package/dist/exit-hook.js +13 -0
  21. package/dist/exit-hook.js.map +1 -1
  22. package/dist/fn.d.ts +5 -0
  23. package/dist/fn.d.ts.map +1 -1
  24. package/dist/fn.js +11 -13
  25. package/dist/fn.js.map +1 -1
  26. package/dist/folded-lengths.d.ts +16 -0
  27. package/dist/folded-lengths.d.ts.map +1 -0
  28. package/dist/folded-lengths.js +38 -0
  29. package/dist/folded-lengths.js.map +1 -0
  30. package/dist/internal.d.ts +1 -0
  31. package/dist/internal.d.ts.map +1 -1
  32. package/dist/internal.js +1 -0
  33. package/dist/internal.js.map +1 -1
  34. package/dist/library.d.ts +2 -1
  35. package/dist/library.d.ts.map +1 -1
  36. package/dist/library.js +2 -1
  37. package/dist/library.js.map +1 -1
  38. package/dist/lifecycle.d.ts +16 -1
  39. package/dist/lifecycle.d.ts.map +1 -1
  40. package/dist/lifecycle.js +44 -14
  41. package/dist/lifecycle.js.map +1 -1
  42. package/dist/listeners.d.ts.map +1 -1
  43. package/dist/listeners.js +16 -4
  44. package/dist/listeners.js.map +1 -1
  45. package/dist/native-value.js +2 -2
  46. package/dist/native-value.js.map +1 -1
  47. package/dist/object.d.ts +7 -2
  48. package/dist/object.d.ts.map +1 -1
  49. package/dist/object.js +7 -2
  50. package/dist/object.js.map +1 -1
  51. package/dist/param-spec.d.ts.map +1 -1
  52. package/dist/param-spec.js +18 -20
  53. package/dist/param-spec.js.map +1 -1
  54. package/dist/properties.d.ts +2 -1
  55. package/dist/properties.d.ts.map +1 -1
  56. package/dist/properties.js +13 -9
  57. package/dist/properties.js.map +1 -1
  58. package/dist/register-class.d.ts +33 -3
  59. package/dist/register-class.d.ts.map +1 -1
  60. package/dist/register-class.js +21 -7
  61. package/dist/register-class.js.map +1 -1
  62. package/dist/registry.d.ts +14 -4
  63. package/dist/registry.d.ts.map +1 -1
  64. package/dist/registry.js +24 -15
  65. package/dist/registry.js.map +1 -1
  66. package/dist/signal.d.ts +2 -2
  67. package/dist/signal.d.ts.map +1 -1
  68. package/dist/signal.js +22 -18
  69. package/dist/signal.js.map +1 -1
  70. package/dist/t.d.ts +3 -1
  71. package/dist/t.d.ts.map +1 -1
  72. package/dist/t.js +1 -0
  73. package/dist/t.js.map +1 -1
  74. package/dist/tuple.d.ts +6 -3
  75. package/dist/tuple.d.ts.map +1 -1
  76. package/dist/tuple.js +9 -7
  77. package/dist/tuple.js.map +1 -1
  78. package/dist/value.d.ts +3 -1
  79. package/dist/value.d.ts.map +1 -1
  80. package/dist/value.js +64 -18
  81. package/dist/value.js.map +1 -1
  82. package/dist/vfunc-call.d.ts.map +1 -1
  83. package/dist/vfunc-call.js +5 -1
  84. package/dist/vfunc-call.js.map +1 -1
  85. package/dist/vfunc.d.ts.map +1 -1
  86. package/dist/vfunc.js +9 -3
  87. package/dist/vfunc.js.map +1 -1
  88. package/package.json +14 -4
  89. package/src/application-class.ts +12 -2
  90. package/src/callback.ts +70 -66
  91. package/src/closure.ts +1 -1
  92. package/src/default-application.ts +21 -0
  93. package/src/descriptors.ts +98 -29
  94. package/src/exit-hook.ts +18 -0
  95. package/src/fn.ts +23 -13
  96. package/src/folded-lengths.ts +64 -0
  97. package/src/internal.ts +1 -0
  98. package/src/library.ts +2 -1
  99. package/src/lifecycle.ts +60 -14
  100. package/src/listeners.ts +22 -5
  101. package/src/native-value.ts +2 -2
  102. package/src/object.ts +7 -2
  103. package/src/param-spec.ts +21 -22
  104. package/src/properties.ts +23 -9
  105. package/src/register-class.ts +66 -11
  106. package/src/registry.ts +43 -20
  107. package/src/signal.ts +32 -28
  108. package/src/t.ts +4 -1
  109. package/src/tuple.ts +18 -12
  110. package/src/value.ts +94 -19
  111. package/src/vfunc-call.ts +5 -1
  112. package/src/vfunc.ts +10 -3
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACnB,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC;IAC3B,kGAAkG;IAClG,WAAW,CAAC,IAAI,OAAO,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC;IACrC,8EAA8E;IAC9E,QAAQ,IAAI,IAAI,CAAC;IACjB;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC5B,iEAAiE;IACjE,UAAU,CAAC,IAAI,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,YAAY,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,+EAA+E;IAC/E,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAClE,kDAAkD;IAClD,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;CACrC,CAAC;AAEF,6EAA6E;AAC7E,KAAK,oBAAoB,GAAG;IACxB,mFAAmF;IACnF,SAAS,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC;AAKF;;;GAGG;AACH,QAAA,MAAM,IAAI,EAAE,MAAM,IAAmB,CAAC;AAoBtC;;;;;GAKG;AACH,QAAA,MAAM,MAAM,GAAI,UAAU,MAAM,IAAI,KAAG,IAEtC,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,QAAA,MAAM,cAAc,GAAI,aAAa,eAAe,EAAE,MAAM,MAAM,EAAE,KAAG,oBAoBtE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,QAAA,MAAM,eAAe,GAAI,aAAa,eAAe,KAAG,IAiBvD,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACnB,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC;IAC3B,kGAAkG;IAClG,WAAW,CAAC,IAAI,OAAO,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC;IACrC,8EAA8E;IAC9E,QAAQ,IAAI,IAAI,CAAC;IACjB;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC5B,iEAAiE;IACjE,UAAU,CAAC,IAAI,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,YAAY,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,+EAA+E;IAC/E,EAAE,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAClE,kDAAkD;IAClD,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;CACrC,CAAC;AAEF,KAAK,mBAAmB,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;AAE9E,6EAA6E;AAC7E,KAAK,oBAAoB,GAAG;IACxB,mFAAmF;IACnF,SAAS,EAAE,OAAO,CAAC;IACnB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC;AAMF;;;GAGG;AACH,QAAA,MAAM,IAAI,EAAE,MAAM,IAAmB,CAAC;AAoBtC;;;;;GAKG;AACH,QAAA,MAAM,MAAM,GAAI,UAAU,MAAM,IAAI,KAAG,IAEtC,CAAC;AA4BF,QAAA,MAAM,sBAAsB,GAAI,aAAa,eAAe,KAAG,mBAM9D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,cAAc,GAAI,aAAa,eAAe,EAAE,MAAM,MAAM,EAAE,KAAG,oBA4BtE,CAAC;AAqBF;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,eAAe,GAAI,aAAa,eAAe,KAAG,IAGvD,CAAC;AAEF,OAAO,EACH,sBAAsB,EACtB,MAAM,EACN,IAAI,EACJ,cAAc,EACd,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC5B,CAAC"}
package/dist/lifecycle.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { keepAlive, quit as nativeQuit } from "@gtkx/native";
2
2
  import { isDerivedApplication, shutDownThroughRun } from "./application-class.js";
3
+ import { claimDefaultApplication, releaseDefaultApplication } from "./default-application.js";
3
4
  const shutdownCallbacks = [];
4
5
  const startedApplications = new WeakSet();
6
+ const registeredApplications = new WeakSet();
5
7
  const shutDownApplications = new WeakSet();
6
8
  /**
7
9
  * Runs every registered exit callback and shuts down the native runtime. Safe to
@@ -48,6 +50,12 @@ const restartApplication = (application) => {
48
50
  application.activate();
49
51
  return 0;
50
52
  };
53
+ const getApplicationInstance = (application) => {
54
+ if (!application.getIsRegistered()) {
55
+ return registeredApplications.has(application) ? "shutDown" : "unregistered";
56
+ }
57
+ return application.getIsRemote?.() === true ? "remote" : "primary";
58
+ };
51
59
  /**
52
60
  * Hands `argv` to GLib's own command line handling, which parses the application's options, prints
53
61
  * `--help`, runs `handle-local-options`, registers the application, and either activates it or
@@ -66,6 +74,13 @@ const restartApplication = (application) => {
66
74
  * user interface may be built here, because a remote application has no `GtkApplicationImpl` and
67
75
  * attaching a window to it crashes.
68
76
  *
77
+ * The application also claims the process-wide default `Gio.Application.getDefault()` returns, before
78
+ * its command line is parsed, so an `activate` handler and anything the host reads afterwards see the
79
+ * application being started rather than an earlier one. That holds whether the start ends registered,
80
+ * remote or unregistered: a refused command line still has to be reportable through the default, which
81
+ * is how `gtkx dev` learns which application its entry mounted. {@link quitApplication} gives the
82
+ * default back up, since GLib drops it only at finalize.
83
+ *
69
84
  * @param application The application to start.
70
85
  * @param argv The command line, whose first entry names the program as `--help` should print it.
71
86
  * @returns Whether this process may build a user interface, and the status to exit with.
@@ -76,27 +91,21 @@ const runApplication = (application, argv) => {
76
91
  "parsed and it cannot be shut down safely; render <GtkApplication> or <AdwApplication>, " +
77
92
  "or construct it with createApplication from @gtkx/runtime");
78
93
  }
94
+ claimDefaultApplication(application);
79
95
  const exitStatus = startedApplications.has(application)
80
96
  ? restartApplication(application)
81
97
  : startApplication(application, argv);
82
- const isPrimary = application.getIsRegistered() && application.getIsRemote?.() !== true;
98
+ const instance = getApplicationInstance(application);
99
+ if (instance !== "unregistered") {
100
+ registeredApplications.add(application);
101
+ }
102
+ const isPrimary = instance === "primary";
83
103
  if (isPrimary) {
84
104
  keepAlive(true);
85
105
  }
86
106
  return { isPrimary, exitStatus };
87
107
  };
88
- /**
89
- * Detaches every window from the application and runs GLib's own shutdown, which emits `shutdown`,
90
- * destroys the application implementation and releases the D-Bus registration. Does nothing for an
91
- * application that is not registered, so a repeated call is a no-op.
92
- *
93
- * GLib's own shutdown is reachable once per application: reaching it marks the application as
94
- * quitting, which GLib never undoes. An application that has already quit falls back to emitting
95
- * `shutdown`, which releases the runtime and leaves the registration for GLib to drop at finalize.
96
- *
97
- * @param application The application to shut down.
98
- */
99
- const quitApplication = (application) => {
108
+ const tearDownApplication = (application) => {
100
109
  if (!application.getIsRegistered() || shutDownApplications.has(application)) {
101
110
  return;
102
111
  }
@@ -110,5 +119,26 @@ const quitApplication = (application) => {
110
119
  application.emit("shutdown");
111
120
  }
112
121
  };
113
- export { onExit, quit, runApplication, quitApplication };
122
+ /**
123
+ * Detaches every window from the application and runs GLib's own shutdown, which emits `shutdown`,
124
+ * destroys the application implementation and releases the D-Bus registration. Does nothing for an
125
+ * application that is not registered, so a repeated call is a no-op.
126
+ *
127
+ * GLib's own shutdown is reachable once per application: reaching it marks the application as
128
+ * quitting, which GLib never undoes. An application that has already quit falls back to emitting
129
+ * `shutdown`, which releases the runtime and leaves the registration for GLib to drop at finalize.
130
+ *
131
+ * The process-wide default {@link runApplication} claimed is given up whichever of those paths the
132
+ * application took, including the ones that have no teardown left to do, so
133
+ * `Gio.Application.getDefault()` never hands back an application that has been torn down or that
134
+ * never registered in the first place. GLib clears that default only at finalize, which a
135
+ * garbage-collected wrapper reaches arbitrarily late or never.
136
+ *
137
+ * @param application The application to shut down.
138
+ */
139
+ const quitApplication = (application) => {
140
+ tearDownApplication(application);
141
+ releaseDefaultApplication(application);
142
+ };
143
+ export { getApplicationInstance, onExit, quit, runApplication, quitApplication, };
114
144
  //# sourceMappingURL=lifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { keepAlive, quit as nativeQuit } from \"@gtkx/native\";\nimport { isDerivedApplication, type LocalCommandLineApplication, shutDownThroughRun } from \"./application-class.js\";\n\n/**\n * The GIO and GTK application surface {@link runApplication} and {@link quitApplication} drive, so any\n * application subclass satisfies it structurally; the window members only `Gtk.Application` defines are\n * optional.\n */\ntype ApplicationLike = {\n /** Returns whether the application has already been registered. */\n getIsRegistered(): boolean;\n /** Returns whether another process owns the application ID, making this one a remote instance. */\n getIsRemote?(): boolean;\n /** Registers the application with the session, returning whether it succeeded. */\n register(cancellable: null): boolean;\n /** Emits `activate`, bringing up the application's initial user interface. */\n activate(): void;\n /**\n * Runs GLib's own `g_application_run`, whose tail emits `shutdown`, destroys the application\n * implementation and clears the registration.\n */\n run(argv: string[]): number;\n /** Returns the windows currently attached to the application. */\n getWindows?(): object[];\n /** Detaches a window, so it no longer holds the application open. */\n removeWindow?(window: object): void;\n /** Connects a handler to the application's `activate` or `shutdown` signal. */\n on(signal: \"activate\" | \"shutdown\", handler: () => void): unknown;\n /** Emits one of the application's own signals. */\n emit(signal: \"shutdown\"): unknown;\n};\n\n/** What {@link runApplication} reports about the process it just started. */\ntype RunApplicationResult = {\n /** Whether this process owns the application ID and may build a user interface. */\n isPrimary: boolean;\n /** The status GLib determined for the command line, which the process should exit with. */\n exitStatus: number;\n};\n\nconst shutdownCallbacks: (() => void)[] = [];\nconst startedApplications: WeakSet<object> = new WeakSet();\nconst shutDownApplications: WeakSet<object> = new WeakSet();\n/**\n * Runs every registered exit callback and shuts down the native runtime. Safe to\n * call more than once; only the first call takes effect.\n */\nconst quit: () => void = createQuit();\n\nfunction createQuit(): () => void {\n let hasQuit = false;\n\n return () => {\n if (hasQuit) {\n return;\n }\n\n hasQuit = true;\n\n for (const callback of shutdownCallbacks) {\n callback();\n }\n\n nativeQuit();\n };\n}\n\n/**\n * Registers a callback to run once when the process quits, before the native\n * runtime is torn down.\n *\n * @param callback Invoked during shutdown.\n */\nconst onExit = (callback: () => void): void => {\n shutdownCallbacks.push(callback);\n};\n\nconst startApplication = (application: ApplicationLike & LocalCommandLineApplication, argv: string[]): number => {\n startedApplications.add(application);\n\n application.on(\"activate\", () => {\n keepAlive(true);\n });\n\n application.on(\"shutdown\", () => {\n keepAlive(false);\n });\n\n return application.runLocalCommandLine(argv)[2];\n};\n\nconst restartApplication = (application: ApplicationLike): number => {\n shutDownApplications.delete(application);\n\n if (!application.register(null)) {\n return 1;\n }\n\n application.activate();\n\n return 0;\n};\n\n/**\n * Hands `argv` to GLib's own command line handling, which parses the application's options, prints\n * `--help`, runs `handle-local-options`, registers the application, and either activates it or\n * forwards the command line to the process that already owns the application ID. The runtime is\n * held alive while the application is active and released on shutdown.\n *\n * `g_application_run()` is not what starts the application, because it would drive its own main loop\n * and freeze Node; only the local command line handling it delegates to runs here. {@link\n * quitApplication} calls it once no window holds the application open, to reach the teardown only it\n * performs.\n *\n * GLib parses a given application's command line at most once, so starting an application that has\n * already run registers and activates it instead of reading `argv` again.\n *\n * When another process already owns the application ID, this one registers as a remote instance: no\n * user interface may be built here, because a remote application has no `GtkApplicationImpl` and\n * attaching a window to it crashes.\n *\n * @param application The application to start.\n * @param argv The command line, whose first entry names the program as `--help` should print it.\n * @returns Whether this process may build a user interface, and the status to exit with.\n */\nconst runApplication = (application: ApplicationLike, argv: string[]): RunApplicationResult => {\n if (!isDerivedApplication(application)) {\n throw new Error(\n \"runApplication: this application was not built by GTKX, so its command line cannot be \" +\n \"parsed and it cannot be shut down safely; render <GtkApplication> or <AdwApplication>, \" +\n \"or construct it with createApplication from @gtkx/runtime\",\n );\n }\n\n const exitStatus = startedApplications.has(application)\n ? restartApplication(application)\n : startApplication(application, argv);\n\n const isPrimary = application.getIsRegistered() && application.getIsRemote?.() !== true;\n\n if (isPrimary) {\n keepAlive(true);\n }\n\n return { isPrimary, exitStatus };\n};\n\n/**\n * Detaches every window from the application and runs GLib's own shutdown, which emits `shutdown`,\n * destroys the application implementation and releases the D-Bus registration. Does nothing for an\n * application that is not registered, so a repeated call is a no-op.\n *\n * GLib's own shutdown is reachable once per application: reaching it marks the application as\n * quitting, which GLib never undoes. An application that has already quit falls back to emitting\n * `shutdown`, which releases the runtime and leaves the registration for GLib to drop at finalize.\n *\n * @param application The application to shut down.\n */\nconst quitApplication = (application: ApplicationLike): void => {\n if (!application.getIsRegistered() || shutDownApplications.has(application)) {\n return;\n }\n\n const windows = application.getWindows?.() ?? [];\n\n for (const window of windows) {\n application.removeWindow?.(window);\n }\n\n shutDownThroughRun(application);\n\n if (application.getIsRegistered()) {\n shutDownApplications.add(application);\n application.emit(\"shutdown\");\n }\n};\n\nexport { onExit, quit, runApplication, quitApplication, type ApplicationLike, type RunApplicationResult };\n"]}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { keepAlive, quit as nativeQuit } from \"@gtkx/native\";\nimport { isDerivedApplication, type LocalCommandLineApplication, shutDownThroughRun } from \"./application-class.js\";\nimport { claimDefaultApplication, releaseDefaultApplication } from \"./default-application.js\";\n\n/**\n * The GIO and GTK application surface {@link runApplication} and {@link quitApplication} drive, so any\n * application subclass satisfies it structurally; the window members only `Gtk.Application` defines are\n * optional.\n */\ntype ApplicationLike = {\n /** Returns whether the application has already been registered. */\n getIsRegistered(): boolean;\n /** Returns whether another process owns the application ID, making this one a remote instance. */\n getIsRemote?(): boolean;\n /** Registers the application with the session, returning whether it succeeded. */\n register(cancellable: null): boolean;\n /** Emits `activate`, bringing up the application's initial user interface. */\n activate(): void;\n /**\n * Runs GLib's own `g_application_run`, whose tail emits `shutdown`, destroys the application\n * implementation and clears the registration.\n */\n run(argv: string[]): number;\n /** Returns the windows currently attached to the application. */\n getWindows?(): object[];\n /** Detaches a window, so it no longer holds the application open. */\n removeWindow?(window: object): void;\n /** Connects a handler to the application's `activate` or `shutdown` signal. */\n on(signal: \"activate\" | \"shutdown\", handler: () => void): unknown;\n /** Emits one of the application's own signals. */\n emit(signal: \"shutdown\"): unknown;\n};\n\ntype ApplicationInstance = \"primary\" | \"remote\" | \"shutDown\" | \"unregistered\";\n\n/** What {@link runApplication} reports about the process it just started. */\ntype RunApplicationResult = {\n /** Whether this process owns the application ID and may build a user interface. */\n isPrimary: boolean;\n /** The status GLib determined for the command line, which the process should exit with. */\n exitStatus: number;\n};\n\nconst shutdownCallbacks: (() => void)[] = [];\nconst startedApplications: WeakSet<object> = new WeakSet();\nconst registeredApplications: WeakSet<object> = new WeakSet();\nconst shutDownApplications: WeakSet<object> = new WeakSet();\n/**\n * Runs every registered exit callback and shuts down the native runtime. Safe to\n * call more than once; only the first call takes effect.\n */\nconst quit: () => void = createQuit();\n\nfunction createQuit(): () => void {\n let hasQuit = false;\n\n return () => {\n if (hasQuit) {\n return;\n }\n\n hasQuit = true;\n\n for (const callback of shutdownCallbacks) {\n callback();\n }\n\n nativeQuit();\n };\n}\n\n/**\n * Registers a callback to run once when the process quits, before the native\n * runtime is torn down.\n *\n * @param callback Invoked during shutdown.\n */\nconst onExit = (callback: () => void): void => {\n shutdownCallbacks.push(callback);\n};\n\nconst startApplication = (application: ApplicationLike & LocalCommandLineApplication, argv: string[]): number => {\n startedApplications.add(application);\n\n application.on(\"activate\", () => {\n keepAlive(true);\n });\n\n application.on(\"shutdown\", () => {\n keepAlive(false);\n });\n\n return application.runLocalCommandLine(argv)[2];\n};\n\nconst restartApplication = (application: ApplicationLike): number => {\n shutDownApplications.delete(application);\n\n if (!application.register(null)) {\n return 1;\n }\n\n application.activate();\n\n return 0;\n};\n\nconst getApplicationInstance = (application: ApplicationLike): ApplicationInstance => {\n if (!application.getIsRegistered()) {\n return registeredApplications.has(application) ? \"shutDown\" : \"unregistered\";\n }\n\n return application.getIsRemote?.() === true ? \"remote\" : \"primary\";\n};\n\n/**\n * Hands `argv` to GLib's own command line handling, which parses the application's options, prints\n * `--help`, runs `handle-local-options`, registers the application, and either activates it or\n * forwards the command line to the process that already owns the application ID. The runtime is\n * held alive while the application is active and released on shutdown.\n *\n * `g_application_run()` is not what starts the application, because it would drive its own main loop\n * and freeze Node; only the local command line handling it delegates to runs here. {@link\n * quitApplication} calls it once no window holds the application open, to reach the teardown only it\n * performs.\n *\n * GLib parses a given application's command line at most once, so starting an application that has\n * already run registers and activates it instead of reading `argv` again.\n *\n * When another process already owns the application ID, this one registers as a remote instance: no\n * user interface may be built here, because a remote application has no `GtkApplicationImpl` and\n * attaching a window to it crashes.\n *\n * The application also claims the process-wide default `Gio.Application.getDefault()` returns, before\n * its command line is parsed, so an `activate` handler and anything the host reads afterwards see the\n * application being started rather than an earlier one. That holds whether the start ends registered,\n * remote or unregistered: a refused command line still has to be reportable through the default, which\n * is how `gtkx dev` learns which application its entry mounted. {@link quitApplication} gives the\n * default back up, since GLib drops it only at finalize.\n *\n * @param application The application to start.\n * @param argv The command line, whose first entry names the program as `--help` should print it.\n * @returns Whether this process may build a user interface, and the status to exit with.\n */\nconst runApplication = (application: ApplicationLike, argv: string[]): RunApplicationResult => {\n if (!isDerivedApplication(application)) {\n throw new Error(\n \"runApplication: this application was not built by GTKX, so its command line cannot be \" +\n \"parsed and it cannot be shut down safely; render <GtkApplication> or <AdwApplication>, \" +\n \"or construct it with createApplication from @gtkx/runtime\",\n );\n }\n\n claimDefaultApplication(application);\n\n const exitStatus = startedApplications.has(application)\n ? restartApplication(application)\n : startApplication(application, argv);\n\n const instance = getApplicationInstance(application);\n\n if (instance !== \"unregistered\") {\n registeredApplications.add(application);\n }\n\n const isPrimary = instance === \"primary\";\n\n if (isPrimary) {\n keepAlive(true);\n }\n\n return { isPrimary, exitStatus };\n};\n\nconst tearDownApplication = (application: ApplicationLike): void => {\n if (!application.getIsRegistered() || shutDownApplications.has(application)) {\n return;\n }\n\n const windows = application.getWindows?.() ?? [];\n\n for (const window of windows) {\n application.removeWindow?.(window);\n }\n\n shutDownThroughRun(application);\n\n if (application.getIsRegistered()) {\n shutDownApplications.add(application);\n application.emit(\"shutdown\");\n }\n};\n\n/**\n * Detaches every window from the application and runs GLib's own shutdown, which emits `shutdown`,\n * destroys the application implementation and releases the D-Bus registration. Does nothing for an\n * application that is not registered, so a repeated call is a no-op.\n *\n * GLib's own shutdown is reachable once per application: reaching it marks the application as\n * quitting, which GLib never undoes. An application that has already quit falls back to emitting\n * `shutdown`, which releases the runtime and leaves the registration for GLib to drop at finalize.\n *\n * The process-wide default {@link runApplication} claimed is given up whichever of those paths the\n * application took, including the ones that have no teardown left to do, so\n * `Gio.Application.getDefault()` never hands back an application that has been torn down or that\n * never registered in the first place. GLib clears that default only at finalize, which a\n * garbage-collected wrapper reaches arbitrarily late or never.\n *\n * @param application The application to shut down.\n */\nconst quitApplication = (application: ApplicationLike): void => {\n tearDownApplication(application);\n releaseDefaultApplication(application);\n};\n\nexport {\n getApplicationInstance,\n onExit,\n quit,\n runApplication,\n quitApplication,\n type ApplicationInstance,\n type RunApplicationResult,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"listeners.d.ts","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAE9F;;;GAGG;AACH,KAAK,iBAAiB,GAAG;IACrB,iEAAiE;IACjE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3E,uEAAuE;IACvE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC,CAAC;AA4CF;;;;;;;;GAQG;AACH,iBAAS,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAG9G;AAED;;;;;;;;GAQG;AACH,iBAAS,UAAU,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAchH;AAED;;;;;;;GAOG;AACH,iBAAS,SAAS,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAe5F;AAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"listeners.d.ts","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAE9F;;;GAGG;AACH,KAAK,iBAAiB,GAAG;IACrB,iEAAiE;IACjE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3E,uEAAuE;IACvE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC,CAAC;AA6DF;;;;;;;;GAQG;AACH,iBAAS,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAG9G;AAED;;;;;;;;GAQG;AACH,iBAAS,UAAU,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAchH;AAED;;;;;;;GAOG;AACH,iBAAS,SAAS,CAAC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAe5F;AAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
package/dist/listeners.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isSignalHandlerConnected, untrackConnection } from "./signal.js";
2
2
  const listenerTable = new WeakMap();
3
- const findListenerHandlerId = (instance, signal, handler) => listenerTable.get(instance)?.get(signal)?.get(handler);
3
+ const findListenerHandlerId = (instance, signal, handler) => listenerTable.get(instance)?.get(signal)?.get(handler)?.at(-1);
4
4
  const trackListener = (instance, signal, handler, handlerId) => {
5
5
  let bySignal = listenerTable.get(instance);
6
6
  if (!bySignal) {
@@ -12,7 +12,19 @@ const trackListener = (instance, signal, handler, handlerId) => {
12
12
  byHandler = new Map();
13
13
  bySignal.set(signal, byHandler);
14
14
  }
15
- byHandler.set(handler, handlerId);
15
+ let handlerIds = byHandler.get(handler);
16
+ if (!handlerIds) {
17
+ handlerIds = [];
18
+ byHandler.set(handler, handlerIds);
19
+ }
20
+ handlerIds.push(handlerId);
21
+ };
22
+ const removeTrackedHandlerId = (handlerIds, handlerId) => {
23
+ const index = handlerIds.lastIndexOf(handlerId);
24
+ if (index !== -1) {
25
+ handlerIds.splice(index, 1);
26
+ }
27
+ return handlerIds.length;
16
28
  };
17
29
  const untrackHandlerId = (instance, signal, handlerId) => {
18
30
  const bySignal = listenerTable.get(instance);
@@ -20,8 +32,8 @@ const untrackHandlerId = (instance, signal, handlerId) => {
20
32
  if (byHandler === undefined) {
21
33
  return;
22
34
  }
23
- for (const [handler, id] of byHandler) {
24
- if (id === handlerId) {
35
+ for (const [handler, handlerIds] of byHandler) {
36
+ if (removeTrackedHandlerId(handlerIds, handlerId) === 0) {
25
37
  byHandler.delete(handler);
26
38
  }
27
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"listeners.js","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"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","sourcesContent":["import { isSignalHandlerConnected, type SignalHandler, untrackConnection } from \"./signal.js\";\n\n/**\n * The connect and disconnect surface {@link onSignal}, {@link onceSignal} and {@link offSignal}\n * drive on an emitter.\n */\ntype SignalConnectable = {\n /** Connects a handler to a signal and returns its handler id. */\n connect(signal: string, handler: SignalHandler, isAfter?: boolean): number;\n /** Disconnects the handler previously connected under the given id. */\n disconnect(handlerId: number): void;\n};\n\nconst listenerTable: WeakMap<object, Map<string, Map<SignalHandler, number>>> = new WeakMap();\n\nconst findListenerHandlerId = (instance: object, signal: string, handler: SignalHandler): number | undefined =>\n listenerTable.get(instance)?.get(signal)?.get(handler);\n\nconst trackListener = (instance: object, signal: string, handler: SignalHandler, handlerId: number): void => {\n let bySignal = listenerTable.get(instance);\n\n if (!bySignal) {\n bySignal = new Map();\n listenerTable.set(instance, bySignal);\n }\n\n let byHandler = bySignal.get(signal);\n\n if (!byHandler) {\n byHandler = new Map();\n bySignal.set(signal, byHandler);\n }\n\n byHandler.set(handler, handlerId);\n};\n\nconst untrackHandlerId = (instance: object, signal: string, handlerId: number): void => {\n const bySignal = listenerTable.get(instance);\n const byHandler = bySignal?.get(signal);\n\n if (byHandler === undefined) {\n return;\n }\n\n for (const [handler, id] of byHandler) {\n if (id === handlerId) {\n byHandler.delete(handler);\n }\n }\n\n if (byHandler.size === 0) {\n bySignal?.delete(signal);\n }\n};\n\n/**\n * Connects a handler to a signal and tracks it so it can later be removed with\n * {@link offSignal}.\n *\n * @param instance The object emitting the signal.\n * @param signal The signal name to connect to.\n * @param handler The callback invoked on each emission.\n * @param isAfter When true, run the handler after the default handler.\n */\nfunction onSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n const handlerId = instance.connect(signal, handler, isAfter);\n trackListener(instance, signal, handler, handlerId);\n}\n\n/**\n * Connects a handler that runs at most once, disconnecting itself after the first\n * emission.\n *\n * @param instance The object emitting the signal.\n * @param signal The signal name to connect to.\n * @param handler The callback invoked on the first emission.\n * @param isAfter When true, run the handler after the default handler.\n */\nfunction onceSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n let handlerId = 0;\n\n const wrapped: SignalHandler = (...args) => {\n untrackHandlerId(instance, signal, handlerId);\n untrackConnection(instance, handlerId);\n instance.disconnect(handlerId);\n\n return handler(...args);\n };\n\n handlerId = instance.connect(signal, wrapped, isAfter);\n trackListener(instance, signal, wrapped, handlerId);\n trackListener(instance, signal, handler, handlerId);\n}\n\n/**\n * Disconnects a handler previously connected with {@link onSignal} or\n * {@link onceSignal}. Does nothing if the handler is not currently connected.\n *\n * @param instance The object the handler was connected to.\n * @param signal The signal name the handler was connected to.\n * @param handler The handler to disconnect.\n */\nfunction offSignal(instance: SignalConnectable, signal: string, handler: SignalHandler): void {\n const handlerId = findListenerHandlerId(instance, signal, handler);\n\n if (handlerId === undefined) {\n return;\n }\n\n untrackHandlerId(instance, signal, handlerId);\n untrackConnection(instance, handlerId);\n\n if (!isSignalHandlerConnected(instance, handlerId)) {\n return;\n }\n\n instance.disconnect(handlerId);\n}\n\nexport { onSignal, onceSignal, offSignal };\n"]}
1
+ {"version":3,"file":"listeners.js","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"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","sourcesContent":["import { isSignalHandlerConnected, type SignalHandler, untrackConnection } from \"./signal.js\";\n\n/**\n * The connect and disconnect surface {@link onSignal}, {@link onceSignal} and {@link offSignal}\n * drive on an emitter.\n */\ntype SignalConnectable = {\n /** Connects a handler to a signal and returns its handler id. */\n connect(signal: string, handler: SignalHandler, isAfter?: boolean): number;\n /** Disconnects the handler previously connected under the given id. */\n disconnect(handlerId: number): void;\n};\n\nconst listenerTable: WeakMap<object, Map<string, Map<SignalHandler, number[]>>> = new WeakMap();\n\nconst findListenerHandlerId = (instance: object, signal: string, handler: SignalHandler): number | undefined =>\n listenerTable.get(instance)?.get(signal)?.get(handler)?.at(-1);\n\nconst trackListener = (instance: object, signal: string, handler: SignalHandler, handlerId: number): void => {\n let bySignal = listenerTable.get(instance);\n\n if (!bySignal) {\n bySignal = new Map();\n listenerTable.set(instance, bySignal);\n }\n\n let byHandler = bySignal.get(signal);\n\n if (!byHandler) {\n byHandler = new Map();\n bySignal.set(signal, byHandler);\n }\n\n let handlerIds = byHandler.get(handler);\n\n if (!handlerIds) {\n handlerIds = [];\n byHandler.set(handler, handlerIds);\n }\n\n handlerIds.push(handlerId);\n};\n\nconst removeTrackedHandlerId = (handlerIds: number[], handlerId: number): number => {\n const index = handlerIds.lastIndexOf(handlerId);\n\n if (index !== -1) {\n handlerIds.splice(index, 1);\n }\n\n return handlerIds.length;\n};\n\nconst untrackHandlerId = (instance: object, signal: string, handlerId: number): void => {\n const bySignal = listenerTable.get(instance);\n const byHandler = bySignal?.get(signal);\n\n if (byHandler === undefined) {\n return;\n }\n\n for (const [handler, handlerIds] of byHandler) {\n if (removeTrackedHandlerId(handlerIds, handlerId) === 0) {\n byHandler.delete(handler);\n }\n }\n\n if (byHandler.size === 0) {\n bySignal?.delete(signal);\n }\n};\n\n/**\n * Connects a handler to a signal and tracks it so it can later be removed with\n * {@link offSignal}.\n *\n * @param instance The object emitting the signal.\n * @param signal The signal name to connect to.\n * @param handler The callback invoked on each emission.\n * @param isAfter When true, run the handler after the default handler.\n */\nfunction onSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n const handlerId = instance.connect(signal, handler, isAfter);\n trackListener(instance, signal, handler, handlerId);\n}\n\n/**\n * Connects a handler that runs at most once, disconnecting itself after the first\n * emission.\n *\n * @param instance The object emitting the signal.\n * @param signal The signal name to connect to.\n * @param handler The callback invoked on the first emission.\n * @param isAfter When true, run the handler after the default handler.\n */\nfunction onceSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n let handlerId = 0;\n\n const wrapped: SignalHandler = (...args) => {\n untrackHandlerId(instance, signal, handlerId);\n untrackConnection(instance, handlerId);\n instance.disconnect(handlerId);\n\n return handler(...args);\n };\n\n handlerId = instance.connect(signal, wrapped, isAfter);\n trackListener(instance, signal, wrapped, handlerId);\n trackListener(instance, signal, handler, handlerId);\n}\n\n/**\n * Disconnects a handler previously connected with {@link onSignal} or\n * {@link onceSignal}. Does nothing if the handler is not currently connected.\n *\n * @param instance The object the handler was connected to.\n * @param signal The signal name the handler was connected to.\n * @param handler The handler to disconnect.\n */\nfunction offSignal(instance: SignalConnectable, signal: string, handler: SignalHandler): void {\n const handlerId = findListenerHandlerId(instance, signal, handler);\n\n if (handlerId === undefined) {\n return;\n }\n\n untrackHandlerId(instance, signal, handlerId);\n untrackConnection(instance, handlerId);\n\n if (!isSignalHandlerConnected(instance, handlerId)) {\n return;\n }\n\n instance.disconnect(handlerId);\n}\n\nexport { onSignal, onceSignal, offSignal };\n"]}
@@ -1,4 +1,4 @@
1
- import { getHandle, getWrapperClass, wrapHandle, wrapObject } from "./registry.js";
1
+ import { getHandle, getWrapperClass, wrapCallScopedObject, wrapHandle, wrapObject } from "./registry.js";
2
2
  import { resolveDescriptorType } from "./type.js";
3
3
  const MARSHALLED_KINDS = new Set([
4
4
  "object",
@@ -51,7 +51,7 @@ function fromNative(descriptor, value) {
51
51
  }
52
52
  switch (descriptor.kind) {
53
53
  case "object": {
54
- return wrapObject(value);
54
+ return descriptor.isCallScoped === true ? wrapCallScopedObject(value) : wrapObject(value);
55
55
  }
56
56
  case "struct": {
57
57
  return wrapHandle(value, descriptor.wrapperClass);
@@ -1 +1 @@
1
- {"version":3,"file":"native-value.js","sourceRoot":"","sources":["../src/native-value.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Descriptor, ExternalObject, Handle } from \"@gtkx/native\";\nimport type { ArrayDescriptor, FundamentalDescriptor, HashTableDescriptor, StructDescriptor } from \"./descriptors.js\";\nimport { getHandle, getWrapperClass, wrapHandle, wrapObject } from \"./registry.js\";\nimport { resolveDescriptorType } from \"./type.js\";\n\ntype MarshalledKind = \"object\" | \"struct\" | \"boxed\" | \"fundamental\" | \"array\" | \"hashtable\";\ntype MarshalledDescriptor = Extract<Descriptor, { kind: MarshalledKind }>;\n\nconst MARSHALLED_KINDS: Set<Descriptor[\"kind\"]> = new Set<MarshalledKind>([\n \"object\",\n \"struct\",\n \"boxed\",\n \"fundamental\",\n \"array\",\n \"hashtable\",\n]);\n\nfunction isMarshalledDescriptor(descriptor: Descriptor): descriptor is MarshalledDescriptor {\n return MARSHALLED_KINDS.has(descriptor.kind);\n}\n\nfunction mapCollection(\n descriptor: ArrayDescriptor,\n value: unknown,\n convert: (itemDescriptor: Descriptor, item: unknown) => unknown,\n): unknown[] {\n return (value as unknown[]).map((item) => convert(descriptor.itemDescriptor, item));\n}\n\nfunction collectionFromNative(descriptor: ArrayDescriptor, value: unknown): unknown {\n return value === null ? null : mapCollection(descriptor, value, fromNative);\n}\n\nfunction boxedFromNative(descriptor: Descriptor, value: unknown): unknown {\n return value == null\n ? null\n : wrapHandle(value as ExternalObject<Handle>, getWrapperClass(resolveDescriptorType(descriptor)));\n}\n\nfunction fundamentalFromNative(descriptor: FundamentalDescriptor, value: unknown): unknown {\n return value == null\n ? null\n : wrapHandle(\n value as ExternalObject<Handle>,\n descriptor.wrapperClass ?? getWrapperClass(resolveDescriptorType(descriptor)),\n );\n}\n\nfunction hashTableFromNative(descriptor: HashTableDescriptor, value: unknown): unknown {\n if (value === null) {\n return null;\n }\n\n const entries = value as [unknown, unknown][];\n\n return new Map(\n entries.map(([key, val]): [unknown, unknown] => [\n fromNative(descriptor.keyDescriptor, key),\n fromNative(descriptor.valueDescriptor, val),\n ]),\n );\n}\n\n/**\n * Converts a raw value returned from native code into its JavaScript form,\n * wrapping object, struct, boxed, and fundamental handles and recursively\n * converting arrays and hash tables according to the descriptor.\n *\n * @param descriptor Describes the native type of the value.\n * @param value The raw native value to convert.\n */\nfunction fromNative(descriptor: Descriptor, value: unknown): unknown {\n if (!isMarshalledDescriptor(descriptor)) {\n return value;\n }\n\n switch (descriptor.kind) {\n case \"object\": {\n return wrapObject(value);\n }\n case \"struct\": {\n return wrapHandle(value as ExternalObject<Handle> | null, (descriptor as StructDescriptor).wrapperClass);\n }\n case \"boxed\": {\n return boxedFromNative(descriptor, value);\n }\n case \"fundamental\": {\n return fundamentalFromNative(descriptor, value);\n }\n case \"array\": {\n return collectionFromNative(descriptor, value);\n }\n case \"hashtable\": {\n return hashTableFromNative(descriptor, value);\n }\n }\n}\n\nfunction collectionToNative(descriptor: ArrayDescriptor, value: unknown): unknown {\n return value == null ? null : mapCollection(descriptor, value, toNative);\n}\n\nfunction hashTableToNative(descriptor: HashTableDescriptor, value: unknown): unknown {\n if (value == null) {\n return null;\n }\n\n return [...(value as Map<unknown, unknown>)].map(([key, val]): [unknown, unknown] => [\n toNative(descriptor.keyDescriptor, key),\n toNative(descriptor.valueDescriptor, val),\n ]);\n}\n\n/**\n * Converts a JavaScript value into the raw form native code expects, unwrapping\n * object, struct, boxed, and fundamental wrappers back to their handles and\n * recursively converting arrays and maps according to the descriptor.\n *\n * @param descriptor Describes the native type to convert to.\n * @param value The JavaScript value to convert.\n */\nfunction toNative(descriptor: Descriptor, value: unknown): unknown {\n if (!isMarshalledDescriptor(descriptor)) {\n return value;\n }\n\n switch (descriptor.kind) {\n case \"object\":\n case \"struct\":\n case \"boxed\":\n case \"fundamental\": {\n const instance = value as object | null | undefined;\n\n return instance == null ? null : getHandle(instance);\n }\n case \"array\": {\n return collectionToNative(descriptor, value);\n }\n case \"hashtable\": {\n return hashTableToNative(descriptor, value);\n }\n }\n}\n\nexport { fromNative, toNative };\n"]}
1
+ {"version":3,"file":"native-value.js","sourceRoot":"","sources":["../src/native-value.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAKlD,MAAM,gBAAgB,GAA4B,IAAI,GAAG,CAAiB;IACtE,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,aAAa;IACb,OAAO;IACP,WAAW;CACd,CAAC,CAAC;AAEH,SAAS,sBAAsB,CAAC,UAAsB;IAClD,OAAO,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,aAAa,CAClB,UAA2B,EAC3B,KAAc,EACd,OAA+D;IAE/D,OAAQ,KAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,oBAAoB,CAAC,UAA2B,EAAE,KAAc;IACrE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,eAAe,CAAC,UAAsB,EAAE,KAAc;IAC3D,OAAO,KAAK,IAAI,IAAI;QAChB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,UAAU,CAAC,KAA+B,EAAE,eAAe,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1G,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAiC,EAAE,KAAc;IAC5E,OAAO,KAAK,IAAI,IAAI;QAChB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,UAAU,CACJ,KAA+B,EAC/B,UAAU,CAAC,YAAY,IAAI,eAAe,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAChF,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,UAA+B,EAAE,KAAc;IACxE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,OAAO,GAAG,KAA6B,CAAC;IAE9C,OAAO,IAAI,GAAG,CACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAsB,EAAE,CAAC;QAC5C,UAAU,CAAC,UAAU,CAAC,aAAa,EAAE,GAAG,CAAC;QACzC,UAAU,CAAC,UAAU,CAAC,eAAe,EAAE,GAAG,CAAC;KAC9C,CAAC,CACL,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,UAAsB,EAAE,KAAc;IACtD,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACZ,OAAO,UAAU,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9F,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACZ,OAAO,UAAU,CAAC,KAAsC,EAAG,UAA+B,CAAC,YAAY,CAAC,CAAC;QAC7G,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACX,OAAO,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACjB,OAAO,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACX,OAAO,oBAAoB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACf,OAAO,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAClD,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,UAA2B,EAAE,KAAc;IACnE,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,iBAAiB,CAAC,UAA+B,EAAE,KAAc;IACtE,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAI,KAA+B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAsB,EAAE,CAAC;QACjF,QAAQ,CAAC,UAAU,CAAC,aAAa,EAAE,GAAG,CAAC;QACvC,QAAQ,CAAC,UAAU,CAAC,eAAe,EAAE,GAAG,CAAC;KAC5C,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,QAAQ,CAAC,UAAsB,EAAE,KAAc;IACpD,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,aAAa,CAAC,CAAC,CAAC;YACjB,MAAM,QAAQ,GAAG,KAAkC,CAAC;YAEpD,OAAO,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACX,OAAO,kBAAkB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACf,OAAO,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACL,CAAC;AACL,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC","sourcesContent":["import type { Descriptor, ExternalObject, Handle } from \"@gtkx/native\";\nimport type { ArrayDescriptor, FundamentalDescriptor, HashTableDescriptor, StructDescriptor } from \"./descriptors.js\";\nimport { getHandle, getWrapperClass, wrapCallScopedObject, wrapHandle, wrapObject } from \"./registry.js\";\nimport { resolveDescriptorType } from \"./type.js\";\n\ntype MarshalledKind = \"object\" | \"struct\" | \"boxed\" | \"fundamental\" | \"array\" | \"hashtable\";\ntype MarshalledDescriptor = Extract<Descriptor, { kind: MarshalledKind }>;\n\nconst MARSHALLED_KINDS: Set<Descriptor[\"kind\"]> = new Set<MarshalledKind>([\n \"object\",\n \"struct\",\n \"boxed\",\n \"fundamental\",\n \"array\",\n \"hashtable\",\n]);\n\nfunction isMarshalledDescriptor(descriptor: Descriptor): descriptor is MarshalledDescriptor {\n return MARSHALLED_KINDS.has(descriptor.kind);\n}\n\nfunction mapCollection(\n descriptor: ArrayDescriptor,\n value: unknown,\n convert: (itemDescriptor: Descriptor, item: unknown) => unknown,\n): unknown[] {\n return (value as unknown[]).map((item) => convert(descriptor.itemDescriptor, item));\n}\n\nfunction collectionFromNative(descriptor: ArrayDescriptor, value: unknown): unknown {\n return value === null ? null : mapCollection(descriptor, value, fromNative);\n}\n\nfunction boxedFromNative(descriptor: Descriptor, value: unknown): unknown {\n return value == null\n ? null\n : wrapHandle(value as ExternalObject<Handle>, getWrapperClass(resolveDescriptorType(descriptor)));\n}\n\nfunction fundamentalFromNative(descriptor: FundamentalDescriptor, value: unknown): unknown {\n return value == null\n ? null\n : wrapHandle(\n value as ExternalObject<Handle>,\n descriptor.wrapperClass ?? getWrapperClass(resolveDescriptorType(descriptor)),\n );\n}\n\nfunction hashTableFromNative(descriptor: HashTableDescriptor, value: unknown): unknown {\n if (value === null) {\n return null;\n }\n\n const entries = value as [unknown, unknown][];\n\n return new Map(\n entries.map(([key, val]): [unknown, unknown] => [\n fromNative(descriptor.keyDescriptor, key),\n fromNative(descriptor.valueDescriptor, val),\n ]),\n );\n}\n\n/**\n * Converts a raw value returned from native code into its JavaScript form,\n * wrapping object, struct, boxed, and fundamental handles and recursively\n * converting arrays and hash tables according to the descriptor.\n *\n * @param descriptor Describes the native type of the value.\n * @param value The raw native value to convert.\n */\nfunction fromNative(descriptor: Descriptor, value: unknown): unknown {\n if (!isMarshalledDescriptor(descriptor)) {\n return value;\n }\n\n switch (descriptor.kind) {\n case \"object\": {\n return descriptor.isCallScoped === true ? wrapCallScopedObject(value) : wrapObject(value);\n }\n case \"struct\": {\n return wrapHandle(value as ExternalObject<Handle> | null, (descriptor as StructDescriptor).wrapperClass);\n }\n case \"boxed\": {\n return boxedFromNative(descriptor, value);\n }\n case \"fundamental\": {\n return fundamentalFromNative(descriptor, value);\n }\n case \"array\": {\n return collectionFromNative(descriptor, value);\n }\n case \"hashtable\": {\n return hashTableFromNative(descriptor, value);\n }\n }\n}\n\nfunction collectionToNative(descriptor: ArrayDescriptor, value: unknown): unknown {\n return value == null ? null : mapCollection(descriptor, value, toNative);\n}\n\nfunction hashTableToNative(descriptor: HashTableDescriptor, value: unknown): unknown {\n if (value == null) {\n return null;\n }\n\n return [...(value as Map<unknown, unknown>)].map(([key, val]): [unknown, unknown] => [\n toNative(descriptor.keyDescriptor, key),\n toNative(descriptor.valueDescriptor, val),\n ]);\n}\n\n/**\n * Converts a JavaScript value into the raw form native code expects, unwrapping\n * object, struct, boxed, and fundamental wrappers back to their handles and\n * recursively converting arrays and maps according to the descriptor.\n *\n * @param descriptor Describes the native type to convert to.\n * @param value The JavaScript value to convert.\n */\nfunction toNative(descriptor: Descriptor, value: unknown): unknown {\n if (!isMarshalledDescriptor(descriptor)) {\n return value;\n }\n\n switch (descriptor.kind) {\n case \"object\":\n case \"struct\":\n case \"boxed\":\n case \"fundamental\": {\n const instance = value as object | null | undefined;\n\n return instance == null ? null : getHandle(instance);\n }\n case \"array\": {\n return collectionToNative(descriptor, value);\n }\n case \"hashtable\": {\n return hashTableToNative(descriptor, value);\n }\n }\n}\n\nexport { fromNative, toNative };\n"]}
package/dist/object.d.ts CHANGED
@@ -26,7 +26,9 @@ declare function registerConstructProperties(cls: AnyClass, bindings: ConstructB
26
26
  * that name, dashed or camelCased, and is skipped when the type installs none.
27
27
  * A value that ParamSpec would refuse throws before GObject sees it: a `TypeError`
28
28
  * for a read-only property and for a value of a type the property cannot hold, and
29
- * a `RangeError` for a value the ParamSpec rejects.
29
+ * a `RangeError` for a value the ParamSpec rejects. A value marshalled through a
30
+ * declared descriptor is converted rather than checked, so a `null` handed to a
31
+ * numeric one of those lands 0 rather than being refused.
30
32
  * Properties whose value is `undefined` are skipped. A type registered with
31
33
  * `registerClass` binds the wrapper before its `constructed` slot runs, so an
32
34
  * override of that slot already sees a usable instance.
@@ -48,7 +50,10 @@ declare function newObjectWithProperties(gtype: bigint, props: object, wrapper:
48
50
  declare function getObjectProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown;
49
51
  /**
50
52
  * Writes a JavaScript value to a GObject property, converting it to native form
51
- * using the descriptor.
53
+ * using the descriptor. The descriptor converts what it is given rather than checking it against
54
+ * the property's `GObject.ParamSpec`, so `null` and `undefined` written to a numeric or enum
55
+ * property land 0, where the same write to a property installed through `registerClass` is
56
+ * refused with a `TypeError`.
52
57
  *
53
58
  * @param obj The object to write to.
54
59
  * @param propertyName The property name.
@@ -1 +1 @@
1
- {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAa,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAQ5D;;;GAGG;AACH,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC/D,wGAAwG;AACxG,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAmE1D;;;;;;;;;GASG;AACH,iBAAS,2BAA2B,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAGrF;AAoBD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAkBtG;AAED;;;;;;;GAOG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAK7F;AAED;;;;;;;;GAQG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5G;AAED,OAAO,EACH,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC3B,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACzB,CAAC"}
1
+ {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAa,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAQ5D;;;GAGG;AACH,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC/D,wGAAwG;AACxG,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAmE1D;;;;;;;;;GASG;AACH,iBAAS,2BAA2B,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAGrF;AAoBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,iBAAS,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAkBtG;AAED;;;;;;;GAOG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAK7F;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5G;AAED,OAAO,EACH,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC3B,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACzB,CAAC"}
package/dist/object.js CHANGED
@@ -76,7 +76,9 @@ function constructPropertyForEntry(source, name, value) {
76
76
  * that name, dashed or camelCased, and is skipped when the type installs none.
77
77
  * A value that ParamSpec would refuse throws before GObject sees it: a `TypeError`
78
78
  * for a read-only property and for a value of a type the property cannot hold, and
79
- * a `RangeError` for a value the ParamSpec rejects.
79
+ * a `RangeError` for a value the ParamSpec rejects. A value marshalled through a
80
+ * declared descriptor is converted rather than checked, so a `null` handed to a
81
+ * numeric one of those lands 0 rather than being refused.
80
82
  * Properties whose value is `undefined` are skipped. A type registered with
81
83
  * `registerClass` binds the wrapper before its `constructed` slot runs, so an
82
84
  * override of that slot already sees a usable instance.
@@ -116,7 +118,10 @@ function getObjectProperty(obj, propertyName, descriptor) {
116
118
  }
117
119
  /**
118
120
  * Writes a JavaScript value to a GObject property, converting it to native form
119
- * using the descriptor.
121
+ * using the descriptor. The descriptor converts what it is given rather than checking it against
122
+ * the property's `GObject.ParamSpec`, so `null` and `undefined` written to a numeric or enum
123
+ * property land 0, where the same write to a property installed through `registerClass` is
124
+ * refused with a `TypeError`.
120
125
  *
121
126
  * @param obj The object to write to.
122
127
  * @param propertyName The property name.
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Descriptor, type ExternalObject, type Handle, newObject } from \"@gtkx/native\";\nimport { type AnyClass, getParentClass } from \"@gtkx/utils\";\nimport { bind } from \"./bind.js\";\nimport { objectT, stringT, voidT } from \"./descriptors.js\";\nimport { LIB, VALUE_T } from \"./library.js\";\nimport { type ConstructProperty, constructPropertyFor } from \"./properties.js\";\nimport { getHandle, registerWrapper } from \"./registry.js\";\nimport { fromValue, newValueForDescriptor, toValue } from \"./value.js\";\n\n/**\n * One construct property a wrapper class accepts: the canonical `GObject` name it is set under,\n * and the descriptor its value is marshalled through.\n */\ntype ConstructBinding = [name: string, descriptor: Descriptor];\n/** The construct properties a wrapper class accepts, keyed by the camelCased name callers give them. */\ntype ConstructBindings = Record<string, ConstructBinding>;\ntype ResolvedBindings = { generation: number; bindings: ConstructBindings };\n\nconst declaredBindings: WeakMap<AnyClass, ConstructBindings> = new WeakMap();\nconst resolvedBindings: WeakMap<AnyClass, ResolvedBindings> = new WeakMap();\nconst declarations = { generation: 0 };\nconst NO_BINDINGS: ConstructBindings = Object.create(null) as ConstructBindings;\n\nconst gObjectGetProperty = bind(\n LIB,\n \"g_object_get_property\",\n [objectT(\"borrowed\"), stringT(\"borrowed\"), VALUE_T],\n voidT,\n);\n\nconst gObjectSetProperty = bind(\n LIB,\n \"g_object_set_property\",\n [objectT(\"borrowed\"), stringT(\"borrowed\"), VALUE_T],\n voidT,\n);\n\nfunction collectDeclaredBindings(cls: AnyClass): ConstructBindings[] {\n const declared: ConstructBindings[] = [];\n let current: AnyClass | null = cls;\n\n while (current !== null) {\n const own = declaredBindings.get(current);\n\n if (own !== undefined) {\n declared.push(own);\n }\n\n current = getParentClass(current);\n }\n\n return declared;\n}\n\nfunction mergeDeclaredBindings(cls: AnyClass): ConstructBindings {\n const declared = collectDeclaredBindings(cls);\n const merged: ConstructBindings = Object.create(null) as ConstructBindings;\n\n for (let index = declared.length - 1; index >= 0; index--) {\n Object.assign(merged, declared[index]);\n }\n\n return merged;\n}\n\nfunction constructBindingsFor(cls: AnyClass | undefined): ConstructBindings {\n if (cls === undefined) {\n return NO_BINDINGS;\n }\n\n const cached = resolvedBindings.get(cls);\n\n if (cached?.generation === declarations.generation) {\n return cached.bindings;\n }\n\n const bindings = mergeDeclaredBindings(cls);\n resolvedBindings.set(cls, { generation: declarations.generation, bindings });\n\n return bindings;\n}\n\n/**\n * Declares the construct properties a wrapper class accepts, so `newObjectWithProperties`\n * marshals each one through its descriptor rather than resolving it from the\n * `GObject.ParamSpec` the type installs. A class inherits the declarations of its ancestors.\n * Registering takes effect immediately, including for classes already constructed from and for\n * subclasses that already inherited an earlier declaration.\n *\n * @param cls The wrapper class the properties are declared on.\n * @param bindings CamelCased property names mapped to their canonical name and descriptor.\n */\nfunction registerConstructProperties(cls: AnyClass, bindings: ConstructBindings): void {\n declaredBindings.set(cls, bindings);\n declarations.generation += 1;\n}\n\nfunction constructPropertyForEntry(\n source: { gtype: bigint; bindings: ConstructBindings; wrapper: object },\n name: string,\n value: unknown,\n): ConstructProperty | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const binding = source.bindings[name];\n\n if (binding === undefined) {\n return constructPropertyFor(source.gtype, name, value, source.wrapper);\n }\n\n return { name: binding[0], value: toValue(binding[1], value) };\n}\n\n/**\n * Constructs a new GObject of the given type, setting the supplied construct\n * properties, and binds `wrapper` to it. A property the wrapper's class declares\n * through `registerConstructProperties` is marshalled through its descriptor; any\n * other one is marshalled through the `GObject.ParamSpec` the type installs under\n * that name, dashed or camelCased, and is skipped when the type installs none.\n * A value that ParamSpec would refuse throws before GObject sees it: a `TypeError`\n * for a read-only property and for a value of a type the property cannot hold, and\n * a `RangeError` for a value the ParamSpec rejects.\n * Properties whose value is `undefined` are skipped. A type registered with\n * `registerClass` binds the wrapper before its `constructed` slot runs, so an\n * override of that slot already sees a usable instance.\n *\n * @param gtype The GType of the object to construct.\n * @param props Property names mapped to the values to set them to.\n * @param wrapper The wrapper instance to bind to the new object.\n * @returns The handle of the newly created object.\n */\nfunction newObjectWithProperties(gtype: bigint, props: object, wrapper: object): ExternalObject<Handle> {\n const names: string[] = [];\n const values: ExternalObject<Handle>[] = [];\n const bindings = constructBindingsFor(wrapper.constructor as AnyClass | undefined);\n const source = { gtype, bindings, wrapper };\n\n for (const name of Object.keys(props)) {\n const property = constructPropertyForEntry(source, name, Reflect.get(props, name));\n\n if (property !== undefined) {\n names.push(property.name);\n values.push(property.value);\n }\n }\n\n newObject(gtype, names, values, wrapper, registerWrapper);\n\n return getHandle(wrapper);\n}\n\n/**\n * Reads a GObject property and converts it to its JavaScript value using the\n * descriptor.\n *\n * @param obj The object to read from.\n * @param propertyName The property name.\n * @param descriptor Describes the property's type.\n */\nfunction getObjectProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown {\n const value = newValueForDescriptor(descriptor);\n gObjectGetProperty(getHandle(obj), propertyName, value);\n\n return fromValue(value);\n}\n\n/**\n * Writes a JavaScript value to a GObject property, converting it to native form\n * using the descriptor.\n *\n * @param obj The object to write to.\n * @param propertyName The property name.\n * @param descriptor Describes the property's type.\n * @param jsValue The value to set.\n */\nfunction setObjectProperty(obj: object, propertyName: string, descriptor: Descriptor, jsValue: unknown): void {\n gObjectSetProperty(getHandle(obj), propertyName, toValue(descriptor, jsValue));\n}\n\nexport {\n newObjectWithProperties,\n getObjectProperty,\n registerConstructProperties,\n setObjectProperty,\n type ConstructBinding,\n type ConstructBindings,\n};\n"]}
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAiB,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA0B,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAWvE,MAAM,gBAAgB,GAAyC,IAAI,OAAO,EAAE,CAAC;AAC7E,MAAM,gBAAgB,GAAwC,IAAI,OAAO,EAAE,CAAC;AAC5E,MAAM,YAAY,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AACvC,MAAM,WAAW,GAAsB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAsB,CAAC;AAEhF,MAAM,kBAAkB,GAAG,IAAI,CAC3B,GAAG,EACH,uBAAuB,EACvB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,EACnD,KAAK,CACR,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,CAC3B,GAAG,EACH,uBAAuB,EACvB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,EACnD,KAAK,CACR,CAAC;AAEF,SAAS,uBAAuB,CAAC,GAAa;IAC1C,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,IAAI,OAAO,GAAoB,GAAG,CAAC;IAEnC,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE1C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAa;IACxC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAsB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAsB,CAAC;IAE3E,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAyB;IACnD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEzC,IAAI,MAAM,EAAE,UAAU,KAAK,YAAY,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC5C,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE7E,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,2BAA2B,CAAC,GAAa,EAAE,QAA2B;IAC3E,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpC,YAAY,CAAC,UAAU,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,yBAAyB,CAC9B,MAAuE,EACvE,IAAY,EACZ,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,uBAAuB,CAAC,KAAa,EAAE,KAAa,EAAE,OAAe;IAC1E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,WAAmC,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,yBAAyB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAEnF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAE1D,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,GAAW,EAAE,YAAoB,EAAE,UAAsB;IAChF,MAAM,KAAK,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAChD,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IAExD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CAAC,GAAW,EAAE,YAAoB,EAAE,UAAsB,EAAE,OAAgB;IAClG,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,OAAO,EACH,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC3B,iBAAiB,GAGpB,CAAC","sourcesContent":["import { type Descriptor, type ExternalObject, type Handle, newObject } from \"@gtkx/native\";\nimport { type AnyClass, getParentClass } from \"@gtkx/utils\";\nimport { bind } from \"./bind.js\";\nimport { objectT, stringT, voidT } from \"./descriptors.js\";\nimport { LIB, VALUE_T } from \"./library.js\";\nimport { type ConstructProperty, constructPropertyFor } from \"./properties.js\";\nimport { getHandle, registerWrapper } from \"./registry.js\";\nimport { fromValue, newValueForDescriptor, toValue } from \"./value.js\";\n\n/**\n * One construct property a wrapper class accepts: the canonical `GObject` name it is set under,\n * and the descriptor its value is marshalled through.\n */\ntype ConstructBinding = [name: string, descriptor: Descriptor];\n/** The construct properties a wrapper class accepts, keyed by the camelCased name callers give them. */\ntype ConstructBindings = Record<string, ConstructBinding>;\ntype ResolvedBindings = { generation: number; bindings: ConstructBindings };\n\nconst declaredBindings: WeakMap<AnyClass, ConstructBindings> = new WeakMap();\nconst resolvedBindings: WeakMap<AnyClass, ResolvedBindings> = new WeakMap();\nconst declarations = { generation: 0 };\nconst NO_BINDINGS: ConstructBindings = Object.create(null) as ConstructBindings;\n\nconst gObjectGetProperty = bind(\n LIB,\n \"g_object_get_property\",\n [objectT(\"borrowed\"), stringT(\"borrowed\"), VALUE_T],\n voidT,\n);\n\nconst gObjectSetProperty = bind(\n LIB,\n \"g_object_set_property\",\n [objectT(\"borrowed\"), stringT(\"borrowed\"), VALUE_T],\n voidT,\n);\n\nfunction collectDeclaredBindings(cls: AnyClass): ConstructBindings[] {\n const declared: ConstructBindings[] = [];\n let current: AnyClass | null = cls;\n\n while (current !== null) {\n const own = declaredBindings.get(current);\n\n if (own !== undefined) {\n declared.push(own);\n }\n\n current = getParentClass(current);\n }\n\n return declared;\n}\n\nfunction mergeDeclaredBindings(cls: AnyClass): ConstructBindings {\n const declared = collectDeclaredBindings(cls);\n const merged: ConstructBindings = Object.create(null) as ConstructBindings;\n\n for (let index = declared.length - 1; index >= 0; index--) {\n Object.assign(merged, declared[index]);\n }\n\n return merged;\n}\n\nfunction constructBindingsFor(cls: AnyClass | undefined): ConstructBindings {\n if (cls === undefined) {\n return NO_BINDINGS;\n }\n\n const cached = resolvedBindings.get(cls);\n\n if (cached?.generation === declarations.generation) {\n return cached.bindings;\n }\n\n const bindings = mergeDeclaredBindings(cls);\n resolvedBindings.set(cls, { generation: declarations.generation, bindings });\n\n return bindings;\n}\n\n/**\n * Declares the construct properties a wrapper class accepts, so `newObjectWithProperties`\n * marshals each one through its descriptor rather than resolving it from the\n * `GObject.ParamSpec` the type installs. A class inherits the declarations of its ancestors.\n * Registering takes effect immediately, including for classes already constructed from and for\n * subclasses that already inherited an earlier declaration.\n *\n * @param cls The wrapper class the properties are declared on.\n * @param bindings CamelCased property names mapped to their canonical name and descriptor.\n */\nfunction registerConstructProperties(cls: AnyClass, bindings: ConstructBindings): void {\n declaredBindings.set(cls, bindings);\n declarations.generation += 1;\n}\n\nfunction constructPropertyForEntry(\n source: { gtype: bigint; bindings: ConstructBindings; wrapper: object },\n name: string,\n value: unknown,\n): ConstructProperty | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n const binding = source.bindings[name];\n\n if (binding === undefined) {\n return constructPropertyFor(source.gtype, name, value, source.wrapper);\n }\n\n return { name: binding[0], value: toValue(binding[1], value) };\n}\n\n/**\n * Constructs a new GObject of the given type, setting the supplied construct\n * properties, and binds `wrapper` to it. A property the wrapper's class declares\n * through `registerConstructProperties` is marshalled through its descriptor; any\n * other one is marshalled through the `GObject.ParamSpec` the type installs under\n * that name, dashed or camelCased, and is skipped when the type installs none.\n * A value that ParamSpec would refuse throws before GObject sees it: a `TypeError`\n * for a read-only property and for a value of a type the property cannot hold, and\n * a `RangeError` for a value the ParamSpec rejects. A value marshalled through a\n * declared descriptor is converted rather than checked, so a `null` handed to a\n * numeric one of those lands 0 rather than being refused.\n * Properties whose value is `undefined` are skipped. A type registered with\n * `registerClass` binds the wrapper before its `constructed` slot runs, so an\n * override of that slot already sees a usable instance.\n *\n * @param gtype The GType of the object to construct.\n * @param props Property names mapped to the values to set them to.\n * @param wrapper The wrapper instance to bind to the new object.\n * @returns The handle of the newly created object.\n */\nfunction newObjectWithProperties(gtype: bigint, props: object, wrapper: object): ExternalObject<Handle> {\n const names: string[] = [];\n const values: ExternalObject<Handle>[] = [];\n const bindings = constructBindingsFor(wrapper.constructor as AnyClass | undefined);\n const source = { gtype, bindings, wrapper };\n\n for (const name of Object.keys(props)) {\n const property = constructPropertyForEntry(source, name, Reflect.get(props, name));\n\n if (property !== undefined) {\n names.push(property.name);\n values.push(property.value);\n }\n }\n\n newObject(gtype, names, values, wrapper, registerWrapper);\n\n return getHandle(wrapper);\n}\n\n/**\n * Reads a GObject property and converts it to its JavaScript value using the\n * descriptor.\n *\n * @param obj The object to read from.\n * @param propertyName The property name.\n * @param descriptor Describes the property's type.\n */\nfunction getObjectProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown {\n const value = newValueForDescriptor(descriptor);\n gObjectGetProperty(getHandle(obj), propertyName, value);\n\n return fromValue(value);\n}\n\n/**\n * Writes a JavaScript value to a GObject property, converting it to native form\n * using the descriptor. The descriptor converts what it is given rather than checking it against\n * the property's `GObject.ParamSpec`, so `null` and `undefined` written to a numeric or enum\n * property land 0, where the same write to a property installed through `registerClass` is\n * refused with a `TypeError`.\n *\n * @param obj The object to write to.\n * @param propertyName The property name.\n * @param descriptor Describes the property's type.\n * @param jsValue The value to set.\n */\nfunction setObjectProperty(obj: object, propertyName: string, descriptor: Descriptor, jsValue: unknown): void {\n gObjectSetProperty(getHandle(obj), propertyName, toValue(descriptor, jsValue));\n}\n\nexport {\n newObjectWithProperties,\n getObjectProperty,\n registerConstructProperties,\n setObjectProperty,\n type ConstructBinding,\n type ConstructBindings,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"param-spec.d.ts","sourceRoot":"","sources":["../src/param-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAQ,MAAM,cAAc,CAAC;AAiCtE,KAAK,UAAU,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AA4D9C,QAAA,MAAM,aAAa,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,MAA2D,CAAC;AAEnH,QAAA,MAAM,iBAAiB,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,MACE,CAAC;AAE9D,QAAA,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,OAAyC,CAAC;AACnF,QAAA,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,OAA+C,CAAC;AAC9F,QAAA,MAAM,qBAAqB,GAAI,OAAO,MAAM,KAAG,OAA+C,CAAC;AAE/F,QAAA,MAAM,qBAAqB,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,OAC/C,CAAC;AAwEhD,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAcpD;AAoCD,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,KAAK,UAAU,EACf,aAAa,EACb,qBAAqB,GACxB,CAAC"}
1
+ {"version":3,"file":"param-spec.d.ts","sourceRoot":"","sources":["../src/param-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAQ,MAAM,cAAc,CAAC;AAkCtE,KAAK,UAAU,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AA6D9C,QAAA,MAAM,aAAa,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,MAA2D,CAAC;AAEnH,QAAA,MAAM,iBAAiB,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,MACE,CAAC;AAE9D,QAAA,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,OAAyC,CAAC;AACnF,QAAA,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,OAA+C,CAAC;AAC9F,QAAA,MAAM,qBAAqB,GAAI,OAAO,MAAM,KAAG,OAA+C,CAAC;AAE/F,QAAA,MAAM,qBAAqB,GAAI,OAAO,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,cAAc,CAAC,MAAM,CAAC,KAAG,OAC/C,CAAC;AAoEhD,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAepD;AAoCD,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,KAAK,UAAU,EACf,aAAa,EACb,qBAAqB,GACxB,CAAC"}
@@ -3,7 +3,7 @@ import { bind } from "./bind.js";
3
3
  import { biguint64T, booleanT, stringT, uint32T, voidT } from "./descriptors.js";
4
4
  import { LIB, PARAM_T, VALUE_T } from "./library.js";
5
5
  import { getInstanceType } from "./registry.js";
6
- import { getStrvType, isTypedClass, TYPE_BOOLEAN, TYPE_BOXED, TYPE_CHAR, TYPE_DOUBLE, TYPE_ENUM, TYPE_FLAGS, TYPE_FLOAT, TYPE_INT, TYPE_INT64, TYPE_INTERFACE, TYPE_INVALID, TYPE_LONG, TYPE_OBJECT, TYPE_PARAM, TYPE_POINTER, TYPE_STRING, TYPE_UCHAR, TYPE_UINT, TYPE_UINT64, TYPE_ULONG, TYPE_VARIANT, typeFundamental, typeIsA, } from "./type.js";
6
+ import { getStrvType, isTypedClass, TYPE_BOOLEAN, TYPE_BOXED, TYPE_CHAR, TYPE_DOUBLE, TYPE_ENUM, TYPE_FLAGS, TYPE_FLOAT, TYPE_GTYPE, TYPE_INT, TYPE_INT64, TYPE_INTERFACE, TYPE_INVALID, TYPE_LONG, TYPE_OBJECT, TYPE_PARAM, TYPE_POINTER, TYPE_STRING, TYPE_UCHAR, TYPE_UINT, TYPE_UINT64, TYPE_ULONG, TYPE_VARIANT, typeFundamental, typeIsA, } from "./type.js";
7
7
  const PARAM_READABLE = 1;
8
8
  const PARAM_WRITABLE = 2;
9
9
  const PARAM_CONSTRUCT_ONLY = 8;
@@ -21,7 +21,6 @@ const UINT32_MAXIMUM = 4_294_967_295;
21
21
  const INT64_MINIMUM = -(2n ** 63n);
22
22
  const INT64_MAXIMUM = 2n ** 63n - 1n;
23
23
  const UINT64_MAXIMUM = 2n ** 64n - 1n;
24
- const FLOAT_MAXIMUM = 3.4028234663852886e38;
25
24
  const WRAPPED_FUNDAMENTALS = new Set([
26
25
  TYPE_BOXED,
27
26
  TYPE_INTERFACE,
@@ -29,6 +28,7 @@ const WRAPPED_FUNDAMENTALS = new Set([
29
28
  TYPE_PARAM,
30
29
  TYPE_VARIANT,
31
30
  ]);
31
+ const isWideUnsignedValue = wideIntegerGuardFor(0n, UINT64_MAXIMUM);
32
32
  const SCALAR_GUARDS = new Map([
33
33
  [TYPE_BOOLEAN, isBooleanValue],
34
34
  [TYPE_STRING, isStringValue],
@@ -39,11 +39,11 @@ const SCALAR_GUARDS = new Map([
39
39
  [TYPE_ENUM, integerGuardFor(INT32_MINIMUM, INT32_MAXIMUM)],
40
40
  [TYPE_FLAGS, integerGuardFor(0, UINT32_MAXIMUM)],
41
41
  [TYPE_LONG, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],
42
- [TYPE_ULONG, wideIntegerGuardFor(0n, UINT64_MAXIMUM)],
42
+ [TYPE_ULONG, isWideUnsignedValue],
43
43
  [TYPE_INT64, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],
44
- [TYPE_UINT64, wideIntegerGuardFor(0n, UINT64_MAXIMUM)],
45
- [TYPE_FLOAT, isFloatValue],
46
- [TYPE_DOUBLE, isDoubleValue],
44
+ [TYPE_UINT64, isWideUnsignedValue],
45
+ [TYPE_FLOAT, isNumberValue],
46
+ [TYPE_DOUBLE, isNumberValue],
47
47
  [TYPE_POINTER, isNullValue],
48
48
  ]);
49
49
  const layout = { wasChecked: false };
@@ -66,11 +66,8 @@ function isStringValue(value) {
66
66
  function isStrvValue(value) {
67
67
  return value == null || (Array.isArray(value) && value.every((item) => typeof item === "string"));
68
68
  }
69
- function isDoubleValue(value) {
70
- return value == null || (typeof value === "number" && Number.isFinite(value));
71
- }
72
- function isFloatValue(value) {
73
- return isDoubleValue(value) && (value == null || Math.abs(value) <= FLOAT_MAXIMUM);
69
+ function isNumberValue(value) {
70
+ return typeof value === "number";
74
71
  }
75
72
  function isAnyValue() {
76
73
  return true;
@@ -78,11 +75,8 @@ function isAnyValue() {
78
75
  function isNullValue(value) {
79
76
  return value == null;
80
77
  }
81
- function isIntegerWithin(value, minimum, maximum) {
82
- return Number.isSafeInteger(value) && value >= minimum && value <= maximum;
83
- }
84
78
  function integerGuardFor(minimum, maximum) {
85
- return (value) => value == null || isIntegerWithin(value, minimum, maximum);
79
+ return (value) => Number.isSafeInteger(value) && value >= minimum && value <= maximum;
86
80
  }
87
81
  function toWideInteger(value) {
88
82
  if (typeof value === "bigint") {
@@ -92,9 +86,6 @@ function toWideInteger(value) {
92
86
  }
93
87
  function wideIntegerGuardFor(minimum, maximum) {
94
88
  return (value) => {
95
- if (value == null) {
96
- return true;
97
- }
98
89
  const wide = toWideInteger(value);
99
90
  return wide !== undefined && wide >= minimum && wide <= maximum;
100
91
  };
@@ -109,10 +100,17 @@ function resolveGtype(value) {
109
100
  function wrappedGuardFor(valueType) {
110
101
  return (value) => value == null || typeIsA(resolveGtype(value), valueType);
111
102
  }
103
+ function exactGuardFor(valueType) {
104
+ if (valueType === TYPE_GTYPE) {
105
+ return isWideUnsignedValue;
106
+ }
107
+ return valueType === getStrvType() ? isStrvValue : undefined;
108
+ }
112
109
  function valueGuardFor(valueType) {
113
110
  assertParamLayout();
114
- if (valueType === getStrvType()) {
115
- return isStrvValue;
111
+ const exact = exactGuardFor(valueType);
112
+ if (exact !== undefined) {
113
+ return exact;
116
114
  }
117
115
  const fundamental = typeFundamental(valueType);
118
116
  if (WRAPPED_FUNDAMENTALS.has(fundamental)) {
@@ -1 +1 @@
1
- {"version":3,"file":"param-spec.js","sourceRoot":"","sources":["../src/param-spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ExternalObject, type Handle, read } from \"@gtkx/native\";\nimport { bind } from \"./bind.js\";\nimport { biguint64T, booleanT, stringT, uint32T, voidT } from \"./descriptors.js\";\nimport { LIB, PARAM_T, VALUE_T } from \"./library.js\";\nimport { getInstanceType } from \"./registry.js\";\nimport {\n getStrvType,\n isTypedClass,\n TYPE_BOOLEAN,\n TYPE_BOXED,\n TYPE_CHAR,\n TYPE_DOUBLE,\n TYPE_ENUM,\n TYPE_FLAGS,\n TYPE_FLOAT,\n TYPE_INT,\n TYPE_INT64,\n TYPE_INTERFACE,\n TYPE_INVALID,\n TYPE_LONG,\n TYPE_OBJECT,\n TYPE_PARAM,\n TYPE_POINTER,\n TYPE_STRING,\n TYPE_UCHAR,\n TYPE_UINT,\n TYPE_UINT64,\n TYPE_ULONG,\n TYPE_VARIANT,\n typeFundamental,\n typeIsA,\n} from \"./type.js\";\n\ntype ValueGuard = (value: unknown) => boolean;\ntype ParamLayout = { flags: number; valueType: bigint };\n\nconst PARAM_READABLE = 1;\nconst PARAM_WRITABLE = 2;\nconst PARAM_CONSTRUCT_ONLY = 8;\nconst PARAM_LAX_VALIDATION = 16;\nconst READ_FLAGS = PARAM_READABLE | PARAM_WRITABLE | PARAM_CONSTRUCT_ONLY | PARAM_LAX_VALIDATION;\nconst FLAGS_BYTE_OFFSET = 16;\nconst VALUE_TYPE_BYTE_OFFSET = 24;\nconst LAYOUT_PROBE_NAME = \"gtkx-param-layout\";\nconst INT8_MINIMUM = -128;\nconst INT8_MAXIMUM = 127;\nconst UINT8_MAXIMUM = 255;\nconst INT32_MINIMUM = -2_147_483_648;\nconst INT32_MAXIMUM = 2_147_483_647;\nconst UINT32_MAXIMUM = 4_294_967_295;\nconst INT64_MINIMUM = -(2n ** 63n);\nconst INT64_MAXIMUM = 2n ** 63n - 1n;\nconst UINT64_MAXIMUM = 2n ** 64n - 1n;\nconst FLOAT_MAXIMUM = 3.4028234663852886e38;\n\nconst WRAPPED_FUNDAMENTALS: Set<bigint> = new Set([\n TYPE_BOXED,\n TYPE_INTERFACE,\n TYPE_OBJECT,\n TYPE_PARAM,\n TYPE_VARIANT,\n]);\n\nconst SCALAR_GUARDS: Map<bigint, ValueGuard> = new Map([\n [TYPE_BOOLEAN, isBooleanValue],\n [TYPE_STRING, isStringValue],\n [TYPE_CHAR, integerGuardFor(INT8_MINIMUM, INT8_MAXIMUM)],\n [TYPE_UCHAR, integerGuardFor(0, UINT8_MAXIMUM)],\n [TYPE_INT, integerGuardFor(INT32_MINIMUM, INT32_MAXIMUM)],\n [TYPE_UINT, integerGuardFor(0, UINT32_MAXIMUM)],\n [TYPE_ENUM, integerGuardFor(INT32_MINIMUM, INT32_MAXIMUM)],\n [TYPE_FLAGS, integerGuardFor(0, UINT32_MAXIMUM)],\n [TYPE_LONG, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],\n [TYPE_ULONG, wideIntegerGuardFor(0n, UINT64_MAXIMUM)],\n [TYPE_INT64, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],\n [TYPE_UINT64, wideIntegerGuardFor(0n, UINT64_MAXIMUM)],\n [TYPE_FLOAT, isFloatValue],\n [TYPE_DOUBLE, isDoubleValue],\n [TYPE_POINTER, isNullValue],\n]);\n\nconst layout = { wasChecked: false };\nconst paramValueValidate = bind(LIB, \"g_param_value_validate\", [PARAM_T, VALUE_T], booleanT);\nconst paramSpecUnref = bind(LIB, \"g_param_spec_unref\", [PARAM_T], voidT);\nconst paramSpecRefSink = bind(LIB, \"g_param_spec_ref_sink\", [PARAM_T], PARAM_T);\n\nconst newParamSpecBoolean = bind(\n LIB,\n \"g_param_spec_boolean\",\n [stringT(\"borrowed\"), stringT(\"borrowed\"), stringT(\"borrowed\"), booleanT, uint32T],\n PARAM_T,\n);\n\nconst getParamFlags = (pspec: ExternalObject<Handle>): number => read(pspec, uint32T, FLAGS_BYTE_OFFSET) as number;\n\nconst getParamValueType = (pspec: ExternalObject<Handle>): bigint =>\n read(pspec, biguint64T, VALUE_TYPE_BYTE_OFFSET) as bigint;\n\nconst isParamWritable = (flags: number): boolean => (flags & PARAM_WRITABLE) !== 0;\nconst isParamConstructOnly = (flags: number): boolean => (flags & PARAM_CONSTRUCT_ONLY) !== 0;\nconst isParamLaxlyValidated = (flags: number): boolean => (flags & PARAM_LAX_VALIDATION) !== 0;\n\nconst wasParamValueModified = (pspec: ExternalObject<Handle>, value: ExternalObject<Handle>): boolean =>\n paramValueValidate(pspec, value) as boolean;\n\nfunction isBooleanValue(value: unknown): boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isStringValue(value: unknown): boolean {\n return value == null || typeof value === \"string\";\n}\n\nfunction isStrvValue(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.every((item) => typeof item === \"string\"));\n}\n\nfunction isDoubleValue(value: unknown): boolean {\n return value == null || (typeof value === \"number\" && Number.isFinite(value));\n}\n\nfunction isFloatValue(value: unknown): boolean {\n return isDoubleValue(value) && (value == null || Math.abs(value as number) <= FLOAT_MAXIMUM);\n}\n\nfunction isAnyValue(): boolean {\n return true;\n}\n\nfunction isNullValue(value: unknown): boolean {\n return value == null;\n}\n\nfunction isIntegerWithin(value: unknown, minimum: number, maximum: number): boolean {\n return Number.isSafeInteger(value) && (value as number) >= minimum && (value as number) <= maximum;\n}\n\nfunction integerGuardFor(minimum: number, maximum: number): ValueGuard {\n return (value) => value == null || isIntegerWithin(value, minimum, maximum);\n}\n\nfunction toWideInteger(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") {\n return value;\n }\n\n return Number.isSafeInteger(value) ? BigInt(value as number) : undefined;\n}\n\nfunction wideIntegerGuardFor(minimum: bigint, maximum: bigint): ValueGuard {\n return (value) => {\n if (value == null) {\n return true;\n }\n\n const wide = toWideInteger(value);\n\n return wide !== undefined && wide >= minimum && wide <= maximum;\n };\n}\n\nfunction resolveGtype(value: unknown): bigint {\n const instanceType = getInstanceType(value as object);\n\n if (instanceType !== TYPE_INVALID) {\n return instanceType;\n }\n\n return isTypedClass(value) ? value.__type__ : TYPE_INVALID;\n}\n\nfunction wrappedGuardFor(valueType: bigint): ValueGuard {\n return (value) => value == null || typeIsA(resolveGtype(value), valueType);\n}\n\nfunction valueGuardFor(valueType: bigint): ValueGuard {\n assertParamLayout();\n\n if (valueType === getStrvType()) {\n return isStrvValue;\n }\n\n const fundamental = typeFundamental(valueType);\n\n if (WRAPPED_FUNDAMENTALS.has(fundamental)) {\n return wrappedGuardFor(valueType);\n }\n\n return SCALAR_GUARDS.get(fundamental) ?? isAnyValue;\n}\n\nfunction readProbeLayout(flags: number): ParamLayout {\n const probe = newParamSpecBoolean(LAYOUT_PROBE_NAME, null, null, false, flags) as ExternalObject<Handle>;\n paramSpecRefSink(probe);\n\n try {\n return { flags: getParamFlags(probe), valueType: getParamValueType(probe) };\n } finally {\n paramSpecUnref(probe);\n }\n}\n\nfunction isLayoutIntact(flags: number): boolean {\n const layout = readProbeLayout(flags);\n\n return (layout.flags & READ_FLAGS) === flags && layout.valueType === TYPE_BOOLEAN;\n}\n\nfunction assertParamLayout(): void {\n if (layout.wasChecked) {\n return;\n }\n\n layout.wasChecked = true;\n const readWrite = PARAM_READABLE | PARAM_WRITABLE;\n\n if (isLayoutIntact(readWrite) && isLayoutIntact(readWrite | PARAM_CONSTRUCT_ONLY | PARAM_LAX_VALIDATION)) {\n return;\n }\n\n throw new Error(\n \"GParamSpec does not match the memory layout this build reads a property's flags and value type at\",\n );\n}\n\nexport {\n getParamFlags,\n getParamValueType,\n isParamConstructOnly,\n isParamLaxlyValidated,\n isParamWritable,\n type ValueGuard,\n valueGuardFor,\n wasParamValueModified,\n};\n"]}
1
+ {"version":3,"file":"param-spec.js","sourceRoot":"","sources":["../src/param-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,IAAI,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACH,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,cAAc,EACd,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,eAAe,EACf,OAAO,GACV,MAAM,WAAW,CAAC;AAKnB,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,MAAM,UAAU,GAAG,cAAc,GAAG,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AACjG,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAC9C,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC;AAC1B,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,aAAa,GAAG,CAAC,aAAa,CAAC;AACrC,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,cAAc,GAAG,aAAa,CAAC;AACrC,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC;AACnC,MAAM,aAAa,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAC;AACrC,MAAM,cAAc,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAC;AAEtC,MAAM,oBAAoB,GAAgB,IAAI,GAAG,CAAC;IAC9C,UAAU;IACV,cAAc;IACd,WAAW;IACX,UAAU;IACV,YAAY;CACf,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAe,mBAAmB,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;AAEhF,MAAM,aAAa,GAA4B,IAAI,GAAG,CAAC;IACnD,CAAC,YAAY,EAAE,cAAc,CAAC;IAC9B,CAAC,WAAW,EAAE,aAAa,CAAC;IAC5B,CAAC,SAAS,EAAE,eAAe,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC/C,CAAC,QAAQ,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACzD,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IAC/C,CAAC,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAC1D,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IAChD,CAAC,SAAS,EAAE,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAC9D,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACjC,CAAC,UAAU,EAAE,mBAAmB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAC/D,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAClC,CAAC,UAAU,EAAE,aAAa,CAAC;IAC3B,CAAC,WAAW,EAAE,aAAa,CAAC;IAC5B,CAAC,YAAY,EAAE,WAAW,CAAC;CAC9B,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACrC,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC7F,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,oBAAoB,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AACzE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,uBAAuB,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAEhF,MAAM,mBAAmB,GAAG,IAAI,CAC5B,GAAG,EACH,sBAAsB,EACtB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAClF,OAAO,CACV,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,KAA6B,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,iBAAiB,CAAW,CAAC;AAEnH,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAU,EAAE,CAChE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,sBAAsB,CAAW,CAAC;AAE9D,MAAM,eAAe,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,CAAC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AACnF,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,CAAC,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;AAC9F,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,CAAC,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;AAE/F,MAAM,qBAAqB,GAAG,CAAC,KAA6B,EAAE,KAA6B,EAAW,EAAE,CACpG,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAY,CAAC;AAEhD,SAAS,cAAc,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACjC,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IAC/B,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;AACtG,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,UAAU;IACf,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IAC/B,OAAO,KAAK,IAAI,IAAI,CAAC;AACzB,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,OAAe;IACrD,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAK,KAAgB,IAAI,OAAO,IAAK,KAAgB,IAAI,OAAO,CAAC;AAClH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe,EAAE,OAAe;IACzD,OAAO,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAElC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC;IACpE,CAAC,CAAC;AACN,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAChC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAe,CAAC,CAAC;IAEtD,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC;IACxB,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB;IACtC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB;IACpC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB;IACpC,iBAAiB,EAAE,CAAC;IACpB,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAEvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAE/C,IAAI,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC;AACxD,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAA2B,CAAC;IACzG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAExB,IAAI,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;IAChF,CAAC;YAAS,CAAC;QACP,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACjC,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,KAAK,IAAI,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC;AACtF,CAAC;AAED,SAAS,iBAAiB;IACtB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACpB,OAAO;IACX,CAAC;IAED,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,SAAS,GAAG,cAAc,GAAG,cAAc,CAAC;IAElD,IAAI,cAAc,CAAC,SAAS,CAAC,IAAI,cAAc,CAAC,SAAS,GAAG,oBAAoB,GAAG,oBAAoB,CAAC,EAAE,CAAC;QACvG,OAAO;IACX,CAAC;IAED,MAAM,IAAI,KAAK,CACX,mGAAmG,CACtG,CAAC;AACN,CAAC;AAED,OAAO,EACH,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EAEf,aAAa,EACb,qBAAqB,GACxB,CAAC","sourcesContent":["import { type ExternalObject, type Handle, read } from \"@gtkx/native\";\nimport { bind } from \"./bind.js\";\nimport { biguint64T, booleanT, stringT, uint32T, voidT } from \"./descriptors.js\";\nimport { LIB, PARAM_T, VALUE_T } from \"./library.js\";\nimport { getInstanceType } from \"./registry.js\";\nimport {\n getStrvType,\n isTypedClass,\n TYPE_BOOLEAN,\n TYPE_BOXED,\n TYPE_CHAR,\n TYPE_DOUBLE,\n TYPE_ENUM,\n TYPE_FLAGS,\n TYPE_FLOAT,\n TYPE_GTYPE,\n TYPE_INT,\n TYPE_INT64,\n TYPE_INTERFACE,\n TYPE_INVALID,\n TYPE_LONG,\n TYPE_OBJECT,\n TYPE_PARAM,\n TYPE_POINTER,\n TYPE_STRING,\n TYPE_UCHAR,\n TYPE_UINT,\n TYPE_UINT64,\n TYPE_ULONG,\n TYPE_VARIANT,\n typeFundamental,\n typeIsA,\n} from \"./type.js\";\n\ntype ValueGuard = (value: unknown) => boolean;\ntype ParamLayout = { flags: number; valueType: bigint };\n\nconst PARAM_READABLE = 1;\nconst PARAM_WRITABLE = 2;\nconst PARAM_CONSTRUCT_ONLY = 8;\nconst PARAM_LAX_VALIDATION = 16;\nconst READ_FLAGS = PARAM_READABLE | PARAM_WRITABLE | PARAM_CONSTRUCT_ONLY | PARAM_LAX_VALIDATION;\nconst FLAGS_BYTE_OFFSET = 16;\nconst VALUE_TYPE_BYTE_OFFSET = 24;\nconst LAYOUT_PROBE_NAME = \"gtkx-param-layout\";\nconst INT8_MINIMUM = -128;\nconst INT8_MAXIMUM = 127;\nconst UINT8_MAXIMUM = 255;\nconst INT32_MINIMUM = -2_147_483_648;\nconst INT32_MAXIMUM = 2_147_483_647;\nconst UINT32_MAXIMUM = 4_294_967_295;\nconst INT64_MINIMUM = -(2n ** 63n);\nconst INT64_MAXIMUM = 2n ** 63n - 1n;\nconst UINT64_MAXIMUM = 2n ** 64n - 1n;\n\nconst WRAPPED_FUNDAMENTALS: Set<bigint> = new Set([\n TYPE_BOXED,\n TYPE_INTERFACE,\n TYPE_OBJECT,\n TYPE_PARAM,\n TYPE_VARIANT,\n]);\n\nconst isWideUnsignedValue: ValueGuard = wideIntegerGuardFor(0n, UINT64_MAXIMUM);\n\nconst SCALAR_GUARDS: Map<bigint, ValueGuard> = new Map([\n [TYPE_BOOLEAN, isBooleanValue],\n [TYPE_STRING, isStringValue],\n [TYPE_CHAR, integerGuardFor(INT8_MINIMUM, INT8_MAXIMUM)],\n [TYPE_UCHAR, integerGuardFor(0, UINT8_MAXIMUM)],\n [TYPE_INT, integerGuardFor(INT32_MINIMUM, INT32_MAXIMUM)],\n [TYPE_UINT, integerGuardFor(0, UINT32_MAXIMUM)],\n [TYPE_ENUM, integerGuardFor(INT32_MINIMUM, INT32_MAXIMUM)],\n [TYPE_FLAGS, integerGuardFor(0, UINT32_MAXIMUM)],\n [TYPE_LONG, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],\n [TYPE_ULONG, isWideUnsignedValue],\n [TYPE_INT64, wideIntegerGuardFor(INT64_MINIMUM, INT64_MAXIMUM)],\n [TYPE_UINT64, isWideUnsignedValue],\n [TYPE_FLOAT, isNumberValue],\n [TYPE_DOUBLE, isNumberValue],\n [TYPE_POINTER, isNullValue],\n]);\n\nconst layout = { wasChecked: false };\nconst paramValueValidate = bind(LIB, \"g_param_value_validate\", [PARAM_T, VALUE_T], booleanT);\nconst paramSpecUnref = bind(LIB, \"g_param_spec_unref\", [PARAM_T], voidT);\nconst paramSpecRefSink = bind(LIB, \"g_param_spec_ref_sink\", [PARAM_T], PARAM_T);\n\nconst newParamSpecBoolean = bind(\n LIB,\n \"g_param_spec_boolean\",\n [stringT(\"borrowed\"), stringT(\"borrowed\"), stringT(\"borrowed\"), booleanT, uint32T],\n PARAM_T,\n);\n\nconst getParamFlags = (pspec: ExternalObject<Handle>): number => read(pspec, uint32T, FLAGS_BYTE_OFFSET) as number;\n\nconst getParamValueType = (pspec: ExternalObject<Handle>): bigint =>\n read(pspec, biguint64T, VALUE_TYPE_BYTE_OFFSET) as bigint;\n\nconst isParamWritable = (flags: number): boolean => (flags & PARAM_WRITABLE) !== 0;\nconst isParamConstructOnly = (flags: number): boolean => (flags & PARAM_CONSTRUCT_ONLY) !== 0;\nconst isParamLaxlyValidated = (flags: number): boolean => (flags & PARAM_LAX_VALIDATION) !== 0;\n\nconst wasParamValueModified = (pspec: ExternalObject<Handle>, value: ExternalObject<Handle>): boolean =>\n paramValueValidate(pspec, value) as boolean;\n\nfunction isBooleanValue(value: unknown): boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isStringValue(value: unknown): boolean {\n return value == null || typeof value === \"string\";\n}\n\nfunction isStrvValue(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.every((item) => typeof item === \"string\"));\n}\n\nfunction isNumberValue(value: unknown): boolean {\n return typeof value === \"number\";\n}\n\nfunction isAnyValue(): boolean {\n return true;\n}\n\nfunction isNullValue(value: unknown): boolean {\n return value == null;\n}\n\nfunction integerGuardFor(minimum: number, maximum: number): ValueGuard {\n return (value) => Number.isSafeInteger(value) && (value as number) >= minimum && (value as number) <= maximum;\n}\n\nfunction toWideInteger(value: unknown): bigint | undefined {\n if (typeof value === \"bigint\") {\n return value;\n }\n\n return Number.isSafeInteger(value) ? BigInt(value as number) : undefined;\n}\n\nfunction wideIntegerGuardFor(minimum: bigint, maximum: bigint): ValueGuard {\n return (value) => {\n const wide = toWideInteger(value);\n\n return wide !== undefined && wide >= minimum && wide <= maximum;\n };\n}\n\nfunction resolveGtype(value: unknown): bigint {\n const instanceType = getInstanceType(value as object);\n\n if (instanceType !== TYPE_INVALID) {\n return instanceType;\n }\n\n return isTypedClass(value) ? value.__type__ : TYPE_INVALID;\n}\n\nfunction wrappedGuardFor(valueType: bigint): ValueGuard {\n return (value) => value == null || typeIsA(resolveGtype(value), valueType);\n}\n\nfunction exactGuardFor(valueType: bigint): ValueGuard | undefined {\n if (valueType === TYPE_GTYPE) {\n return isWideUnsignedValue;\n }\n\n return valueType === getStrvType() ? isStrvValue : undefined;\n}\n\nfunction valueGuardFor(valueType: bigint): ValueGuard {\n assertParamLayout();\n const exact = exactGuardFor(valueType);\n\n if (exact !== undefined) {\n return exact;\n }\n\n const fundamental = typeFundamental(valueType);\n\n if (WRAPPED_FUNDAMENTALS.has(fundamental)) {\n return wrappedGuardFor(valueType);\n }\n\n return SCALAR_GUARDS.get(fundamental) ?? isAnyValue;\n}\n\nfunction readProbeLayout(flags: number): ParamLayout {\n const probe = newParamSpecBoolean(LAYOUT_PROBE_NAME, null, null, false, flags) as ExternalObject<Handle>;\n paramSpecRefSink(probe);\n\n try {\n return { flags: getParamFlags(probe), valueType: getParamValueType(probe) };\n } finally {\n paramSpecUnref(probe);\n }\n}\n\nfunction isLayoutIntact(flags: number): boolean {\n const layout = readProbeLayout(flags);\n\n return (layout.flags & READ_FLAGS) === flags && layout.valueType === TYPE_BOOLEAN;\n}\n\nfunction assertParamLayout(): void {\n if (layout.wasChecked) {\n return;\n }\n\n layout.wasChecked = true;\n const readWrite = PARAM_READABLE | PARAM_WRITABLE;\n\n if (isLayoutIntact(readWrite) && isLayoutIntact(readWrite | PARAM_CONSTRUCT_ONLY | PARAM_LAX_VALIDATION)) {\n return;\n }\n\n throw new Error(\n \"GParamSpec does not match the memory layout this build reads a property's flags and value type at\",\n );\n}\n\nexport {\n getParamFlags,\n getParamValueType,\n isParamConstructOnly,\n isParamLaxlyValidated,\n isParamWritable,\n type ValueGuard,\n valueGuardFor,\n wasParamValueModified,\n};\n"]}
@@ -2,7 +2,7 @@ import type { ExternalObject, Handle, RegisterClassProperty } from "@gtkx/native
2
2
  import type { AnyClass } from "@gtkx/utils";
3
3
  import { type ValueGuard } from "./param-spec.js";
4
4
  import { type InterfaceProperty } from "./registry.js";
5
- import { type ValueWriter } from "./value.js";
5
+ import { type ValueNarrower, type ValueWriter } from "./value.js";
6
6
  type PropertyCheck = {
7
7
  name: string;
8
8
  propertyName: string;
@@ -10,6 +10,7 @@ type PropertyCheck = {
10
10
  flags: number;
11
11
  valueType: bigint;
12
12
  canHoldValue: ValueGuard;
13
+ narrowValue: ValueNarrower;
13
14
  write?: ValueWriter;
14
15
  scratch?: ExternalObject<Handle>;
15
16
  };