@metamask-previews/client-controller 1.0.1-preview-3866c0ff1 → 1.0.1-preview-e3275932a

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 (45) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/dist/ClientController-method-action-types.cjs +7 -0
  3. package/dist/ClientController-method-action-types.cjs.map +1 -0
  4. package/dist/{ClientController-method-action-types.d.ts → ClientController-method-action-types.d.cts} +2 -2
  5. package/dist/ClientController-method-action-types.d.cts.map +1 -0
  6. package/dist/ClientController-method-action-types.d.mts +23 -0
  7. package/dist/ClientController-method-action-types.d.mts.map +1 -0
  8. package/dist/{ClientController-method-action-types.js → ClientController-method-action-types.mjs} +1 -1
  9. package/dist/ClientController-method-action-types.mjs.map +1 -0
  10. package/dist/ClientController.cjs +117 -0
  11. package/dist/ClientController.cjs.map +1 -0
  12. package/dist/{ClientController.d.ts → ClientController.d.cts} +5 -5
  13. package/dist/ClientController.d.cts.map +1 -0
  14. package/dist/ClientController.d.mts +135 -0
  15. package/dist/ClientController.d.mts.map +1 -0
  16. package/dist/{ClientController.js → ClientController.mjs} +2 -2
  17. package/dist/ClientController.mjs.map +1 -0
  18. package/dist/index.cjs +9 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.cts +5 -0
  21. package/dist/index.d.cts.map +1 -0
  22. package/dist/index.d.mts +5 -0
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/index.mjs +3 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/selectors.cjs +18 -0
  27. package/dist/selectors.cjs.map +1 -0
  28. package/dist/selectors.d.cts +9 -0
  29. package/dist/selectors.d.cts.map +1 -0
  30. package/dist/selectors.d.mts +9 -0
  31. package/dist/selectors.d.mts.map +1 -0
  32. package/dist/{selectors.js → selectors.mjs} +1 -1
  33. package/dist/selectors.mjs.map +1 -0
  34. package/package.json +16 -12
  35. package/dist/ClientController-method-action-types.d.ts.map +0 -1
  36. package/dist/ClientController-method-action-types.js.map +0 -1
  37. package/dist/ClientController.d.ts.map +0 -1
  38. package/dist/ClientController.js.map +0 -1
  39. package/dist/index.d.ts +0 -5
  40. package/dist/index.d.ts.map +0 -1
  41. package/dist/index.js +0 -3
  42. package/dist/index.js.map +0 -1
  43. package/dist/selectors.d.ts +0 -17
  44. package/dist/selectors.d.ts.map +0 -1
  45. package/dist/selectors.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
