@rimori/client 2.4.0-next.3 → 2.4.0-next.4

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.
@@ -47,6 +47,7 @@ export declare class RimoriCommunicationHandler {
47
47
  private pluginId;
48
48
  private isMessageChannelReady;
49
49
  private pendingRequests;
50
+ private updateCallbacks;
50
51
  constructor(pluginId: string, standalone: boolean);
51
52
  private initMessageChannel;
52
53
  private sendHello;
@@ -65,4 +66,15 @@ export declare class RimoriCommunicationHandler {
65
66
  getSupabaseUrl(): string;
66
67
  getBackendUrl(): string;
67
68
  getGlobalEventTopic(preliminaryTopic: string): string;
69
+ /**
70
+ * Handles updates to RimoriInfo from rimori-main.
71
+ * Updates the cached info and Supabase client, then notifies all registered callbacks.
72
+ */
73
+ private handleRimoriInfoUpdate;
74
+ /**
75
+ * Registers a callback to be called when RimoriInfo is updated.
76
+ * @param callback - Function to call with the new RimoriInfo
77
+ * @returns Cleanup function to unregister the callback
78
+ */
79
+ onUpdate(callback: (info: RimoriInfo) => void): () => void;
68
80
  }
@@ -17,6 +17,7 @@ export class RimoriCommunicationHandler {
17
17
  this.rimoriInfo = null;
18
18
  this.isMessageChannelReady = false;
19
19
  this.pendingRequests = [];
20
+ this.updateCallbacks = new Set();
20
21
  this.pluginId = pluginId;
21
22
  this.getClient = this.getClient.bind(this);
22
23
  //no need to forward messages to parent in standalone mode or worker context
@@ -78,6 +79,12 @@ export class RimoriCommunicationHandler {
78
79
  (_a = this.port) === null || _a === void 0 ? void 0 : _a.postMessage({ event: ev });
79
80
  }
80
81
  });
82
+ // Listen for updates from rimori-main (data changes, token refresh, etc.)
83
+ // Topic format: {pluginId}.supabase.triggerUpdate
84
+ EventBus.on(`${this.pluginId}.supabase.triggerUpdate`, (ev) => {
85
+ console.log('[RimoriCommunicationHandler] Received update from rimori-main');
86
+ this.handleRimoriInfoUpdate(ev.data);
87
+ });
81
88
  // Mark MessageChannel as ready and process pending requests
82
89
  this.isMessageChannelReady = true;
83
90
  // Process any pending requests
@@ -250,4 +257,36 @@ export class RimoriCommunicationHandler {
250
257
  const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : 'global';
251
258
  return `${topicRoot}.${preliminaryTopic}`;
252
259
  }
260
+ /**
261
+ * Handles updates to RimoriInfo from rimori-main.
262
+ * Updates the cached info and Supabase client, then notifies all registered callbacks.
263
+ */
264
+ handleRimoriInfoUpdate(newInfo) {
265
+ // Update cached rimoriInfo
266
+ this.rimoriInfo = newInfo;
267
+ // Update Supabase client with new token
268
+ this.supabase = createClient(newInfo.url, newInfo.key, {
269
+ accessToken: () => Promise.resolve(newInfo.token),
270
+ });
271
+ // Notify all registered callbacks
272
+ this.updateCallbacks.forEach((callback) => {
273
+ try {
274
+ callback(newInfo);
275
+ }
276
+ catch (error) {
277
+ console.error('[RimoriCommunicationHandler] Error in update callback:', error);
278
+ }
279
+ });
280
+ }
281
+ /**
282
+ * Registers a callback to be called when RimoriInfo is updated.
283
+ * @param callback - Function to call with the new RimoriInfo
284
+ * @returns Cleanup function to unregister the callback
285
+ */
286
+ onUpdate(callback) {
287
+ this.updateCallbacks.add(callback);
288
+ return () => {
289
+ this.updateCallbacks.delete(callback);
290
+ };
291
+ }
253
292
  }
@@ -8,6 +8,7 @@ import { CreateExerciseParams } from '../controller/ExerciseController';
8
8
  import { EventBusMessage, EventHandler, EventPayload, EventListener } from '../fromRimori/EventBus';
9
9
  import { ActivePlugin, MainPanelAction, Plugin, Tool } from '../fromRimori/PluginTypes';
10
10
  import { AccomplishmentPayload } from '../controller/AccomplishmentController';
11
+ import { RimoriInfo } from './CommunicationHandler';
11
12
  import { Translator } from '../controller/TranslationController';
