@gtkx/runtime 2.0.0-beta.1 → 2.0.0-beta.10

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 (74) hide show
  1. package/README.md +43 -40
  2. package/dist/descriptors.d.ts +2 -1
  3. package/dist/descriptors.d.ts.map +1 -1
  4. package/dist/descriptors.js +5 -1
  5. package/dist/descriptors.js.map +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/internal.d.ts +17 -0
  11. package/dist/internal.d.ts.map +1 -1
  12. package/dist/internal.js +13 -0
  13. package/dist/internal.js.map +1 -1
  14. package/dist/lifecycle.js +1 -1
  15. package/dist/lifecycle.js.map +1 -1
  16. package/dist/listeners.d.ts +3 -13
  17. package/dist/listeners.d.ts.map +1 -1
  18. package/dist/listeners.js +12 -12
  19. package/dist/listeners.js.map +1 -1
  20. package/dist/mixin.d.ts +5 -3
  21. package/dist/mixin.d.ts.map +1 -1
  22. package/dist/mixin.js +36 -9
  23. package/dist/mixin.js.map +1 -1
  24. package/dist/object.d.ts +14 -3
  25. package/dist/object.d.ts.map +1 -1
  26. package/dist/object.js +20 -27
  27. package/dist/object.js.map +1 -1
  28. package/dist/properties.d.ts +4 -2
  29. package/dist/properties.d.ts.map +1 -1
  30. package/dist/properties.js +69 -16
  31. package/dist/properties.js.map +1 -1
  32. package/dist/property-brand.d.ts +5 -0
  33. package/dist/property-brand.d.ts.map +1 -0
  34. package/dist/property-brand.js +5 -0
  35. package/dist/property-brand.js.map +1 -0
  36. package/dist/register-class.d.ts +102 -20
  37. package/dist/register-class.d.ts.map +1 -1
  38. package/dist/register-class.js +19 -37
  39. package/dist/register-class.js.map +1 -1
  40. package/dist/registry.d.ts +1 -1
  41. package/dist/registry.d.ts.map +1 -1
  42. package/dist/registry.js +4 -4
  43. package/dist/registry.js.map +1 -1
  44. package/dist/signal-brand.d.ts +12 -0
  45. package/dist/signal-brand.d.ts.map +1 -0
  46. package/dist/signal-brand.js +6 -0
  47. package/dist/signal-brand.js.map +1 -0
  48. package/dist/signal.d.ts +39 -2
  49. package/dist/signal.d.ts.map +1 -1
  50. package/dist/signal.js +75 -5
  51. package/dist/signal.js.map +1 -1
  52. package/dist/type.d.ts.map +1 -1
  53. package/dist/type.js +1 -1
  54. package/dist/type.js.map +1 -1
  55. package/dist/value.d.ts +2 -1
  56. package/dist/value.d.ts.map +1 -1
  57. package/dist/value.js +28 -7
  58. package/dist/value.js.map +1 -1
  59. package/package.json +7 -5
  60. package/src/descriptors.ts +7 -0
  61. package/src/index.ts +2 -2
  62. package/src/internal.ts +42 -0
  63. package/src/lifecycle.ts +1 -1
  64. package/src/listeners.ts +21 -26
  65. package/src/mixin.ts +55 -9
  66. package/src/object.ts +57 -7
  67. package/src/properties.ts +94 -17
  68. package/src/property-brand.ts +5 -0
  69. package/src/register-class.ts +296 -95
  70. package/src/registry.ts +4 -4
  71. package/src/signal-brand.ts +29 -0
  72. package/src/signal.ts +177 -6
  73. package/src/type.ts +1 -1
  74. package/src/value.ts +40 -5