- - **BREAKING:** Bump minimum Node.js version to 22 ([#9168](https://github.com/MetaMask/core/pull/9168))
13
12
  - Bump `@metamask/messenger` from `^1.0.0` to `^2.0.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632), [#9392](https://github.com/MetaMask/core/pull/9392))
14
13
  - Bump `@metamask/base-controller` from `^9.0.1` to `^9.1.0` ([#8457](https://github.com/MetaMask/core/pull/8457))
15
14
 
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * This file is auto generated.
4
+ * Do not edit manually.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=ClientController-method-action-types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController-method-action-types.cjs","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ClientController } from './ClientController.js';\n\n/**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\nexport type ClientControllerSetUiOpenAction = {\n type: `ClientController:setUiOpen`;\n handler: ClientController['setUiOpen'];\n};\n\n/**\n * Union of all ClientController action types.\n */\nexport type ClientControllerMethodActions = ClientControllerSetUiOpenAction;\n"]}
@@ -2,7 +2,7 @@
2
2
  * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
- import type { ClientController } from './ClientController.js';
5
+ import type { ClientController } from "./ClientController.cjs";
6
6
  /**
7
7
  * Updates state with whether the MetaMask UI is open.
8
8
  *
@@ -20,4 +20,4 @@ export type ClientControllerSetUiOpenAction = {
20
20
  * Union of all ClientController action types.
21
21
  */
22
22
  export type ClientControllerMethodActions = ClientControllerSetUiOpenAction;
23
- //# sourceMappingURL=ClientController-method-action-types.d.ts.map
23
+ //# sourceMappingURL=ClientController-method-action-types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController-method-action-types.d.cts","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,+BAA8B;AAE9D;;;;;;;;GAQG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,+BAA+B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * This file is auto generated.
3
+ * Do not edit manually.
4
+ */
5
+ import type { ClientController } from "./ClientController.mjs";
6
+ /**
7
+ * Updates state with whether the MetaMask UI is open.
8
+ *
9
+ * This method should be called when the user has opened the first window or
10
+ * screen containing the MetaMask UI, or closed the last window or screen
11
+ * containing the MetaMask UI.
12
+ *
13
+ * @param open - Whether the MetaMask UI is open.
14
+ */
15
+ export type ClientControllerSetUiOpenAction = {
16
+ type: `ClientController:setUiOpen`;
17
+ handler: ClientController['setUiOpen'];
18
+ };
19
+ /**
20
+ * Union of all ClientController action types.
21
+ */
22
+ export type ClientControllerMethodActions = ClientControllerSetUiOpenAction;
23
+ //# sourceMappingURL=ClientController-method-action-types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController-method-action-types.d.mts","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,+BAA8B;AAE9D;;;;;;;;GAQG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,+BAA+B,CAAC"}
@@ -3,4 +3,4 @@
3
3
  * Do not edit manually.
4
4
  */
5
5
  export {};
6
- //# sourceMappingURL=ClientController-method-action-types.js.map
6
+ //# sourceMappingURL=ClientController-method-action-types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController-method-action-types.mjs","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ClientController } from './ClientController.js';\n\n/**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\nexport type ClientControllerSetUiOpenAction = {\n type: `ClientController:setUiOpen`;\n handler: ClientController['setUiOpen'];\n};\n\n/**\n * Union of all ClientController action types.\n */\nexport type ClientControllerMethodActions = ClientControllerSetUiOpenAction;\n"]}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientController = exports.getDefaultClientControllerState = exports.controllerName = void 0;
4
+ const base_controller_1 = require("@metamask/base-controller");
5
+ // === GENERAL ===
6
+ /**
7
+ * The name of the {@link ClientController}.
8
+ */
9
+ exports.controllerName = 'ClientController';
10
+ /**
11
+ * Constructs the default {@link ClientController} state.
12
+ *
13
+ * @returns The default {@link ClientController} state.
14
+ */
15
+ function getDefaultClientControllerState() {
16
+ return {
17
+ isUiOpen: false,
18
+ };
19
+ }
20
+ exports.getDefaultClientControllerState = getDefaultClientControllerState;
21
+ /**
22
+ * The metadata for each property in {@link ClientControllerState}.
23
+ */
24
+ const controllerMetadata = {
25
+ isUiOpen: {
26
+ includeInDebugSnapshot: true,
27
+ includeInStateLogs: true,
28
+ persist: false,
29
+ usedInUi: false,
30
+ },
31
+ };
32
+ // === MESSENGER ===
33
+ const MESSENGER_EXPOSED_METHODS = ['setUiOpen'];
34
+ /**
35
+ * `ClientController` manages the application lifecycle state.
36
+ *
37
+ * This controller tracks whether the MetaMask UI is open and publishes state
38
+ * change events that other controllers can subscribe to for adjusting their behavior.
39
+ *
40
+ * **Use cases:**
41
+ * - Polling controllers can pause when the UI closes, resume when it opens
42
+ * - WebSocket connections can disconnect when closed, reconnect when opened
43
+ * - Real-time subscriptions can pause when not visible
44
+ *
45
+ * **Platform Integration:**
46
+ * Platform code should call `ClientController:setUiOpen` via messenger.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * // In MetamaskController or platform code
51
+ * onUiOpened() {
52
+ * // ...
53
+ * this.controllerMessenger.call('ClientController:setUiOpen', true);
54
+ * }
55
+ *
56
+ * onUiClosed() {
57
+ * // ...
58
+ * this.controllerMessenger.call('ClientController:setUiOpen', false);
59
+ * }
60
+ *
61
+ * // Consumer controller subscribing to state changes
62
+ * class MyController extends BaseController {
63
+ * constructor({ messenger }) {
64
+ * super({ messenger, ... });
65
+ *
66
+ * messenger.subscribe(
67
+ * 'ClientController:stateChange',
68
+ * (isClientOpen) => {
69
+ * if (isClientOpen) {
70
+ * this.resumePolling();
71
+ * } else {
72
+ * this.pausePolling();
73
+ * }
74
+ * },
75
+ * clientControllerSelectors.selectIsUiOpen,
76
+ * );
77
+ * }
78
+ * }
79
+ * ```
80
+ */
81
+ class ClientController extends base_controller_1.BaseController {
82
+ /**
83
+ * Constructs a new {@link ClientController}.
84
+ *
85
+ * @param options - The constructor options.
86
+ * @param options.messenger - The messenger suited for this controller.
87
+ * @param options.state - The initial state to set on this controller.
88
+ */
89
+ constructor({ messenger, state = {} }) {
90
+ super({
91
+ messenger,
92
+ metadata: controllerMetadata,
93
+ name: exports.controllerName,
94
+ state: {
95
+ ...getDefaultClientControllerState(),
96
+ ...state,
97
+ },
98
+ });
99
+ this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
100
+ }
101
+ /**
102
+ * Updates state with whether the MetaMask UI is open.
103
+ *
104
+ * This method should be called when the user has opened the first window or
105
+ * screen containing the MetaMask UI, or closed the last window or screen
106
+ * containing the MetaMask UI.
107
+ *
108
+ * @param open - Whether the MetaMask UI is open.
109
+ */
110
+ setUiOpen(open) {
111
+ this.update((state) => {
112
+ state.isUiOpen = open;
113
+ });
114
+ }
115
+ }
116
+ exports.ClientController = ClientController;
117
+ //# sourceMappingURL=ClientController.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController.cjs","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":";;;AAKA,+DAA2D;AAK3D,kBAAkB;AAElB;;GAEG;AACU,QAAA,cAAc,GAAG,kBAAkB,CAAC;AAgBjD;;;;GAIG;AACH,SAAgB,+BAA+B;IAC7C,OAAO;QACL,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAJD,0EAIC;AAED;;GAEG;AACH,MAAM,kBAAkB,GAAG;IACzB,QAAQ,EAAE;QACR,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;CAC6C,CAAC;AAEjD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG,CAAC,WAAW,CAAU,CAAC;AAiEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAa,gBAAiB,SAAQ,gCAIrC;IACC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAA2B;QAC5D,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,sBAAc;YACpB,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAa;QACrB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA3CD,4CA2CC","sourcesContent":["import type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { ClientControllerMethodActions } from './ClientController-method-action-types.js';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link ClientController}.\n */\nexport const controllerName = 'ClientController';\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link ClientController}.\n */\nexport type ClientControllerState = {\n /**\n * Whether the user has opened at least one window or screen\n * containing the MetaMask UI. These windows or screens may or\n * may not be in an inactive state.\n */\n isUiOpen: boolean;\n};\n\n/**\n * Constructs the default {@link ClientController} state.\n *\n * @returns The default {@link ClientController} state.\n */\nexport function getDefaultClientControllerState(): ClientControllerState {\n return {\n isUiOpen: false,\n };\n}\n\n/**\n * The metadata for each property in {@link ClientControllerState}.\n */\nconst controllerMetadata = {\n isUiOpen: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<ClientControllerState>;\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = ['setUiOpen'] as const;\n\n/**\n * Retrieves the state of the {@link ClientController}.\n */\nexport type ClientControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Actions that {@link ClientController} exposes.\n */\nexport type ClientControllerActions =\n | ClientControllerGetStateAction\n | ClientControllerMethodActions;\n\n/**\n * Actions from other messengers that {@link ClientController} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when the state of {@link ClientController} changes.\n */\nexport type ClientControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Events that {@link ClientController} exposes.\n */\nexport type ClientControllerEvents = ClientControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link ClientController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger for {@link ClientController}.\n */\nexport type ClientControllerMessenger = Messenger<\n typeof controllerName,\n ClientControllerActions | AllowedActions,\n ClientControllerEvents | AllowedEvents\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * The options for constructing a {@link ClientController}.\n */\nexport type ClientControllerOptions = {\n /**\n * The messenger suited for this controller.\n */\n messenger: ClientControllerMessenger;\n /**\n * The initial state to set on this controller.\n */\n state?: Partial<ClientControllerState>;\n};\n\n/**\n * `ClientController` manages the application lifecycle state.\n *\n * This controller tracks whether the MetaMask UI is open and publishes state\n * change events that other controllers can subscribe to for adjusting their behavior.\n *\n * **Use cases:**\n * - Polling controllers can pause when the UI closes, resume when it opens\n * - WebSocket connections can disconnect when closed, reconnect when opened\n * - Real-time subscriptions can pause when not visible\n *\n * **Platform Integration:**\n * Platform code should call `ClientController:setUiOpen` via messenger.\n *\n * @example\n * ```typescript\n * // In MetamaskController or platform code\n * onUiOpened() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', true);\n * }\n *\n * onUiClosed() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', false);\n * }\n *\n * // Consumer controller subscribing to state changes\n * class MyController extends BaseController {\n * constructor({ messenger }) {\n * super({ messenger, ... });\n *\n * messenger.subscribe(\n * 'ClientController:stateChange',\n * (isClientOpen) => {\n * if (isClientOpen) {\n * this.resumePolling();\n * } else {\n * this.pausePolling();\n * }\n * },\n * clientControllerSelectors.selectIsUiOpen,\n * );\n * }\n * }\n * ```\n */\nexport class ClientController extends BaseController<\n typeof controllerName,\n ClientControllerState,\n ClientControllerMessenger\n> {\n /**\n * Constructs a new {@link ClientController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - The initial state to set on this controller.\n */\n constructor({ messenger, state = {} }: ClientControllerOptions) {\n super({\n messenger,\n metadata: controllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultClientControllerState(),\n ...state,\n },\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\n setUiOpen(open: boolean): void {\n this.update((state) => {\n state.isUiOpen = open;\n });\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
- import type { ControllerGetStateAction, ControllerStateChangeEvent } from '@metamask/base-controller';
2
- import { BaseController } from '@metamask/base-controller';
3
- import type { Messenger } from '@metamask/messenger';
4
- import type { ClientControllerMethodActions } from './ClientController-method-action-types.js';
1
+ import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
+ import { BaseController } from "@metamask/base-controller";
3
+ import type { Messenger } from "@metamask/messenger";
4
+ import type { ClientControllerMethodActions } from "./ClientController-method-action-types.cjs";
5
5
  /**
6
6
  * The name of the {@link ClientController}.
7
7
  */
@@ -132,4 +132,4 @@ export declare class ClientController extends BaseController<typeof controllerNa
132
132
  setUiOpen(open: boolean): void;
133
133
  }
134
134
  export {};
135
- //# sourceMappingURL=ClientController.d.ts.map
135
+ //# sourceMappingURL=ClientController.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController.d.cts","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAI/F;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAIjD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAIvE;AAkBD;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAEtE;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAIF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,SAAS,EAAE,yBAAyB,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;IACC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,KAAU,EAAE,EAAE,uBAAuB;IAiB9D;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAK/B"}
@@ -0,0 +1,135 @@
1
+ import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
2
+ import { BaseController } from "@metamask/base-controller";
3
+ import type { Messenger } from "@metamask/messenger";
4
+ import type { ClientControllerMethodActions } from "./ClientController-method-action-types.mjs";
5
+ /**
6
+ * The name of the {@link ClientController}.
7
+ */
8
+ export declare const controllerName = "ClientController";
9
+ /**
10
+ * Describes the shape of the state object for {@link ClientController}.
11
+ */
12
+ export type ClientControllerState = {
13
+ /**
14
+ * Whether the user has opened at least one window or screen
15
+ * containing the MetaMask UI. These windows or screens may or
16
+ * may not be in an inactive state.
17
+ */
18
+ isUiOpen: boolean;
19
+ };
20
+ /**
21
+ * Constructs the default {@link ClientController} state.
22
+ *
23
+ * @returns The default {@link ClientController} state.
24
+ */
25
+ export declare function getDefaultClientControllerState(): ClientControllerState;
26
+ /**
27
+ * Retrieves the state of the {@link ClientController}.
28
+ */
29
+ export type ClientControllerGetStateAction = ControllerGetStateAction<typeof controllerName, ClientControllerState>;
30
+ /**
31
+ * Actions that {@link ClientController} exposes.
32
+ */
33
+ export type ClientControllerActions = ClientControllerGetStateAction | ClientControllerMethodActions;
34
+ /**
35
+ * Actions from other messengers that {@link ClientController} calls.
36
+ */
37
+ type AllowedActions = never;
38
+ /**
39
+ * Published when the state of {@link ClientController} changes.
40
+ */
41
+ export type ClientControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, ClientControllerState>;
42
+ /**
43
+ * Events that {@link ClientController} exposes.
44
+ */
45
+ export type ClientControllerEvents = ClientControllerStateChangeEvent;
46
+ /**
47
+ * Events from other messengers that {@link ClientController} subscribes to.
48
+ */
49
+ type AllowedEvents = never;
50
+ /**
51
+ * The messenger for {@link ClientController}.
52
+ */
53
+ export type ClientControllerMessenger = Messenger<typeof controllerName, ClientControllerActions | AllowedActions, ClientControllerEvents | AllowedEvents>;
54
+ /**
55
+ * The options for constructing a {@link ClientController}.
56
+ */
57
+ export type ClientControllerOptions = {
58
+ /**
59
+ * The messenger suited for this controller.
60
+ */
61
+ messenger: ClientControllerMessenger;
62
+ /**
63
+ * The initial state to set on this controller.
64
+ */
65
+ state?: Partial<ClientControllerState>;
66
+ };
67
+ /**
68
+ * `ClientController` manages the application lifecycle state.
69
+ *
70
+ * This controller tracks whether the MetaMask UI is open and publishes state
71
+ * change events that other controllers can subscribe to for adjusting their behavior.
72
+ *
73
+ * **Use cases:**
74
+ * - Polling controllers can pause when the UI closes, resume when it opens
75
+ * - WebSocket connections can disconnect when closed, reconnect when opened
76
+ * - Real-time subscriptions can pause when not visible
77
+ *
78
+ * **Platform Integration:**
79
+ * Platform code should call `ClientController:setUiOpen` via messenger.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // In MetamaskController or platform code
84
+ * onUiOpened() {
85
+ * // ...
86
+ * this.controllerMessenger.call('ClientController:setUiOpen', true);
87
+ * }
88
+ *
89
+ * onUiClosed() {
90
+ * // ...
91
+ * this.controllerMessenger.call('ClientController:setUiOpen', false);
92
+ * }
93
+ *
94
+ * // Consumer controller subscribing to state changes
95
+ * class MyController extends BaseController {
96
+ * constructor({ messenger }) {
97
+ * super({ messenger, ... });
98
+ *
99
+ * messenger.subscribe(
100
+ * 'ClientController:stateChange',
101
+ * (isClientOpen) => {
102
+ * if (isClientOpen) {
103
+ * this.resumePolling();
104
+ * } else {
105
+ * this.pausePolling();
106
+ * }
107
+ * },
108
+ * clientControllerSelectors.selectIsUiOpen,
109
+ * );
110
+ * }
111
+ * }
112
+ * ```
113
+ */
114
+ export declare class ClientController extends BaseController<typeof controllerName, ClientControllerState, ClientControllerMessenger> {
115
+ /**
116
+ * Constructs a new {@link ClientController}.
117
+ *
118
+ * @param options - The constructor options.
119
+ * @param options.messenger - The messenger suited for this controller.
120
+ * @param options.state - The initial state to set on this controller.
121
+ */
122
+ constructor({ messenger, state }: ClientControllerOptions);
123
+ /**
124
+ * Updates state with whether the MetaMask UI is open.
125
+ *
126
+ * This method should be called when the user has opened the first window or
127
+ * screen containing the MetaMask UI, or closed the last window or screen
128
+ * containing the MetaMask UI.
129
+ *
130
+ * @param open - Whether the MetaMask UI is open.
131
+ */
132
+ setUiOpen(open: boolean): void;
133
+ }
134
+ export {};
135
+ //# sourceMappingURL=ClientController.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController.d.mts","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAErD,OAAO,KAAK,EAAE,6BAA6B,EAAE,mDAAkD;AAI/F;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAIjD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAIvE;AAkBD;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAEtE;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAIF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,SAAS,EAAE,yBAAyB,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;IACC;;;;;;OAMG;gBACS,EAAE,SAAS,EAAE,KAAU,EAAE,EAAE,uBAAuB;IAiB9D;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAK/B"}
@@ -1,4 +1,4 @@
1
- import { BaseController } from '@metamask/base-controller';
1
+ import { BaseController } from "@metamask/base-controller";
2
2
  // === GENERAL ===
3
3
  /**
4
4
  * The name of the {@link ClientController}.
@@ -109,4 +109,4 @@ export class ClientController extends BaseController {
109
109
  });
110
110
  }
111
111
  }
112
- //# sourceMappingURL=ClientController.js.map
112
+ //# sourceMappingURL=ClientController.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientController.mjs","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAK3D,kBAAkB;AAElB;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAgBjD;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,kBAAkB,GAAG;IACzB,QAAQ,EAAE;QACR,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;CAC6C,CAAC;AAEjD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG,CAAC,WAAW,CAAU,CAAC;AAiEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAIrC;IACC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAA2B;QAC5D,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAa;QACrB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { ClientControllerMethodActions } from './ClientController-method-action-types.js';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link ClientController}.\n */\nexport const controllerName = 'ClientController';\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link ClientController}.\n */\nexport type ClientControllerState = {\n /**\n * Whether the user has opened at least one window or screen\n * containing the MetaMask UI. These windows or screens may or\n * may not be in an inactive state.\n */\n isUiOpen: boolean;\n};\n\n/**\n * Constructs the default {@link ClientController} state.\n *\n * @returns The default {@link ClientController} state.\n */\nexport function getDefaultClientControllerState(): ClientControllerState {\n return {\n isUiOpen: false,\n };\n}\n\n/**\n * The metadata for each property in {@link ClientControllerState}.\n */\nconst controllerMetadata = {\n isUiOpen: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<ClientControllerState>;\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = ['setUiOpen'] as const;\n\n/**\n * Retrieves the state of the {@link ClientController}.\n */\nexport type ClientControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Actions that {@link ClientController} exposes.\n */\nexport type ClientControllerActions =\n | ClientControllerGetStateAction\n | ClientControllerMethodActions;\n\n/**\n * Actions from other messengers that {@link ClientController} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when the state of {@link ClientController} changes.\n */\nexport type ClientControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Events that {@link ClientController} exposes.\n */\nexport type ClientControllerEvents = ClientControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link ClientController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger for {@link ClientController}.\n */\nexport type ClientControllerMessenger = Messenger<\n typeof controllerName,\n ClientControllerActions | AllowedActions,\n ClientControllerEvents | AllowedEvents\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * The options for constructing a {@link ClientController}.\n */\nexport type ClientControllerOptions = {\n /**\n * The messenger suited for this controller.\n */\n messenger: ClientControllerMessenger;\n /**\n * The initial state to set on this controller.\n */\n state?: Partial<ClientControllerState>;\n};\n\n/**\n * `ClientController` manages the application lifecycle state.\n *\n * This controller tracks whether the MetaMask UI is open and publishes state\n * change events that other controllers can subscribe to for adjusting their behavior.\n *\n * **Use cases:**\n * - Polling controllers can pause when the UI closes, resume when it opens\n * - WebSocket connections can disconnect when closed, reconnect when opened\n * - Real-time subscriptions can pause when not visible\n *\n * **Platform Integration:**\n * Platform code should call `ClientController:setUiOpen` via messenger.\n *\n * @example\n * ```typescript\n * // In MetamaskController or platform code\n * onUiOpened() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', true);\n * }\n *\n * onUiClosed() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', false);\n * }\n *\n * // Consumer controller subscribing to state changes\n * class MyController extends BaseController {\n * constructor({ messenger }) {\n * super({ messenger, ... });\n *\n * messenger.subscribe(\n * 'ClientController:stateChange',\n * (isClientOpen) => {\n * if (isClientOpen) {\n * this.resumePolling();\n * } else {\n * this.pausePolling();\n * }\n * },\n * clientControllerSelectors.selectIsUiOpen,\n * );\n * }\n * }\n * ```\n */\nexport class ClientController extends BaseController<\n typeof controllerName,\n ClientControllerState,\n ClientControllerMessenger\n> {\n /**\n * Constructs a new {@link ClientController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - The initial state to set on this controller.\n */\n constructor({ messenger, state = {} }: ClientControllerOptions) {\n super({\n messenger,\n metadata: controllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultClientControllerState(),\n ...state,\n },\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\n setUiOpen(open: boolean): void {\n this.update((state) => {\n state.isUiOpen = open;\n });\n }\n}\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clientControllerSelectors = exports.getDefaultClientControllerState = exports.ClientController = void 0;
4
+ var ClientController_js_1 = require("./ClientController.cjs");
5
+ Object.defineProperty(exports, "ClientController", { enumerable: true, get: function () { return ClientController_js_1.ClientController; } });
6
+ Object.defineProperty(exports, "getDefaultClientControllerState", { enumerable: true, get: function () { return ClientController_js_1.getDefaultClientControllerState; } });
7
+ var selectors_js_1 = require("./selectors.cjs");
8
+ Object.defineProperty(exports, "clientControllerSelectors", { enumerable: true, get: function () { return selectors_js_1.clientControllerSelectors; } });
9
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8DAG+B;AAF7B,uHAAA,gBAAgB,OAAA;AAChB,sIAAA,+BAA+B,OAAA;AAEjC,gDAA2D;AAAlD,yHAAA,yBAAyB,OAAA","sourcesContent":["export {\n ClientController,\n getDefaultClientControllerState,\n} from './ClientController.js';\nexport { clientControllerSelectors } from './selectors.js';\n\nexport type {\n ClientControllerState,\n ClientControllerOptions,\n ClientControllerGetStateAction,\n ClientControllerActions,\n ClientControllerStateChangeEvent,\n ClientControllerEvents,\n ClientControllerMessenger,\n} from './ClientController.js';\nexport type { ClientControllerSetUiOpenAction } from './ClientController-method-action-types.js';\n"]}
@@ -0,0 +1,5 @@
1
+ export { ClientController, getDefaultClientControllerState, } from "./ClientController.cjs";
2
+ export { clientControllerSelectors } from "./selectors.cjs";
3
+ export type { ClientControllerState, ClientControllerOptions, ClientControllerGetStateAction, ClientControllerActions, ClientControllerStateChangeEvent, ClientControllerEvents, ClientControllerMessenger, } from "./ClientController.cjs";
4
+ export type { ClientControllerSetUiOpenAction } from "./ClientController-method-action-types.cjs";
5
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA8B;AAC/B,OAAO,EAAE,yBAAyB,EAAE,wBAAuB;AAE3D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,sBAAsB,EACtB,yBAAyB,GAC1B,+BAA8B;AAC/B,YAAY,EAAE,+BAA+B,EAAE,mDAAkD"}
@@ -0,0 +1,5 @@
1
+ export { ClientController, getDefaultClientControllerState, } from "./ClientController.mjs";
2
+ export { clientControllerSelectors } from "./selectors.mjs";
3
+ export type { ClientControllerState, ClientControllerOptions, ClientControllerGetStateAction, ClientControllerActions, ClientControllerStateChangeEvent, ClientControllerEvents, ClientControllerMessenger, } from "./ClientController.mjs";
4
+ export type { ClientControllerSetUiOpenAction } from "./ClientController-method-action-types.mjs";
5
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,+BAA8B;AAC/B,OAAO,EAAE,yBAAyB,EAAE,wBAAuB;AAE3D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,sBAAsB,EACtB,yBAAyB,GAC1B,+BAA8B;AAC/B,YAAY,EAAE,+BAA+B,EAAE,mDAAkD"}
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ export { ClientController, getDefaultClientControllerState } from "./ClientController.mjs";
2
+ export { clientControllerSelectors } from "./selectors.mjs";
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,EAChC,+BAA8B;AAC/B,OAAO,EAAE,yBAAyB,EAAE,wBAAuB","sourcesContent":["export {\n ClientController,\n getDefaultClientControllerState,\n} from './ClientController.js';\nexport { clientControllerSelectors } from './selectors.js';\n\nexport type {\n ClientControllerState,\n ClientControllerOptions,\n ClientControllerGetStateAction,\n ClientControllerActions,\n ClientControllerStateChangeEvent,\n ClientControllerEvents,\n ClientControllerMessenger,\n} from './ClientController.js';\nexport type { ClientControllerSetUiOpenAction } from './ClientController-method-action-types.js';\n"]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clientControllerSelectors = void 0;
4
+ /**
5
+ * Selects whether the UI is currently open.
6
+ *
7
+ * @param state - The ClientController state.
8
+ * @returns True if the UI is open.
9
+ */
10
+ const selectIsUiOpen = (state) => state.isUiOpen;
11
+ /**
12
+ * Selectors for the ClientController state.
13
+ * These can be used with Redux or directly with controller state.
14
+ */
15
+ exports.clientControllerSelectors = {
16
+ selectIsUiOpen,
17
+ };
18
+ //# sourceMappingURL=selectors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.cjs","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,KAA4B,EAAW,EAAE,CAC/D,KAAK,CAAC,QAAQ,CAAC;AAEjB;;;GAGG;AACU,QAAA,yBAAyB,GAAG;IACvC,cAAc;CACf,CAAC","sourcesContent":["import type { ClientControllerState } from './ClientController.js';\n\n/**\n * Selects whether the UI is currently open.\n *\n * @param state - The ClientController state.\n * @returns True if the UI is open.\n */\nconst selectIsUiOpen = (state: ClientControllerState): boolean =>\n state.isUiOpen;\n\n/**\n * Selectors for the ClientController state.\n * These can be used with Redux or directly with controller state.\n */\nexport const clientControllerSelectors = {\n selectIsUiOpen,\n};\n"]}
@@ -0,0 +1,9 @@
1
+ import type { ClientControllerState } from "./ClientController.cjs";
2
+ /**
3
+ * Selectors for the ClientController state.
4
+ * These can be used with Redux or directly with controller state.
5
+ */
6
+ export declare const clientControllerSelectors: {
7
+ selectIsUiOpen: (state: ClientControllerState) => boolean;
8
+ };
9
+ //# sourceMappingURL=selectors.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.d.cts","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,+BAA8B;AAWnE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;4BAPP,qBAAqB,KAAG,OAAO;CAS7D,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ClientControllerState } from "./ClientController.mjs";
2
+ /**
3
+ * Selectors for the ClientController state.
4
+ * These can be used with Redux or directly with controller state.
5
+ */
6
+ export declare const clientControllerSelectors: {
7
+ selectIsUiOpen: (state: ClientControllerState) => boolean;
8
+ };
9
+ //# sourceMappingURL=selectors.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.d.mts","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,+BAA8B;AAWnE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;4BAPP,qBAAqB,KAAG,OAAO;CAS7D,CAAC"}
@@ -12,4 +12,4 @@ const selectIsUiOpen = (state) => state.isUiOpen;
12
12
  export const clientControllerSelectors = {
13
13
  selectIsUiOpen,
14
14
  };
15
- //# sourceMappingURL=selectors.js.map
15
+ //# sourceMappingURL=selectors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.mjs","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,KAA4B,EAAW,EAAE,CAC/D,KAAK,CAAC,QAAQ,CAAC;AAEjB;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,cAAc;CACf,CAAC","sourcesContent":["import type { ClientControllerState } from './ClientController.js';\n\n/**\n * Selects whether the UI is currently open.\n *\n * @param state - The ClientController state.\n * @returns True if the UI is open.\n */\nconst selectIsUiOpen = (state: ClientControllerState): boolean =>\n state.isUiOpen;\n\n/**\n * Selectors for the ClientController state.\n * These can be used with Redux or directly with controller state.\n */\nexport const clientControllerSelectors = {\n selectIsUiOpen,\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/client-controller",
3
- "version": "1.0.1-preview-3866c0ff1",
3
+ "version": "1.0.1-preview-e3275932a",
4
4
  "description": "Client-level state for MetaMask (e.g. whether a UI window is open)",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -18,12 +18,19 @@
18
18
  "files": [
19
19
  "dist/"
20
20
  ],
21
- "type": "module",
22
21
  "sideEffects": false,
22
+ "main": "./dist/index.cjs",
23
+ "types": "./dist/index.d.cts",
23
24
  "exports": {
24
25
  ".": {
25
- "types": "./dist/index.d.ts",
26
- "default": "./dist/index.js"
26
+ "import": {
27
+ "types": "./dist/index.d.mts",
28
+ "default": "./dist/index.mjs"
29
+ },
30
+ "require": {
31
+ "types": "./dist/index.d.cts",
32
+ "default": "./dist/index.cjs"
33
+ }
27
34
  },
28
35
  "./package.json": "./package.json"
29
36
  },
@@ -32,11 +39,9 @@
32
39
  "registry": "https://registry.npmjs.org/"
33
40
  },
34
41
  "scripts": {
35
- "build": "tsc --project tsconfig.build.json",
36
- "build:all": "tsc --build tsconfig.build.json --verbose",
37
- "build:clean": "yarn build:only-clean && yarn build",
42
+ "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
43
+ "build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
38
44
  "build:docs": "typedoc",
39
- "build:only-clean": "rimraf './dist' './tsconfig.build.tsbuildinfo'",
40
45
  "changelog:update": "../../scripts/update-changelog.sh @metamask/client-controller",
41
46
  "changelog:validate": "../../scripts/validate-changelog.sh @metamask/client-controller",
42
47
  "lint:tsconfigs": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts",
@@ -55,19 +60,18 @@
55
60
  },
56
61
  "devDependencies": {
57
62
  "@metamask/auto-changelog": "^6.1.0",
63
+ "@ts-bridge/cli": "^0.6.4",
58
64
  "@types/jest": "^30.0.0",
59
- "@typescript/native": "npm:typescript@^7.0.2",
60
65
  "deepmerge": "^4.2.2",
61
66
  "jest": "^30.4.2",
62
67
  "jest-environment-jsdom": "^30.4.1",
63
- "rimraf": "^5.0.5",
64
68
  "ts-jest": "^29.4.11",
65
69
  "tsx": "^4.20.5",
66
70
  "typedoc": "^0.25.13",
67
71
  "typedoc-plugin-missing-exports": "^2.0.0",
68
- "typescript": "npm:@typescript/typescript6@^6.0.2"
72
+ "typescript": "~5.3.3"
69
73
  },
70
74
  "engines": {
71
- "node": "^22.14.0 || ^24"
75
+ "node": "^18.18 || >=20"
72
76
  }
73
77
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClientController-method-action-types.d.ts","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,+BAA+B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClientController-method-action-types.js","sourceRoot":"","sources":["../src/ClientController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ClientController } from './ClientController.js';\n\n/**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\nexport type ClientControllerSetUiOpenAction = {\n type: `ClientController:setUiOpen`;\n handler: ClientController['setUiOpen'];\n};\n\n/**\n * Union of all ClientController action types.\n */\nexport type ClientControllerMethodActions = ClientControllerSetUiOpenAction;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClientController.d.ts","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAC;AAI/F;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAIjD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,qBAAqB,CAIvE;AAkBD;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,wBAAwB,CACnE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B,8BAA8B,GAC9B,6BAA6B,CAAC;AAElC;;GAEG;AACH,KAAK,cAAc,GAAG,KAAK,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,gCAAgC,GAAG,0BAA0B,CACvE,OAAO,cAAc,EACrB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAEtE;;GAEG;AACH,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAC/C,OAAO,cAAc,EACrB,uBAAuB,GAAG,cAAc,EACxC,sBAAsB,GAAG,aAAa,CACvC,CAAC;AAIF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,SAAS,EAAE,yBAAyB,CAAC;IACrC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,gBAAiB,SAAQ,cAAc,CAClD,OAAO,cAAc,EACrB,qBAAqB,EACrB,yBAAyB,CAC1B;IACC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAE,KAAU,EAAE,EAAE,uBAAuB,EAe7D;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAI7B;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClientController.js","sourceRoot":"","sources":["../src/ClientController.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAK3D,kBAAkB;AAElB;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAgBjD;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,kBAAkB,GAAG;IACzB,QAAQ,EAAE;QACR,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;CAC6C,CAAC;AAEjD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG,CAAC,WAAW,CAAU,CAAC;AAiEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAIrC;IACC;;;;;;OAMG;IACH,YAAY,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAA2B;QAC5D,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,IAAa;QACrB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type { ClientControllerMethodActions } from './ClientController-method-action-types.js';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link ClientController}.\n */\nexport const controllerName = 'ClientController';\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link ClientController}.\n */\nexport type ClientControllerState = {\n /**\n * Whether the user has opened at least one window or screen\n * containing the MetaMask UI. These windows or screens may or\n * may not be in an inactive state.\n */\n isUiOpen: boolean;\n};\n\n/**\n * Constructs the default {@link ClientController} state.\n *\n * @returns The default {@link ClientController} state.\n */\nexport function getDefaultClientControllerState(): ClientControllerState {\n return {\n isUiOpen: false,\n };\n}\n\n/**\n * The metadata for each property in {@link ClientControllerState}.\n */\nconst controllerMetadata = {\n isUiOpen: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<ClientControllerState>;\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = ['setUiOpen'] as const;\n\n/**\n * Retrieves the state of the {@link ClientController}.\n */\nexport type ClientControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Actions that {@link ClientController} exposes.\n */\nexport type ClientControllerActions =\n | ClientControllerGetStateAction\n | ClientControllerMethodActions;\n\n/**\n * Actions from other messengers that {@link ClientController} calls.\n */\ntype AllowedActions = never;\n\n/**\n * Published when the state of {@link ClientController} changes.\n */\nexport type ClientControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n ClientControllerState\n>;\n\n/**\n * Events that {@link ClientController} exposes.\n */\nexport type ClientControllerEvents = ClientControllerStateChangeEvent;\n\n/**\n * Events from other messengers that {@link ClientController} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger for {@link ClientController}.\n */\nexport type ClientControllerMessenger = Messenger<\n typeof controllerName,\n ClientControllerActions | AllowedActions,\n ClientControllerEvents | AllowedEvents\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * The options for constructing a {@link ClientController}.\n */\nexport type ClientControllerOptions = {\n /**\n * The messenger suited for this controller.\n */\n messenger: ClientControllerMessenger;\n /**\n * The initial state to set on this controller.\n */\n state?: Partial<ClientControllerState>;\n};\n\n/**\n * `ClientController` manages the application lifecycle state.\n *\n * This controller tracks whether the MetaMask UI is open and publishes state\n * change events that other controllers can subscribe to for adjusting their behavior.\n *\n * **Use cases:**\n * - Polling controllers can pause when the UI closes, resume when it opens\n * - WebSocket connections can disconnect when closed, reconnect when opened\n * - Real-time subscriptions can pause when not visible\n *\n * **Platform Integration:**\n * Platform code should call `ClientController:setUiOpen` via messenger.\n *\n * @example\n * ```typescript\n * // In MetamaskController or platform code\n * onUiOpened() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', true);\n * }\n *\n * onUiClosed() {\n * // ...\n * this.controllerMessenger.call('ClientController:setUiOpen', false);\n * }\n *\n * // Consumer controller subscribing to state changes\n * class MyController extends BaseController {\n * constructor({ messenger }) {\n * super({ messenger, ... });\n *\n * messenger.subscribe(\n * 'ClientController:stateChange',\n * (isClientOpen) => {\n * if (isClientOpen) {\n * this.resumePolling();\n * } else {\n * this.pausePolling();\n * }\n * },\n * clientControllerSelectors.selectIsUiOpen,\n * );\n * }\n * }\n * ```\n */\nexport class ClientController extends BaseController<\n typeof controllerName,\n ClientControllerState,\n ClientControllerMessenger\n> {\n /**\n * Constructs a new {@link ClientController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - The initial state to set on this controller.\n */\n constructor({ messenger, state = {} }: ClientControllerOptions) {\n super({\n messenger,\n metadata: controllerMetadata,\n name: controllerName,\n state: {\n ...getDefaultClientControllerState(),\n ...state,\n },\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Updates state with whether the MetaMask UI is open.\n *\n * This method should be called when the user has opened the first window or\n * screen containing the MetaMask UI, or closed the last window or screen\n * containing the MetaMask UI.\n *\n * @param open - Whether the MetaMask UI is open.\n */\n setUiOpen(open: boolean): void {\n this.update((state) => {\n state.isUiOpen = open;\n });\n }\n}\n"]}
package/dist/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export { ClientController, getDefaultClientControllerState, } from './ClientController.js';
2
- export { clientControllerSelectors } from './selectors.js';
3
- export type { ClientControllerState, ClientControllerOptions, ClientControllerGetStateAction, ClientControllerActions, ClientControllerStateChangeEvent, ClientControllerEvents, ClientControllerMessenger, } from './ClientController.js';
4
- export type { ClientControllerSetUiOpenAction } from './ClientController-method-action-types.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,gCAAgC,EAChC,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,+BAA+B,EAAE,MAAM,2CAA2C,CAAC"}
package/dist/index.js DELETED
@@ -1,3 +0,0 @@
1
- export { ClientController, getDefaultClientControllerState, } from './ClientController.js';
2
- export { clientControllerSelectors } from './selectors.js';
3
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export {\n ClientController,\n getDefaultClientControllerState,\n} from './ClientController.js';\nexport { clientControllerSelectors } from './selectors.js';\n\nexport type {\n ClientControllerState,\n ClientControllerOptions,\n ClientControllerGetStateAction,\n ClientControllerActions,\n ClientControllerStateChangeEvent,\n ClientControllerEvents,\n ClientControllerMessenger,\n} from './ClientController.js';\nexport type { ClientControllerSetUiOpenAction } from './ClientController-method-action-types.js';\n"]}
@@ -1,17 +0,0 @@
1
- import type { ClientControllerState } from './ClientController.js';
2
- /**
3
- * Selects whether the UI is currently open.
4
- *
5
- * @param state - The ClientController state.
6
- * @returns True if the UI is open.
7
- */
8
- declare const selectIsUiOpen: (state: ClientControllerState) => boolean;
9
- /**
10
- * Selectors for the ClientController state.
11
- * These can be used with Redux or directly with controller state.
12
- */
13
- export declare const clientControllerSelectors: {
14
- selectIsUiOpen: typeof selectIsUiOpen;
15
- };
16
- export {};
17
- //# sourceMappingURL=selectors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE;;;;;GAKG;AACH,QAAA,MAAM,cAAc,UAAW,qBAAqB,KAAG,OACvC,CAAC;AAEjB;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;CAErC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,KAA4B,EAAW,EAAE,CAC/D,KAAK,CAAC,QAAQ,CAAC;AAEjB;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,cAAc;CACf,CAAC","sourcesContent":["import type { ClientControllerState } from './ClientController.js';\n\n/**\n * Selects whether the UI is currently open.\n *\n * @param state - The ClientController state.\n * @returns True if the UI is open.\n */\nconst selectIsUiOpen = (state: ClientControllerState): boolean =>\n state.isUiOpen;\n\n/**\n * Selectors for the ClientController state.\n * These can be used with Redux or directly with controller state.\n */\nexport const clientControllerSelectors = {\n selectIsUiOpen,\n};\n"]}