12
13
  export declare class RimoriClient {
13
14
  private static instance;
@@ -39,7 +40,19 @@ export declare class RimoriClient {
39
40
  * @returns The settings for the plugin.
40
41
  */
41
42
  getSettings: <T extends object>(defaultSettings: T) => Promise<T>;
43
+ /**
44
+ * Get the current user info.
45
+ * Note: For reactive updates in React components, use the userInfo from useRimori() hook instead.
46
+ * @returns The user info.
47
+ */
42
48
  getUserInfo: () => UserInfo;
49
+ /**
50
+ * Register a callback to be notified when RimoriInfo is updated.
51
+ * This is useful for reacting to changes in user info, tokens, or other rimori data.
52
+ * @param callback - Function to call with the new RimoriInfo
53
+ * @returns Cleanup function to unregister the callback
54
+ */
55
+ onRimoriInfoUpdate: (callback: (info: RimoriInfo) => void) => (() => void);
43
56
  /**
44
57
  * Retrieves information about plugins, including:
45
58
  * - All installed plugins
@@ -333,9 +333,23 @@ export class RimoriClient {
333
333
  getSettings: (defaultSettings) => __awaiter(this, void 0, void 0, function* () {
334
334
  return yield this.settingsController.getSettings(defaultSettings);
335
335
  }),
336
+ /**
337
+ * Get the current user info.
338
+ * Note: For reactive updates in React components, use the userInfo from useRimori() hook instead.
339
+ * @returns The user info.
340
+ */
336
341
  getUserInfo: () => {
337
342
  return this.rimoriInfo.profile;
338
343
  },
344
+ /**
345
+ * Register a callback to be notified when RimoriInfo is updated.
346
+ * This is useful for reacting to changes in user info, tokens, or other rimori data.
347
+ * @param callback - Function to call with the new RimoriInfo
348
+ * @returns Cleanup function to unregister the callback
349
+ */
350
+ onRimoriInfoUpdate: (callback) => {
351
+ return this.pluginController.onUpdate(callback);
352
+ },
339
353
  /**
340
354
  * Retrieves information about plugins, including:
341
355
  * - All installed plugins
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/client",
3
- "version": "2.4.0-next.3",
3
+ "version": "2.4.0-next.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {
@@ -54,6 +54,7 @@ export class RimoriCommunicationHandler {
54
54
  private pluginId: string;
55
55
  private isMessageChannelReady = false;
56
56
  private pendingRequests: Array<() => void> = [];
57
+ private updateCallbacks: Set<(info: RimoriInfo) => void> = new Set();
57
58
 
58
59
  public constructor(pluginId: string, standalone: boolean) {
59
60
  this.pluginId = pluginId;
@@ -124,6 +125,13 @@ export class RimoriCommunicationHandler {
124
125
  }
125
126
  });
126
127
 
128
+ // Listen for updates from rimori-main (data changes, token refresh, etc.)
129
+ // Topic format: {pluginId}.supabase.triggerUpdate
130
+ EventBus.on(`${this.pluginId}.supabase.triggerUpdate`, (ev) => {
131
+ console.log('[RimoriCommunicationHandler] Received update from rimori-main');
132
+ this.handleRimoriInfoUpdate(ev.data as RimoriInfo);
133
+ });
134
+
127
135
  // Mark MessageChannel as ready and process pending requests
128
136
  this.isMessageChannelReady = true;
129
137
 
@@ -307,4 +315,39 @@ export class RimoriCommunicationHandler {
307
315
  const topicRoot = this.rimoriInfo?.pluginId ?? 'global';
308
316
  return `${topicRoot}.${preliminaryTopic}`;
309
317
  }
318
+
319
+ /**
320
+ * Handles updates to RimoriInfo from rimori-main.
321
+ * Updates the cached info and Supabase client, then notifies all registered callbacks.
322
+ */
323
+ private handleRimoriInfoUpdate(newInfo: RimoriInfo): void {
324
+ // Update cached rimoriInfo
325
+ this.rimoriInfo = newInfo;
326
+
327
+ // Update Supabase client with new token
328
+ this.supabase = createClient(newInfo.url, newInfo.key, {
329
+ accessToken: () => Promise.resolve(newInfo.token),
330
+ });
331
+
332
+ // Notify all registered callbacks
333
+ this.updateCallbacks.forEach((callback) => {
334
+ try {
335
+ callback(newInfo);
336
+ } catch (error) {
337
+ console.error('[RimoriCommunicationHandler] Error in update callback:', error);
338
+ }
339
+ });
340
+ }
341
+
342
+ /**
343
+ * Registers a callback to be called when RimoriInfo is updated.
344
+ * @param callback - Function to call with the new RimoriInfo
345
+ * @returns Cleanup function to unregister the callback
346
+ */
347
+ public onUpdate(callback: (info: RimoriInfo) => void): () => void {
348
+ this.updateCallbacks.add(callback);
349
+ return () => {
350
+ this.updateCallbacks.delete(callback);
351
+ };
352
+ }
310
353
  }
@@ -74,9 +74,23 @@ export class RimoriClient {
74
74
  getSettings: async <T extends object>(defaultSettings: T): Promise<T> => {
75
75
  return await this.settingsController.getSettings<T>(defaultSettings);
76
76
  },
77
+ /**
78
+ * Get the current user info.
79
+ * Note: For reactive updates in React components, use the userInfo from useRimori() hook instead.
80
+ * @returns The user info.
81
+ */
77
82
  getUserInfo: (): UserInfo => {
78
83
  return this.rimoriInfo.profile;
79
84
  },
85
+ /**
86
+ * Register a callback to be notified when RimoriInfo is updated.
87
+ * This is useful for reacting to changes in user info, tokens, or other rimori data.
88
+ * @param callback - Function to call with the new RimoriInfo
89
+ * @returns Cleanup function to unregister the callback
90
+ */
91
+ onRimoriInfoUpdate: (callback: (info: RimoriInfo) => void): (() => void) => {
92
+ return this.pluginController.onUpdate(callback);
93
+ },
80
94
  /**
81
95
  * Retrieves information about plugins, including:
82
96
  * - All installed plugins