@rimori/client 2.3.0-next.7 → 2.3.0-next.9

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.
package/README.md CHANGED
@@ -155,7 +155,7 @@ Use `client.runtime.fetchBackend` for authenticated calls to Rimori-managed HTTP
155
155
  - `on(topic, handler)` / `once(topic, handler)` / `respond(topic, handler)` – subscribe and reply (each call returns an object with `off()` for cleanup).
156
156
  - `emitAccomplishment(payload)` / `onAccomplishment(topic, handler)` – report learning milestones.
157
157
  - `emitSidebarAction(pluginId, actionKey, text?)` – trigger sidebar plugins.
158
- - `onMainPanelAction(handler, actionsToListen?)` – react to dashboard actions.
158
+ - `onMainPanelAction(handler, actionsToListen?)` – react to dashboard actions. Returns an `EventListener` with an `off()` method. **Important:** Call `listener.off()` when your component unmounts or when you no longer need to listen, especially to prevent the event from firing again when navigating away from or returning to the page.
159
159
  - `client.navigation.toDashboard()` – navigate the user back to Rimori.
160
160
 
161
161
  ### Community Content
@@ -29,11 +29,12 @@ export class AccomplishmentController {
29
29
  if (!['micro', 'macro'].includes(payload.type)) {
30
30
  throw new Error('Invalid accomplishment type ' + payload.type);
31
31
  }
32
+ // disabled detection temporarelly to determine how long exercises normally are
32
33
  //durationMinutes is required
33
- if (payload.type === 'macro' && payload.durationMinutes < 4) {
34
- console.warn('The duration must be at least 4 minutes');
35
- return false;
36
- }
34
+ // if (payload.type === 'macro' && payload.durationMinutes < 4) {
35
+ // console.warn('The duration must be at least 4 minutes');
36
+ // return false;
37
+ // }
37
38
  //errorRatio is required
38
39
  if (payload.type === 'macro' && (payload.errorRatio < 0 || payload.errorRatio > 1)) {
39
40
  throw new Error('The error ratio must be between 0 and 1');
@@ -143,6 +143,29 @@ export declare class RimoriClient {
143
143
  * @param text Optional text to be used for the action like for example text that the translator would look up.
144
144
  */
145
145
  emitSidebarAction: (pluginId: string, actionKey: string, text?: string) => void;
146
+ /**
147
+ * Subscribe to main panel actions triggered by the user from the dashboard.
148
+ * @param callback Handler function that receives the action data when a matching action is triggered.
149
+ * @param actionsToListen Optional filter to listen only to specific action keys. If empty or not provided, all actions will trigger the callback.
150
+ * @returns An EventListener object with an `off()` method for cleanup.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * const listener = client.event.onMainPanelAction((data) => {
155
+ * console.log('Action received:', data.action_key);
156
+ * }, ['startSession', 'pauseSession']);
157
+ *
158
+ * // Clean up when component unmounts to prevent events from firing
159
+ * // when navigating away or returning to the page
160
+ * useEffect(() => {
161
+ * return () => listener.off();
162
+ * }, []);
163
+ * ```
164
+ *
165
+ * **Important:** Always call `listener.off()` when your component unmounts or when you no longer need to listen.
166
+ * This prevents the event handler from firing when navigating away from or returning to the page, which could
167
+ * cause unexpected behavior or duplicate event handling.
168
+ */
146
169
  onMainPanelAction: (callback: (data: MainPanelAction) => void, actionsToListen?: string | string[]) => EventListener;
147
170
  onSidePanelAction: (callback: (data: MainPanelAction) => void, actionsToListen?: string | string[]) => EventListener;
148
171
  };
@@ -96,6 +96,29 @@ export class RimoriClient {
96
96
  emitSidebarAction: (pluginId, actionKey, text) => {
97
97
  this.event.emit('global.sidebar.triggerAction', { plugin_id: pluginId, action_key: actionKey, text });
98
98
  },
99
+ /**
100
+ * Subscribe to main panel actions triggered by the user from the dashboard.
101
+ * @param callback Handler function that receives the action data when a matching action is triggered.
102
+ * @param actionsToListen Optional filter to listen only to specific action keys. If empty or not provided, all actions will trigger the callback.
103
+ * @returns An EventListener object with an `off()` method for cleanup.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const listener = client.event.onMainPanelAction((data) => {
108
+ * console.log('Action received:', data.action_key);
109
+ * }, ['startSession', 'pauseSession']);
110
+ *
111
+ * // Clean up when component unmounts to prevent events from firing
112
+ * // when navigating away or returning to the page
113
+ * useEffect(() => {
114
+ * return () => listener.off();
115
+ * }, []);
116
+ * ```
117
+ *
118
+ * **Important:** Always call `listener.off()` when your component unmounts or when you no longer need to listen.
119
+ * This prevents the event handler from firing when navigating away from or returning to the page, which could
120
+ * cause unexpected behavior or duplicate event handling.
121
+ */
99
122
  onMainPanelAction: (callback, actionsToListen = []) => {
100
123
  const listeningActions = Array.isArray(actionsToListen) ? actionsToListen : [actionsToListen];
101
124
  // this needs to be a emit and on because the main panel action is triggered by the user and not by the plugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/client",
3
- "version": "2.3.0-next.7",
3
+ "version": "2.3.0-next.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {
@@ -82,11 +82,12 @@ export class AccomplishmentController {
82
82
  throw new Error('Invalid accomplishment type ' + payload.type);
83
83
  }
84
84
 
85
+ // disabled detection temporarelly to determine how long exercises normally are
85
86
  //durationMinutes is required
86
- if (payload.type === 'macro' && payload.durationMinutes < 4) {
87
- console.warn('The duration must be at least 4 minutes');
88
- return false;
89
- }
87
+ // if (payload.type === 'macro' && payload.durationMinutes < 4) {
88
+ // console.warn('The duration must be at least 4 minutes');
89
+ // return false;
90
+ // }
90
91
 
91
92
  //errorRatio is required
92
93
  if (payload.type === 'macro' && (payload.errorRatio < 0 || payload.errorRatio > 1)) {
@@ -260,6 +260,29 @@ export class RimoriClient {
260
260
  this.event.emit('global.sidebar.triggerAction', { plugin_id: pluginId, action_key: actionKey, text });
261
261
  },
262
262
 
263
+ /**
264
+ * Subscribe to main panel actions triggered by the user from the dashboard.
265
+ * @param callback Handler function that receives the action data when a matching action is triggered.
266
+ * @param actionsToListen Optional filter to listen only to specific action keys. If empty or not provided, all actions will trigger the callback.
267
+ * @returns An EventListener object with an `off()` method for cleanup.
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * const listener = client.event.onMainPanelAction((data) => {
272
+ * console.log('Action received:', data.action_key);
273
+ * }, ['startSession', 'pauseSession']);
274
+ *
275
+ * // Clean up when component unmounts to prevent events from firing
276
+ * // when navigating away or returning to the page
277
+ * useEffect(() => {
278
+ * return () => listener.off();
279
+ * }, []);
280
+ * ```
281
+ *
282
+ * **Important:** Always call `listener.off()` when your component unmounts or when you no longer need to listen.
283
+ * This prevents the event handler from firing when navigating away from or returning to the page, which could
284
+ * cause unexpected behavior or duplicate event handling.
285
+ */
263
286
  onMainPanelAction: (
264
287
  callback: (data: MainPanelAction) => void,
265
288
  actionsToListen: string | string[] = [],