@@ -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\";\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
+ {"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 <AdwApplication> or <GtkApplication>, \" +\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,14 +1,4 @@
1
1
  import { type SignalHandler } from "./signal.js";
2
- /**
3
- * The connect and disconnect surface {@link onSignal}, {@link onceSignal} and {@link offSignal}
4
- * drive on an emitter.
5
- */
6
- type SignalConnectable = {
7
- /** Connects a handler to a signal and returns its handler id. */
8
- connect(signal: string, handler: SignalHandler, isAfter?: boolean): number;
9
- /** Disconnects the handler previously connected under the given id. */
10
- disconnect(handlerId: number): void;
11
- };
12
2
  /**
13
3
  * Connects a handler to a signal and tracks it so it can later be removed with
14
4
  * {@link offSignal}.
@@ -18,7 +8,7 @@ type SignalConnectable = {
18
8
  * @param handler The callback invoked on each emission.
19
9
  * @param isAfter When true, run the handler after the default handler.
20
10
  */
21
- declare function onSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void;
11
+ declare function onSignal(instance: object, signal: string, handler: SignalHandler, isAfter?: boolean): void;
22
12
  /**
23
13
  * Connects a handler that runs at most once, disconnecting itself after the first
24
14
  * emission.
@@ -28,7 +18,7 @@ declare function onSignal(instance: SignalConnectable, signal: string, handler:
28
18
  * @param handler The callback invoked on the first emission.
29
19
  * @param isAfter When true, run the handler after the default handler.
30
20
  */
31
- declare function onceSignal(instance: SignalConnectable, signal: string, handler: SignalHandler, isAfter?: boolean): void;
21
+ declare function onceSignal(instance: object, signal: string, handler: SignalHandler, isAfter?: boolean): void;
32
22
  /**
33
23
  * Disconnects a handler previously connected with {@link onSignal} or
34
24
  * {@link onceSignal}. Does nothing if the handler is not currently connected.
@@ -37,6 +27,6 @@ declare function onceSignal(instance: SignalConnectable, signal: string, handler
37
27
  * @param signal The signal name the handler was connected to.
38
28
  * @param handler The handler to disconnect.
39
29
  */
40
- declare function offSignal(instance: SignalConnectable, signal: string, handler: SignalHandler): void;
30
+ declare function offSignal(instance: object, signal: string, handler: SignalHandler): void;
41
31
  export { onSignal, onceSignal, offSignal };
42
32
  //# sourceMappingURL=listeners.d.ts.map
@@ -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;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"}
1
+ {"version":3,"file":"listeners.d.ts","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,aAAa,EACrB,MAAM,aAAa,CAAC;AA+DrB;;;;;;;;GAQG;AACH,iBAAS,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAGnG;AAED;;;;;;;;GAQG;AACH,iBAAS,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAarG;AAED;;;;;;;GAOG;AACH,iBAAS,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAcjF;AAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
package/dist/listeners.js CHANGED
@@ -1,16 +1,17 @@
1
- import { isSignalHandlerConnected, untrackConnection } from "./signal.js";
1
+ import { canonicalDetailedSignalName, connectSignalByName, disconnectSignal, isSignalHandlerConnected, } from "./signal.js";
2
2
  const listenerTable = new WeakMap();
3
- const findListenerHandlerId = (instance, signal, handler) => listenerTable.get(instance)?.get(signal)?.get(handler)?.at(-1);
3
+ const findListenerHandlerId = (instance, signal, handler) => listenerTable.get(instance)?.get(canonicalDetailedSignalName(signal))?.get(handler)?.at(-1);
4
4
  const trackListener = (instance, signal, handler, handlerId) => {
5
+ const key = canonicalDetailedSignalName(signal);
5
6
  let bySignal = listenerTable.get(instance);
6
7
  if (!bySignal) {
7
8
  bySignal = new Map();
8
9
  listenerTable.set(instance, bySignal);
9
10
  }
10
- let byHandler = bySignal.get(signal);
11
+ let byHandler = bySignal.get(key);
11
12
  if (!byHandler) {
12
13
  byHandler = new Map();
13
- bySignal.set(signal, byHandler);
14
+ bySignal.set(key, byHandler);
14
15
  }
15
16
  let handlerIds = byHandler.get(handler);
16
17
  if (!handlerIds) {
@@ -27,8 +28,9 @@ const removeTrackedHandlerId = (handlerIds, handlerId) => {
27
28
  return handlerIds.length;
28
29
  };
29
30
  const untrackHandlerId = (instance, signal, handlerId) => {
31
+ const key = canonicalDetailedSignalName(signal);
30
32
  const bySignal = listenerTable.get(instance);
31
- const byHandler = bySignal?.get(signal);
33
+ const byHandler = bySignal?.get(key);
32
34
  if (byHandler === undefined) {
33
35
  return;
34
36
  }
@@ -38,7 +40,7 @@ const untrackHandlerId = (instance, signal, handlerId) => {
38
40
  }
39
41
  }
40
42
  if (byHandler.size === 0) {
41
- bySignal?.delete(signal);
43
+ bySignal?.delete(key);
42
44
  }
43
45
  };
44
46
  /**
@@ -51,7 +53,7 @@ const untrackHandlerId = (instance, signal, handlerId) => {
51
53
  * @param isAfter When true, run the handler after the default handler.
52
54
  */
53
55
  function onSignal(instance, signal, handler, isAfter) {
54
- const handlerId = instance.connect(signal, handler, isAfter);
56
+ const handlerId = connectSignalByName(instance, signal, handler, isAfter);
55
57
  trackListener(instance, signal, handler, handlerId);
56
58
  }
57
59
  /**
@@ -67,11 +69,10 @@ function onceSignal(instance, signal, handler, isAfter) {
67
69
  let handlerId = 0;
68
70
  const wrapped = (...args) => {
69
71
  untrackHandlerId(instance, signal, handlerId);
70
- untrackConnection(instance, handlerId);
71
- instance.disconnect(handlerId);
72
+ disconnectSignal(instance, handlerId);
72
73
  return handler(...args);
73
74
  };
74
- handlerId = instance.connect(signal, wrapped, isAfter);
75
+ handlerId = connectSignalByName(instance, signal, wrapped, isAfter);
75
76
  trackListener(instance, signal, wrapped, handlerId);
76
77
  trackListener(instance, signal, handler, handlerId);
77
78
  }
@@ -89,11 +90,10 @@ function offSignal(instance, signal, handler) {
89
90
  return;
90
91
  }
91
92
  untrackHandlerId(instance, signal, handlerId);
92
- untrackConnection(instance, handlerId);
93
93
  if (!isSignalHandlerConnected(instance, handlerId)) {
94
94
  return;
95
95
  }
96
- instance.disconnect(handlerId);
96
+ disconnectSignal(instance, handlerId);
97
97
  }
98
98
  export { onSignal, onceSignal, offSignal };
99
99
  //# sourceMappingURL=listeners.js.map
@@ -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)?.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
+ {"version":3,"file":"listeners.js","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n canonicalDetailedSignalName,\n connectSignalByName,\n disconnectSignal,\n isSignalHandlerConnected,\n type SignalHandler,\n} from \"./signal.js\";\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(canonicalDetailedSignalName(signal))?.get(handler)?.at(-1);\n\nconst trackListener = (instance: object, signal: string, handler: SignalHandler, handlerId: number): void => {\n const key = canonicalDetailedSignalName(signal);\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(key);\n\n if (!byHandler) {\n byHandler = new Map();\n bySignal.set(key, 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 key = canonicalDetailedSignalName(signal);\n const bySignal = listenerTable.get(instance);\n const byHandler = bySignal?.get(key);\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(key);\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: object, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n const handlerId = connectSignalByName(instance, 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: object, signal: string, handler: SignalHandler, isAfter?: boolean): void {\n let handlerId = 0;\n\n const wrapped: SignalHandler = (...args) => {\n untrackHandlerId(instance, signal, handlerId);\n disconnectSignal(instance, handlerId);\n\n return handler(...args);\n };\n\n handlerId = connectSignalByName(instance, 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: object, 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\n if (!isSignalHandlerConnected(instance, handlerId)) {\n return;\n }\n\n disconnectSignal(instance, handlerId);\n}\n\nexport { onSignal, onceSignal, offSignal };\n"]}
package/dist/mixin.d.ts CHANGED
@@ -14,7 +14,8 @@ type MixinReceiver = {
14
14
  * be merged onto a target prototype.
15
15
  */
16
16
  type Mixin = (base: AnyClass<MixinReceiver>) => AnyClass;
17
- declare function copyLayerMembers(target: AnyClass, layer: object): void;
17
+ declare function markSyntheticSignalMembers(klass: AnyClass, names: readonly string[]): void;
18
+ declare function copyLayerMembers(target: AnyClass, layer: object, inheritedOverrides?: Set<string>): void;
18
19
  /**
19
20
  * Copies each mixin's prototype members onto the target class prototype, skipping
20
21
  * any member already defined anywhere in the target's class chain.
@@ -22,7 +23,8 @@ declare function copyLayerMembers(target: AnyClass, layer: object): void;
22
23
  * @param target The class whose prototype receives the mixin members.
23
24
  * @param mixins The mixins to apply, in order.
24
25
  */
25
- declare function installMixins(target: AnyClass, mixins: Mixin[]): void;
26
+ declare function installMixins(target: AnyClass, mixins: Mixin[], inheritedOverrideNames?: Iterable<string>): void;
27
+ declare function createMixinLayer(parent: AnyClass<MixinReceiver>, mixin: Mixin, inheritedNames: Set<string>): AnyClass;
26
28
  declare function insertMixinLayer(target: AnyClass, mixin: Mixin, inheritedNames: Set<string>): void;
27
- export { copyLayerMembers, insertMixinLayer, installMixins, type MixinReceiver, type Mixin };
29
+ export { copyLayerMembers, createMixinLayer, insertMixinLayer, installMixins, markSyntheticSignalMembers, type MixinReceiver, type Mixin, };
28
30
  //# sourceMappingURL=mixin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mixin.d.ts","sourceRoot":"","sources":["../src/mixin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAE5D;;;GAGG;AACH,KAAK,aAAa,GAAG;IACjB,iEAAiE;IACjE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7F,0FAA0F;IAC1F,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACrD,CAAC;AAEF;;;GAGG;AACH,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC;AAgCzD,iBAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAc9D;AAQD,iBAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAK3F;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"mixin.d.ts","sourceRoot":"","sources":["../src/mixin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAE5D;;;GAGG;AACH,KAAK,aAAa,GAAG;IACjB,iEAAiE;IACjE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7F,0FAA0F;IAC1F,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACrD,CAAC;AAEF;;;GAGG;AACH,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC;AAIzD,iBAAS,0BAA0B,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAEnF;AAgDD,iBAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,IAAI,CAI5G;AAED;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,sBAAsB,GAAE,QAAQ,CAAC,MAAM,CAAM,GAAG,IAAI,CAe7G;AAQD,iBAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,QAAQ,CAa9G;AAED,iBAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAK3F;AAED,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,0BAA0B,EAC1B,KAAK,aAAa,EAClB,KAAK,KAAK,GACb,CAAC"}
package/dist/mixin.js CHANGED
@@ -1,4 +1,8 @@
1
1
  import { getParentClass } from "@gtkx/utils";
2
+ const syntheticSignalMembers = new WeakMap();
3
+ function markSyntheticSignalMembers(klass, names) {
4
+ syntheticSignalMembers.set(klass.prototype, new Set(names));
5
+ }
2
6
  function isDefinedInClassChain(prototype, key) {
3
7
  let current = prototype;
4
8
  while (current !== null && current !== Object.prototype) {
@@ -9,11 +13,22 @@ function isDefinedInClassChain(prototype, key) {
9
13
  }
10
14
  return false;
11
15
  }
12
- function copyLayerMember(target, layer, key) {
16
+ function isNaturalInClassChain(prototype, key) {
17
+ let current = prototype;
18
+ while (current !== null && current !== Object.prototype) {
19
+ if (Object.hasOwn(current, key)) {
20
+ return syntheticSignalMembers.get(current)?.has(key) !== true;
21
+ }
22
+ current = Reflect.getPrototypeOf(current);
23
+ }
24
+ return false;
25
+ }
26
+ function copyLayerMember(target, layer, key, inheritedOverrides) {
13
27
  if (key === "constructor") {
14
28
  return;
15
29
  }
16
- if (isDefinedInClassChain(target.prototype, key)) {
30
+ const isProtectedInherited = !inheritedOverrides.has(key) && isDefinedInClassChain(target.prototype, key);
31
+ if (isProtectedInherited || Object.hasOwn(target.prototype, key)) {
17
32
  return;
18
33
  }
19
34
  const descriptor = Object.getOwnPropertyDescriptor(layer, key);
@@ -21,9 +36,9 @@ function copyLayerMember(target, layer, key) {
21
36
  Object.defineProperty(target.prototype, key, descriptor);
22
37
  }
23
38
  }
24
- function copyLayerMembers(target, layer) {
39
+ function copyLayerMembers(target, layer, inheritedOverrides = new Set()) {
25
40
  for (const key of Object.getOwnPropertyNames(layer)) {
26
- copyLayerMember(target, layer, key);
41
+ copyLayerMember(target, layer, key, inheritedOverrides);
27
42
  }
28
43
  }
29
44
  /**
@@ -33,7 +48,8 @@ function copyLayerMembers(target, layer) {
33
48
  * @param target The class whose prototype receives the mixin members.
34
49
  * @param mixins The mixins to apply, in order.
35
50
  */
36
- function installMixins(target, mixins) {
51
+ function installMixins(target, mixins, inheritedOverrideNames = []) {
52
+ const inheritedOverrides = new Set(inheritedOverrideNames);
37
53
  const empty = class {
38
54
  connect() {
39
55
  return 0;
@@ -43,7 +59,7 @@ function installMixins(target, mixins) {
43
59
  }
44
60
  };
45
61
  for (const mixin of mixins) {
46
- copyLayerMembers(target, mixin(empty).prototype);
62
+ copyLayerMembers(target, mixin(empty).prototype, inheritedOverrides);
47
63
  }
48
64
  }
49
65
  function dropLayerMembers(layer, names) {
@@ -51,11 +67,22 @@ function dropLayerMembers(layer, names) {
51
67
  Reflect.deleteProperty(layer.prototype, name);
52
68
  }
53
69
  }
70
+ function createMixinLayer(parent, mixin, inheritedNames) {
71
+ const layer = mixin(parent);
72
+ const protectedNames = new Set(inheritedNames);
73
+ for (const key of Object.getOwnPropertyNames(layer.prototype)) {
74
+ if (key !== "constructor" && isNaturalInClassChain(parent.prototype, key)) {
75
+ protectedNames.add(key);
76
+ }
77
+ }
78
+ dropLayerMembers(layer, protectedNames);
79
+ return layer;
80
+ }
54
81
  function insertMixinLayer(target, mixin, inheritedNames) {
55
- const layer = mixin(getParentClass(target));
56
- dropLayerMembers(layer, inheritedNames);
82
+ const parent = getParentClass(target);
83
+ const layer = createMixinLayer(parent, mixin, inheritedNames);
57
84
  Object.setPrototypeOf(target.prototype, layer.prototype);
58
85
  Object.setPrototypeOf(target, layer);
59
86
  }
60
- export { copyLayerMembers, insertMixinLayer, installMixins };
87
+ export { copyLayerMembers, createMixinLayer, insertMixinLayer, installMixins, markSyntheticSignalMembers, };
61
88
  //# sourceMappingURL=mixin.js.map
package/dist/mixin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mixin.js","sourceRoot":"","sources":["../src/mixin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,MAAM,aAAa,CAAC;AAmB5D,SAAS,qBAAqB,CAAC,SAAiB,EAAE,GAAW;IACzD,IAAI,OAAO,GAAkB,SAAS,CAAC;IAEvC,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;QACtD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,MAAgB,EAAE,KAAa,EAAE,GAAW;IACjE,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;QACxB,OAAO;IACX,CAAC;IAED,IAAI,qBAAqB,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;QAC/C,OAAO;IACX,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAE/D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB,EAAE,KAAa;IACrD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,MAAgB,EAAE,MAAe;IACpD,MAAM,KAAK,GAA4B;QACnC,OAAO;YACH,OAAO,CAAC,CAAC;QACb,CAAC;QAED,IAAI;YACA,OAAO,SAAS,CAAC;QACrB,CAAC;KACJ,CAAC;IAEF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAe,EAAE,KAAkB;IACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB,EAAE,KAAY,EAAE,cAA2B;IACjF,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAA4B,CAAC,CAAC;IACvE,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACxC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAkC,CAAC","sourcesContent":["import { type AnyClass, getParentClass } from \"@gtkx/utils\";\n\n/**\n * The signal plumbing every base class passed to a {@link Mixin} provides, so mixed-in interface\n * members can connect and emit without knowing the concrete class.\n */\ntype MixinReceiver = {\n /** Connects a handler to a signal and returns its handler id. */\n connect(signal: string, handler: (...args: unknown[]) => unknown, isAfter?: boolean): number;\n /** Emits a signal with the given arguments and returns whatever the emission produced. */\n emit(signal: string, ...args: unknown[]): unknown;\n};\n\n/**\n * A factory that, given a base class, returns a subclass adding extra members to\n * be merged onto a target prototype.\n */\ntype Mixin = (base: AnyClass<MixinReceiver>) => AnyClass;\n\nfunction isDefinedInClassChain(prototype: object, key: string): boolean {\n let current: object | null = prototype;\n\n while (current !== null && current !== Object.prototype) {\n if (Object.hasOwn(current, key)) {\n return true;\n }\n\n current = Reflect.getPrototypeOf(current);\n }\n\n return false;\n}\n\nfunction copyLayerMember(target: AnyClass, layer: object, key: string): void {\n if (key === \"constructor\") {\n return;\n }\n\n if (isDefinedInClassChain(target.prototype, key)) {\n return;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(layer, key);\n\n if (descriptor !== undefined) {\n Object.defineProperty(target.prototype, key, descriptor);\n }\n}\n\nfunction copyLayerMembers(target: AnyClass, layer: object): void {\n for (const key of Object.getOwnPropertyNames(layer)) {\n copyLayerMember(target, layer, key);\n }\n}\n\n/**\n * Copies each mixin's prototype members onto the target class prototype, skipping\n * any member already defined anywhere in the target's class chain.\n *\n * @param target The class whose prototype receives the mixin members.\n * @param mixins The mixins to apply, in order.\n */\nfunction installMixins(target: AnyClass, mixins: Mixin[]): void {\n const empty: AnyClass<MixinReceiver> = class {\n connect(): number {\n return 0;\n }\n\n emit(): unknown {\n return undefined;\n }\n };\n\n for (const mixin of mixins) {\n copyLayerMembers(target, mixin(empty).prototype);\n }\n}\n\nfunction dropLayerMembers(layer: AnyClass, names: Set<string>): void {\n for (const name of names) {\n Reflect.deleteProperty(layer.prototype, name);\n }\n}\n\nfunction insertMixinLayer(target: AnyClass, mixin: Mixin, inheritedNames: Set<string>): void {\n const layer = mixin(getParentClass(target) as AnyClass<MixinReceiver>);\n dropLayerMembers(layer, inheritedNames);\n Object.setPrototypeOf(target.prototype, layer.prototype);\n Object.setPrototypeOf(target, layer);\n}\n\nexport { copyLayerMembers, insertMixinLayer, installMixins, type MixinReceiver, type Mixin };\n"]}
1
+ {"version":3,"file":"mixin.js","sourceRoot":"","sources":["../src/mixin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AnyClass, getParentClass } from \"@gtkx/utils\";\n\n/**\n * The signal plumbing every base class passed to a {@link Mixin} provides, so mixed-in interface\n * members can connect and emit without knowing the concrete class.\n */\ntype MixinReceiver = {\n /** Connects a handler to a signal and returns its handler id. */\n connect(signal: string, handler: (...args: unknown[]) => unknown, isAfter?: boolean): number;\n /** Emits a signal with the given arguments and returns whatever the emission produced. */\n emit(signal: string, ...args: unknown[]): unknown;\n};\n\n/**\n * A factory that, given a base class, returns a subclass adding extra members to\n * be merged onto a target prototype.\n */\ntype Mixin = (base: AnyClass<MixinReceiver>) => AnyClass;\n\nconst syntheticSignalMembers: WeakMap<object, ReadonlySet<string>> = new WeakMap();\n\nfunction markSyntheticSignalMembers(klass: AnyClass, names: readonly string[]): void {\n syntheticSignalMembers.set(klass.prototype, new Set(names));\n}\n\nfunction isDefinedInClassChain(prototype: object, key: string): boolean {\n let current: object | null = prototype;\n\n while (current !== null && current !== Object.prototype) {\n if (Object.hasOwn(current, key)) {\n return true;\n }\n\n current = Reflect.getPrototypeOf(current);\n }\n\n return false;\n}\n\nfunction isNaturalInClassChain(prototype: object, key: string): boolean {\n let current: object | null = prototype;\n\n while (current !== null && current !== Object.prototype) {\n if (Object.hasOwn(current, key)) {\n return syntheticSignalMembers.get(current)?.has(key) !== true;\n }\n\n current = Reflect.getPrototypeOf(current);\n }\n\n return false;\n}\n\nfunction copyLayerMember(target: AnyClass, layer: object, key: string, inheritedOverrides: Set<string>): void {\n if (key === \"constructor\") {\n return;\n }\n\n const isProtectedInherited = !inheritedOverrides.has(key) && isDefinedInClassChain(target.prototype, key);\n\n if (isProtectedInherited || Object.hasOwn(target.prototype, key)) {\n return;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(layer, key);\n\n if (descriptor !== undefined) {\n Object.defineProperty(target.prototype, key, descriptor);\n }\n}\n\nfunction copyLayerMembers(target: AnyClass, layer: object, inheritedOverrides: Set<string> = new Set()): void {\n for (const key of Object.getOwnPropertyNames(layer)) {\n copyLayerMember(target, layer, key, inheritedOverrides);\n }\n}\n\n/**\n * Copies each mixin's prototype members onto the target class prototype, skipping\n * any member already defined anywhere in the target's class chain.\n *\n * @param target The class whose prototype receives the mixin members.\n * @param mixins The mixins to apply, in order.\n */\nfunction installMixins(target: AnyClass, mixins: Mixin[], inheritedOverrideNames: Iterable<string> = []): void {\n const inheritedOverrides = new Set(inheritedOverrideNames);\n const empty: AnyClass<MixinReceiver> = class {\n connect(): number {\n return 0;\n }\n\n emit(): unknown {\n return undefined;\n }\n };\n\n for (const mixin of mixins) {\n copyLayerMembers(target, mixin(empty).prototype, inheritedOverrides);\n }\n}\n\nfunction dropLayerMembers(layer: AnyClass, names: Set<string>): void {\n for (const name of names) {\n Reflect.deleteProperty(layer.prototype, name);\n }\n}\n\nfunction createMixinLayer(parent: AnyClass<MixinReceiver>, mixin: Mixin, inheritedNames: Set<string>): AnyClass {\n const layer = mixin(parent);\n const protectedNames = new Set(inheritedNames);\n\n for (const key of Object.getOwnPropertyNames(layer.prototype)) {\n if (key !== \"constructor\" && isNaturalInClassChain(parent.prototype, key)) {\n protectedNames.add(key);\n }\n }\n\n dropLayerMembers(layer, protectedNames);\n\n return layer;\n}\n\nfunction insertMixinLayer(target: AnyClass, mixin: Mixin, inheritedNames: Set<string>): void {\n const parent = getParentClass(target) as AnyClass<MixinReceiver>;\n const layer = createMixinLayer(parent, mixin, inheritedNames);\n Object.setPrototypeOf(target.prototype, layer.prototype);\n Object.setPrototypeOf(target, layer);\n}\n\nexport {\n copyLayerMembers,\n createMixinLayer,\n insertMixinLayer,\n installMixins,\n markSyntheticSignalMembers,\n type MixinReceiver,\n type Mixin,\n};\n"]}
package/dist/object.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type Descriptor } from "@gtkx/native";
2
2
  import { type AnyClass } from "@gtkx/utils";
3
+ import { propertyMapOverride, writablePropertyMapOverride } from "./property-brand.js";
3
4
  /**
4
5
  * One construct property a wrapper class accepts: the canonical `GObject` name it is set under,
5
6
  * and the descriptor its value is marshalled through.
@@ -54,7 +55,12 @@ declare function newObjectWithProperties<T extends object>(gtype: bigint, props:
54
55
  * @param propertyName The property name.
55
56
  * @param descriptor Describes the property's type.
56
57
  */
57
- declare function getObjectProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown;
58
+ declare function getProperty<TObject extends {
59
+ __properties__: object;
60
+ }, TPropertyMap extends object = TObject extends {
61
+ [propertyMapOverride]?: infer TResolver;
62
+ } ? TResolver extends () => infer TMap ? Extract<NonNullable<TMap>, object> : TObject["__properties__"] : TObject["__properties__"], TName extends Extract<keyof NoInfer<TPropertyMap>, string> = Extract<keyof NoInfer<TPropertyMap>, string>>(obj: TObject, propertyName: TName): NoInfer<TPropertyMap>[TName];
63
+ declare function getProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown;
58
64
  /**
59
65
  * Writes a JavaScript value to a GObject property, converting it to native form
60
66
  * using the descriptor. The descriptor converts what it is given rather than checking it against
@@ -68,6 +74,11 @@ declare function getObjectProperty(obj: object, propertyName: string, descriptor
68
74
  * @param descriptor Describes the property's type.
69
75
  * @param jsValue The value to set.
70
76
  */
71
- declare function setObjectProperty(obj: object, propertyName: string, descriptor: Descriptor, jsValue: unknown): void;
72
- export { newObjectWithProperties, getObjectProperty, registerConstructProperties, setObjectProperty, type ConstructBinding, type ConstructBindings, };
77
+ declare function setProperty<TObject extends {
78
+ __writableProperties__: object;
79
+ }, TPropertyMap extends object = TObject extends {
80
+ [writablePropertyMapOverride]?: infer TResolver;
81
+ } ? TResolver extends () => infer TMap ? Extract<NonNullable<TMap>, object> : TObject["__writableProperties__"] : TObject["__writableProperties__"], TName extends Extract<keyof NoInfer<TPropertyMap>, string> = Extract<keyof NoInfer<TPropertyMap>, string>>(obj: TObject, propertyName: TName, jsValue: NoInfer<TPropertyMap>[TName]): void;
82
+ declare function setProperty(obj: object, propertyName: string, descriptor: Descriptor, jsValue: unknown): void;
83
+ export { newObjectWithProperties, getProperty, registerConstructProperties, setProperty, type ConstructBinding, type ConstructBindings, };
73
84
  //# sourceMappingURL=object.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAA+C,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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,iBAAS,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAsB9F;AAED;;;;;;;GAOG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAK7F;AAED;;;;;;;;;;;;GAYG;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,EAA+C,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,aAAa,CAAC;AAW5D,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAIvF;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,iBAAS,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAsB9F;AAED;;;;;;;GAOG;AACH,iBAAS,WAAW,CAChB,OAAO,SAAS;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,EAC1C,YAAY,SAAS,MAAM,GAAG,OAAO,SAAS;IAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,MAAM,SAAS,CAAA;CAAE,GACnF,SAAS,SAAS,MAAM,MAAM,IAAI,GAC9B,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,gBAAgB,CAAC,GAC7B,OAAO,CAAC,gBAAgB,CAAC,EAC/B,KAAK,SAAS,OAAO,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,EAC3G,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC;AACnE,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;AAmBzF;;;;;;;;;;;;GAYG;AACH,iBAAS,WAAW,CAChB,OAAO,SAAS;IAAE,sBAAsB,EAAE,MAAM,CAAA;CAAE,EAClD,YAAY,SAAS,MAAM,GAAG,OAAO,SAAS;IAAE,CAAC,2BAA2B,CAAC,CAAC,EAAE,MAAM,SAAS,CAAA;CAAE,GAC3F,SAAS,SAAS,MAAM,MAAM,IAAI,GAC9B,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,wBAAwB,CAAC,GACrC,OAAO,CAAC,wBAAwB,CAAC,EACvC,KAAK,SAAS,OAAO,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,EAC3G,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;AAClF,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;AAiBxG,OAAO,EACH,uBAAuB,EACvB,WAAW,EACX,2BAA2B,EAC3B,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACzB,CAAC"}
package/dist/object.js CHANGED
@@ -3,9 +3,10 @@ import { getParentClass } from "@gtkx/utils";
3
3
  import { bind } from "./bind.js";
4
4
  import { objectT, stringT, voidT } from "./descriptors.js";
5
5
  import { LIB, VALUE_T } from "./library.js";
6
- import { coercePropertyValue, constructPropertyFor } from "./properties.js";
6
+ import { coercePropertyValue, constructPropertyFor, readableObjectPropertyFor, writableObjectPropertyFor, } from "./properties.js";
7
+ import { propertyMapOverride, writablePropertyMapOverride } from "./property-brand.js";
7
8
  import { getHandle, registerWrapper } from "./registry.js";
8
- import { fromValueForDescriptor, newValueForDescriptor, toValue } from "./value.js";
9
+ import { fromObjectPropertyValue, fromValueForDescriptor, newValueForDescriptor, toValue } from "./value.js";
9
10
  const declaredBindings = new WeakMap();
10
11
  const resolvedBindings = new WeakMap();
11
12
  const declarations = { generation: 0 };
@@ -113,34 +114,26 @@ function newObjectWithProperties(gtype, props, wrapper) {
113
114
  }
114
115
  return wrapper;
115
116
  }
116
- /**
117
- * Reads a GObject property and converts it to its JavaScript value using the
118
- * descriptor.
119
- *
120
- * @param obj The object to read from.
121
- * @param propertyName The property name.
122
- * @param descriptor Describes the property's type.
123
- */
124
- function getObjectProperty(obj, propertyName, descriptor) {
117
+ function getProperty(obj, propertyName, descriptor) {
118
+ if (arguments.length === 2) {
119
+ const property = readableObjectPropertyFor(obj, propertyName);
120
+ gObjectGetProperty(getHandle(obj), property.name, property.value);
121
+ return fromObjectPropertyValue(property.value);
122
+ }
123
+ if (descriptor === undefined) {
124
+ throw new TypeError("getProperty requires a property descriptor when called with three arguments");
125
+ }
125
126
  const value = newValueForDescriptor(descriptor);
126
127
  gObjectGetProperty(getHandle(obj), propertyName, value);
127
128
  return fromValueForDescriptor(descriptor, value);
128
129
  }
129
- /**
130
- * Writes a JavaScript value to a GObject property, converting it to native form
131
- * using the descriptor. The descriptor converts what it is given rather than checking it against
132
- * the property's `GObject.ParamSpec`, so `null` and `undefined` written to a numeric or enum
133
- * property land 0, and a fractional number written to a whole-number property is truncated toward
134
- * zero, where the same writes to a property installed through `registerClass` are refused with a
135
- * `TypeError`.
136
- *
137
- * @param obj The object to write to.
138
- * @param propertyName The property name.
139
- * @param descriptor Describes the property's type.
140
- * @param jsValue The value to set.
141
- */
142
- function setObjectProperty(obj, propertyName, descriptor, jsValue) {
143
- gObjectSetProperty(getHandle(obj), propertyName, toValue(descriptor, jsValue));
130
+ function setProperty(obj, propertyName, descriptorOrValue, jsValue) {
131
+ if (arguments.length === 3) {
132
+ const property = writableObjectPropertyFor(obj, propertyName, descriptorOrValue);
133
+ gObjectSetProperty(getHandle(obj), property.name, property.value);
134
+ return;
135
+ }
136
+ gObjectSetProperty(getHandle(obj), propertyName, toValue(descriptorOrValue, jsValue));
144
137
  }
145
- export { newObjectWithProperties, getObjectProperty, registerConstructProperties, setObjectProperty, };
138
+ export { newObjectWithProperties, getProperty, registerConstructProperties, setProperty, };
146
139
  //# sourceMappingURL=object.js.map
@@ -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 { coercePropertyValue, type ConstructProperty, constructPropertyFor } from \"./properties.js\";\nimport { getHandle, registerWrapper } from \"./registry.js\";\nimport { fromValueForDescriptor, 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], coercePropertyValue(source.gtype, binding[0], 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, and a number is fitted to\n * the property first, as `coerceObjectProperty` does: truncated toward zero for a\n * whole-number property and clamped to the range its `GObject.ParamSpec` allows.\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 * When construction returns an object that already has a wrapper — it reached\n * JavaScript and was wrapped before `g_object_new` returned, for example a\n * `Gtk.Window` observed through the toplevels list — that existing wrapper is\n * returned instead of binding `wrapper`, so both references stay one object.\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 wrapper bound to the constructed object: `wrapper` itself, or\n * the wrapper the object already had.\n */\nfunction newObjectWithProperties<T extends object>(gtype: bigint, props: object, wrapper: T): T {\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 const existing = newObject(gtype, names, values, wrapper, registerWrapper);\n\n if (existing !== null) {\n return existing as T;\n }\n\n return 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 fromValueForDescriptor(descriptor, 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, and a fractional number written to a whole-number property is truncated toward\n * zero, where the same writes to a property installed through `registerClass` are refused with a\n * `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
+ {"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 {\n coercePropertyValue,\n type ConstructProperty,\n constructPropertyFor,\n readableObjectPropertyFor,\n writableObjectPropertyFor,\n} from \"./properties.js\";\nimport { propertyMapOverride, writablePropertyMapOverride } from \"./property-brand.js\";\nimport { getHandle, registerWrapper } from \"./registry.js\";\nimport { fromObjectPropertyValue, fromValueForDescriptor, 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], coercePropertyValue(source.gtype, binding[0], 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, and a number is fitted to\n * the property first, as `coerceObjectProperty` does: truncated toward zero for a\n * whole-number property and clamped to the range its `GObject.ParamSpec` allows.\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 * When construction returns an object that already has a wrapper — it reached\n * JavaScript and was wrapped before `g_object_new` returned, for example a\n * `Gtk.Window` observed through the toplevels list — that existing wrapper is\n * returned instead of binding `wrapper`, so both references stay one object.\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 wrapper bound to the constructed object: `wrapper` itself, or\n * the wrapper the object already had.\n */\nfunction newObjectWithProperties<T extends object>(gtype: bigint, props: object, wrapper: T): T {\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 const existing = newObject(gtype, names, values, wrapper, registerWrapper);\n\n if (existing !== null) {\n return existing as T;\n }\n\n return 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 getProperty<\n TObject extends { __properties__: object },\n TPropertyMap extends object = TObject extends { [propertyMapOverride]?: infer TResolver }\n ? TResolver extends () => infer TMap\n ? Extract<NonNullable<TMap>, object>\n : TObject[\"__properties__\"]\n : TObject[\"__properties__\"],\n TName extends Extract<keyof NoInfer<TPropertyMap>, string> = Extract<keyof NoInfer<TPropertyMap>, string>,\n>(obj: TObject, propertyName: TName): NoInfer<TPropertyMap>[TName];\nfunction getProperty(obj: object, propertyName: string, descriptor: Descriptor): unknown;\nfunction getProperty(obj: object, propertyName: string, descriptor?: Descriptor): unknown {\n if (arguments.length === 2) {\n const property = readableObjectPropertyFor(obj, propertyName);\n gObjectGetProperty(getHandle(obj), property.name, property.value);\n\n return fromObjectPropertyValue(property.value);\n }\n\n if (descriptor === undefined) {\n throw new TypeError(\"getProperty requires a property descriptor when called with three arguments\");\n }\n\n const value = newValueForDescriptor(descriptor);\n gObjectGetProperty(getHandle(obj), propertyName, value);\n\n return fromValueForDescriptor(descriptor, 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, and a fractional number written to a whole-number property is truncated toward\n * zero, where the same writes to a property installed through `registerClass` are refused with a\n * `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 setProperty<\n TObject extends { __writableProperties__: object },\n TPropertyMap extends object = TObject extends { [writablePropertyMapOverride]?: infer TResolver }\n ? TResolver extends () => infer TMap\n ? Extract<NonNullable<TMap>, object>\n : TObject[\"__writableProperties__\"]\n : TObject[\"__writableProperties__\"],\n TName extends Extract<keyof NoInfer<TPropertyMap>, string> = Extract<keyof NoInfer<TPropertyMap>, string>,\n>(obj: TObject, propertyName: TName, jsValue: NoInfer<TPropertyMap>[TName]): void;\nfunction setProperty(obj: object, propertyName: string, descriptor: Descriptor, jsValue: unknown): void;\nfunction setProperty(\n obj: object,\n propertyName: string,\n descriptorOrValue: unknown,\n jsValue?: unknown,\n): void {\n if (arguments.length === 3) {\n const property = writableObjectPropertyFor(obj, propertyName, descriptorOrValue);\n gObjectSetProperty(getHandle(obj), property.name, property.value);\n\n return;\n }\n\n gObjectSetProperty(getHandle(obj), propertyName, toValue(descriptorOrValue as Descriptor, jsValue));\n}\n\nexport {\n newObjectWithProperties,\n getProperty,\n registerConstructProperties,\n setProperty,\n type ConstructBinding,\n type ConstructBindings,\n};\n"]}
@@ -21,7 +21,7 @@ type AccessorBase = PropertyCheck & {
21
21
  type DeclaredAccessor = AccessorBase & {
22
22
  isInterfaceProperty?: false;
23
23
  memberName: string;
24
- hasGeneratedMember: boolean;
24
+ hasMemberAccessor: boolean;
25
25
  };
26
26
  type InterfaceAccessor = AccessorBase & {
27
27
  isInterfaceProperty: true;
@@ -61,6 +61,8 @@ declare const newParamSpecOverride: (name: string, source: bigint | AnyClass) =>
61
61
  * rather than looking for a generated accessor, which codegen omits when a method shares the name.
62
62
  */
63
63
  declare function isReadableProperty(gtype: bigint, propertyName: string): boolean;
64
+ declare function readableObjectPropertyFor(instance: object, name: string): ConstructProperty;
65
+ declare function writableObjectPropertyFor(instance: object, name: string, value: unknown): ConstructProperty;
64
66
  declare function coercePropertyValue(gtype: bigint, propertyName: string, value: unknown): unknown;
65
67
  /**
66
68
  * Fits a number to what a GObject property accepts, the way an animation writing a value on every
@@ -86,5 +88,5 @@ declare function buildPropertyDispatch(source: PropertyDispatchSource): Property
86
88
  */
87
89
  declare function getDeclaredPropertyName(object: object, accessor: string): string | undefined;
88
90
  declare function toNativeProperties(properties: Record<string, PropertySpec>): RegisterClassProperty[];
89
- export { buildPropertyDispatch, coerceObjectProperty, getDeclaredPropertyName, isReadableProperty, coercePropertyValue, constructPropertyFor, GET_PROPERTY_VFUNC, makeGetProperty, makeSetProperty, newParamSpecOverride, SET_PROPERTY_VFUNC, toNativeProperties, type ConstructProperty, type PropertyDispatch, type PropertySpec, };
91
+ export { buildPropertyDispatch, coerceObjectProperty, getDeclaredPropertyName, isReadableProperty, coercePropertyValue, constructPropertyFor, GET_PROPERTY_VFUNC, makeGetProperty, makeSetProperty, newParamSpecOverride, readableObjectPropertyFor, SET_PROPERTY_VFUNC, toNativeProperties, writableObjectPropertyFor, type ConstructProperty, type PropertyDispatch, type PropertySpec, };
90
92
  //# sourceMappingURL=properties.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,KAAK,QAAQ,EAA2C,MAAM,aAAa,CAAC;AAIrF,OAAO,EAQH,KAAK,UAAU,EAIlB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAMH,KAAK,iBAAiB,EACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIH,KAAK,aAAa,EAElB,KAAK,WAAW,EAEnB,MAAM,YAAY,CAAC;AAEpB,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,CAAC;IACzB,WAAW,EAAE,aAAa,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,KAAK,YAAY,GAAG,aAAa,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,KAAK,gBAAgB,GAAG,YAAY,GAAG;IACnC,mBAAmB,CAAC,EAAE,KAAK,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,KAAK,iBAAiB,GAAG,YAAY,GAAG;IAAE,mBAAmB,EAAE,IAAI,CAAA;CAAE,CAAC;AACtE,KAAK,gBAAgB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAC7D,6FAA6F;AAC7F,KAAK,YAAY,GAAG,MAAM,CAAC;AAE3B,KAAK,gBAAgB,GAAG;IACpB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;CACjC,CAAC;AAKF,QAAA,MAAM,kBAAkB,qBAAqB,CAAC;AAC9C,QAAA,MAAM,kBAAkB,qBAAqB,CAAC;AAwH9C;;;;;;;;;;GAUG;AACH,QAAA,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,GAAG,QAAQ,KAAG,cAAc,CAAC,MAAM,CACP,CAAC;AAsGvF;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAUxE;AAgDD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAQzF;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxF;AAED,iBAAS,oBAAoB,CACzB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GAChB,iBAAiB,GAAG,SAAS,CAU/B;AA0ND,iBAAS,eAAe,CAAC,QAAQ,EAAE,gBAAgB,IACnB,MAAM,MAAM,EAAE,YAAY,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,YAAY,KAAG,IAAI,CAM1G;AAED,iBAAS,eAAe,CAAC,QAAQ,EAAE,gBAAgB,IACnB,MAAM,MAAM,EAAE,YAAY,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,YAAY,KAAG,IAAI,CAI1G;AA0ED,iBAAS,qBAAqB,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAK/E;AAED;;;GAGG;AACH,iBAAS,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMrF;AAED,iBAAS,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,qBAAqB,EAAE,CAK7F;AAED,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GACpB,CAAC"}
1
+ {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"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"}