@rimori/client 2.4.0-next.2 → 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.
@@ -24,7 +24,7 @@ jobs:
24
24
  uses: actions/checkout@v4
25
25
  with:
26
26
  fetch-depth: 0
27
- token: ${{ secrets.GITHUB_TOKEN }}
27
+ token: ${{ secrets.PAT_TOKEN }}
28
28
 
29
29
  - name: Setup Node.js
30
30
  uses: actions/setup-node@v4
@@ -109,7 +109,7 @@ jobs:
109
109
  - name: Create Pull Request
110
110
  id: create_pr
111
111
  env:
112
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
112
+ GH_TOKEN: ${{ secrets.PAT_TOKEN }}
113
113
  run: |
114
114
  NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
115
115
  BRANCH_NAME="release/v$NEW_VERSION"
@@ -28,6 +28,8 @@ jobs:
28
28
  with:
29
29
  node-version: '20'
30
30
  cache: 'yarn'
31
+ registry-url: 'https://registry.npmjs.org'
32
+ provenance: true
31
33
 
32
34
  - name: Get version from package.json
33
35
  id: get_version
@@ -69,7 +71,7 @@ jobs:
69
71
  yarn install --frozen-lockfile
70
72
  yarn build
71
73
 
72
- - name: Create GitHub Release (Prerelease)
74
+ - name: Create GitHub Release
73
75
  uses: softprops/action-gh-release@v1
74
76
  with:
75
77
  tag_name: v${{ steps.get_version.outputs.version }}
@@ -80,18 +82,31 @@ jobs:
80
82
  ### Changes in this release
81
83
 
82
84
  ${{ steps.get_changelog.outputs.changelog }}
83
-
84
- ---
85
-
86
- **Note:** This is a prerelease. It will be promoted to a stable release after testing.
87
- prerelease: true
85
+ prerelease: false
88
86
  generate_release_notes: true
89
87
  token: ${{ secrets.GITHUB_TOKEN }}
90
88
 
91
- - name: Publish to npm
89
+ - name: Publish to npm (stable)
92
90
  id: npm_publish
93
91
  run: |
94
- npm publish --provenance --access public --tag prerelease || echo "npm publish skipped (may already exist)"
92
+ npm publish --provenance --access public --tag latest
93
+
94
+ - name: Publish to npm (next)
95
+ id: npm_publish_next
96
+ run: |
97
+ VERSION="${{ steps.get_version.outputs.version }}"
98
+ NEXT_VERSION="${VERSION}-next.0"
99
+
100
+ # Temporarily update package.json version for next publish
101
+ node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); pkg.version = '$NEXT_VERSION'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');"
102
+
103
+ # Publish with next tag
104
+ npm publish --provenance --access public --tag next
105
+
106
+ # Restore original version (don't commit)
107
+ git checkout package.json
108
+
109
+ echo "Published version: $NEXT_VERSION with tag 'next'"
95
110
 
96
111
  - name: Send Slack notification - Success
97
112
  if: success()
@@ -118,7 +133,7 @@ jobs:
118
133
  },
119
134
  {
120
135
  "type": "mrkdwn",
121
- "text": "*Type:*\nPrerelease"
136
+ "text": "*Type:*\nStable + Next"
122
137
  },
123
138
  {
124
139
  "type": "mrkdwn",
@@ -106,7 +106,7 @@ export class EventBusHandler {
106
106
  const blackListedEventIds = [];
107
107
  const eventHandler = (data) => {
108
108
  if (blackListedEventIds.some((item) => item.eventId === data.eventId && item.sender === data.sender)) {
109
- console.log('BLACKLISTED EVENT ID', data.eventId, data);
109
+ // console.log('BLACKLISTED EVENT ID', data.eventId, data);
110
110
  return;
111
111
  }
112
112
  blackListedEventIds.push({
@@ -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.2",
3
+ "version": "2.4.0-next.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {
@@ -162,7 +162,7 @@ export class EventBusHandler {
162
162
  const blackListedEventIds: { eventId: number; sender: string }[] = [];
163
163
  const eventHandler = (data: EventBusMessage) => {
164
164
  if (blackListedEventIds.some((item) => item.eventId === data.eventId && item.sender === data.sender)) {
165
- console.log('BLACKLISTED EVENT ID', data.eventId, data);
165
+ // console.log('BLACKLISTED EVENT ID', data.eventId, data);
166
166
  return;
167
167
  }
168
168
  blackListedEventIds.push({
@@ -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