@rimori/client 1.4.9 → 2.0.0

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 (185) hide show
  1. package/README.md +0 -49
  2. package/dist/react-client/src/plugin/ThemeSetter.d.ts +2 -0
  3. package/dist/react-client/src/plugin/ThemeSetter.js +19 -0
  4. package/dist/react-client/src/utils/PluginUtils.d.ts +2 -0
  5. package/dist/react-client/src/utils/PluginUtils.js +23 -0
  6. package/dist/{cli → rimori-client/src/cli}/scripts/init/main.js +0 -0
  7. package/dist/{cli → rimori-client/src/cli}/scripts/release/release.js +0 -0
  8. package/dist/{core → rimori-client/src}/controller/AIController.d.ts +1 -1
  9. package/dist/{core → rimori-client/src}/controller/AIController.js +2 -2
  10. package/dist/{plugin/AccomplishmentHandler.d.ts → rimori-client/src/controller/AccomplishmentController.d.ts} +1 -1
  11. package/dist/{plugin/AccomplishmentHandler.js → rimori-client/src/controller/AccomplishmentController.js} +1 -1
  12. package/dist/{core → rimori-client/src}/controller/ExerciseController.d.ts +8 -6
  13. package/dist/{core → rimori-client/src}/controller/ExerciseController.js +10 -9
  14. package/dist/{core → rimori-client/src}/controller/ObjectController.d.ts +1 -1
  15. package/dist/{core → rimori-client/src}/controller/ObjectController.js +1 -1
  16. package/dist/{core → rimori-client/src}/controller/SettingsController.d.ts +2 -2
  17. package/dist/{core → rimori-client/src}/controller/SharedContentController.d.ts +1 -1
  18. package/dist/{plugin → rimori-client/src/controller}/TranslationController.js +5 -4
  19. package/dist/{core → rimori-client/src}/controller/VoiceController.d.ts +1 -1
  20. package/dist/rimori-client/src/index.d.ts +11 -0
  21. package/dist/rimori-client/src/index.js +10 -0
  22. package/dist/{plugin/PluginController.d.ts → rimori-client/src/plugin/CommunicationHandler.d.ts} +3 -7
  23. package/dist/{plugin/PluginController.js → rimori-client/src/plugin/CommunicationHandler.js} +3 -28
  24. package/dist/{plugin → rimori-client/src/plugin}/RimoriClient.d.ts +67 -68
  25. package/dist/{plugin → rimori-client/src/plugin}/RimoriClient.js +101 -43
  26. package/dist/{worker → rimori-client/src/worker}/WorkerSetup.js +2 -2
  27. package/example/docs/devdocs.md +1 -1
  28. package/package.json +4 -26
  29. package/src/{core/controller → controller}/AIController.ts +3 -3
  30. package/src/{plugin/AccomplishmentHandler.ts → controller/AccomplishmentController.ts} +1 -1
  31. package/src/{core/controller → controller}/ExerciseController.ts +14 -11
  32. package/src/{core/controller → controller}/ObjectController.ts +2 -2
  33. package/src/{core/controller → controller}/SettingsController.ts +2 -2
  34. package/src/{core/controller → controller}/SharedContentController.ts +1 -1
  35. package/src/{plugin → controller}/TranslationController.ts +6 -4
  36. package/src/{core/controller → controller}/VoiceController.ts +2 -2
  37. package/src/fromRimori/readme.md +1 -1
  38. package/src/index.ts +8 -8
  39. package/src/plugin/{PluginController.ts → CommunicationHandler.ts} +8 -36
  40. package/src/plugin/RimoriClient.ts +125 -118
  41. package/src/worker/WorkerSetup.ts +5 -3
  42. package/tsconfig.json +4 -2
  43. package/dist/cli/scripts/release/release-translation-upload.d.ts +0 -6
  44. package/dist/cli/scripts/release/release-translation-upload.js +0 -87
  45. package/dist/components/CRUDModal.d.ts +0 -17
  46. package/dist/components/CRUDModal.js +0 -24
  47. package/dist/components/MarkdownEditor.d.ts +0 -8
  48. package/dist/components/MarkdownEditor.js +0 -48
  49. package/dist/components/Spinner.d.ts +0 -8
  50. package/dist/components/Spinner.js +0 -4
  51. package/dist/components/ai/Assistant.d.ts +0 -9
  52. package/dist/components/ai/Assistant.js +0 -58
  53. package/dist/components/ai/Avatar.d.ts +0 -14
  54. package/dist/components/ai/Avatar.js +0 -59
  55. package/dist/components/ai/EmbeddedAssistent/AudioInputField.d.ts +0 -7
  56. package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +0 -37
  57. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +0 -8
  58. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +0 -79
  59. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +0 -19
  60. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +0 -91
  61. package/dist/components/ai/EmbeddedAssistent/TTS/Player.d.ts +0 -27
  62. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +0 -185
  63. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +0 -11
  64. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +0 -95
  65. package/dist/components/ai/utils.d.ts +0 -6
  66. package/dist/components/ai/utils.js +0 -13
  67. package/dist/components/audio/Playbutton.d.ts +0 -15
  68. package/dist/components/audio/Playbutton.js +0 -80
  69. package/dist/components/components/ContextMenu.d.ts +0 -10
  70. package/dist/components/components/ContextMenu.js +0 -135
  71. package/dist/components.d.ts +0 -10
  72. package/dist/components.js +0 -11
  73. package/dist/core/controller/EnhancedUserInfo.d.ts +0 -0
  74. package/dist/core/controller/EnhancedUserInfo.js +0 -1
  75. package/dist/core/core.d.ts +0 -14
  76. package/dist/core/core.js +0 -7
  77. package/dist/hooks/I18nHooks.d.ts +0 -11
  78. package/dist/hooks/I18nHooks.js +0 -25
  79. package/dist/hooks/UseChatHook.d.ts +0 -10
  80. package/dist/hooks/UseChatHook.js +0 -29
  81. package/dist/i18n/I18nHooks.d.ts +0 -11
  82. package/dist/i18n/I18nHooks.js +0 -25
  83. package/dist/i18n/Translator.d.ts +0 -43
  84. package/dist/i18n/Translator.js +0 -118
  85. package/dist/i18n/config.d.ts +0 -7
  86. package/dist/i18n/config.js +0 -20
  87. package/dist/i18n/createI18nInstance.d.ts +0 -7
  88. package/dist/i18n/createI18nInstance.js +0 -31
  89. package/dist/i18n/hooks.d.ts +0 -11
  90. package/dist/i18n/hooks.js +0 -25
  91. package/dist/i18n/index.d.ts +0 -4
  92. package/dist/i18n/index.js +0 -4
  93. package/dist/i18n/types.d.ts +0 -7
  94. package/dist/i18n/types.js +0 -1
  95. package/dist/i18n/useRimoriI18n.d.ts +0 -11
  96. package/dist/i18n/useRimoriI18n.js +0 -41
  97. package/dist/index.d.ts +0 -11
  98. package/dist/index.js +0 -11
  99. package/dist/plugin/Translator.d.ts +0 -38
  100. package/dist/plugin/Translator.js +0 -101
  101. package/dist/providers/PluginProvider.d.ts +0 -12
  102. package/dist/providers/PluginProvider.js +0 -152
  103. package/dist/style.css +0 -110
  104. package/dist/style.css.map +0 -1
  105. package/dist/utils/Language.d.ts +0 -67
  106. package/dist/utils/Language.js +0 -69
  107. package/dist/utils/LanguageClass.d.ts +0 -36
  108. package/dist/utils/LanguageClass.example.d.ts +0 -0
  109. package/dist/utils/LanguageClass.example.js +0 -1
  110. package/dist/utils/LanguageClass.js +0 -50
  111. package/dist/utils/LanguageClass.test.d.ts +0 -0
  112. package/dist/utils/LanguageClass.test.js +0 -1
  113. package/src/components/CRUDModal.tsx +0 -75
  114. package/src/components/MarkdownEditor.tsx +0 -144
  115. package/src/components/Spinner.tsx +0 -29
  116. package/src/components/ai/Assistant.tsx +0 -96
  117. package/src/components/ai/Avatar.tsx +0 -99
  118. package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +0 -73
  119. package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +0 -107
  120. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +0 -96
  121. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +0 -197
  122. package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +0 -129
  123. package/src/components/ai/utils.ts +0 -21
  124. package/src/components/audio/Playbutton.tsx +0 -126
  125. package/src/components/components/ContextMenu.tsx +0 -179
  126. package/src/components.ts +0 -11
  127. package/src/core/core.ts +0 -15
  128. package/src/hooks/I18nHooks.ts +0 -33
  129. package/src/hooks/UseChatHook.ts +0 -38
  130. package/src/plugin/ThemeSetter.ts +0 -23
  131. package/src/providers/PluginProvider.tsx +0 -209
  132. package/src/style.scss +0 -136
  133. package/src/utils/PluginUtils.ts +0 -22
  134. /package/dist/{plugin → react-client/plugin}/ThemeSetter.d.ts +0 -0
  135. /package/dist/{plugin → react-client/plugin}/ThemeSetter.js +0 -0
  136. /package/dist/{utils/PluginUtils.d.ts → react-client/src/utils/FullscreenUtils.d.ts} +0 -0
  137. /package/dist/{utils/PluginUtils.js → react-client/src/utils/FullscreenUtils.js} +0 -0
  138. /package/dist/{cli → rimori-client/src/cli}/scripts/init/dev-registration.d.ts +0 -0
  139. /package/dist/{cli → rimori-client/src/cli}/scripts/init/dev-registration.js +0 -0
  140. /package/dist/{cli → rimori-client/src/cli}/scripts/init/env-setup.d.ts +0 -0
  141. /package/dist/{cli → rimori-client/src/cli}/scripts/init/env-setup.js +0 -0
  142. /package/dist/{cli → rimori-client/src/cli}/scripts/init/file-operations.d.ts +0 -0
  143. /package/dist/{cli → rimori-client/src/cli}/scripts/init/file-operations.js +0 -0
  144. /package/dist/{cli → rimori-client/src/cli}/scripts/init/html-cleaner.d.ts +0 -0
  145. /package/dist/{cli → rimori-client/src/cli}/scripts/init/html-cleaner.js +0 -0
  146. /package/dist/{cli → rimori-client/src/cli}/scripts/init/main.d.ts +0 -0
  147. /package/dist/{cli → rimori-client/src/cli}/scripts/init/package-setup.d.ts +0 -0
  148. /package/dist/{cli → rimori-client/src/cli}/scripts/init/package-setup.js +0 -0
  149. /package/dist/{cli → rimori-client/src/cli}/scripts/init/router-transformer.d.ts +0 -0
  150. /package/dist/{cli → rimori-client/src/cli}/scripts/init/router-transformer.js +0 -0
  151. /package/dist/{cli → rimori-client/src/cli}/scripts/init/tailwind-config.d.ts +0 -0
  152. /package/dist/{cli → rimori-client/src/cli}/scripts/init/tailwind-config.js +0 -0
  153. /package/dist/{cli → rimori-client/src/cli}/scripts/init/vite-config.d.ts +0 -0
  154. /package/dist/{cli → rimori-client/src/cli}/scripts/init/vite-config.js +0 -0
  155. /package/dist/{cli → rimori-client/src/cli}/scripts/release/detect-translation-languages.d.ts +0 -0
  156. /package/dist/{cli → rimori-client/src/cli}/scripts/release/detect-translation-languages.js +0 -0
  157. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-config-upload.d.ts +0 -0
  158. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-config-upload.js +0 -0
  159. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-db-update.d.ts +0 -0
  160. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-db-update.js +0 -0
  161. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-file-upload.d.ts +0 -0
  162. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release-file-upload.js +0 -0
  163. /package/dist/{cli → rimori-client/src/cli}/scripts/release/release.d.ts +0 -0
  164. /package/dist/{cli → rimori-client/src/cli}/types/DatabaseTypes.d.ts +0 -0
  165. /package/dist/{cli → rimori-client/src/cli}/types/DatabaseTypes.js +0 -0
  166. /package/dist/{plugin → rimori-client/src/controller}/AudioController.d.ts +0 -0
  167. /package/dist/{plugin → rimori-client/src/controller}/AudioController.js +0 -0
  168. /package/dist/{core → rimori-client/src}/controller/SettingsController.js +0 -0
  169. /package/dist/{core → rimori-client/src}/controller/SharedContentController.js +0 -0
  170. /package/dist/{plugin → rimori-client/src/controller}/TranslationController.d.ts +0 -0
  171. /package/dist/{core → rimori-client/src}/controller/VoiceController.js +0 -0
  172. /package/dist/{fromRimori → rimori-client/src/fromRimori}/EventBus.d.ts +0 -0
  173. /package/dist/{fromRimori → rimori-client/src/fromRimori}/EventBus.js +0 -0
  174. /package/dist/{fromRimori → rimori-client/src/fromRimori}/PluginTypes.d.ts +0 -0
  175. /package/dist/{fromRimori → rimori-client/src/fromRimori}/PluginTypes.js +0 -0
  176. /package/dist/{plugin → rimori-client/src/plugin}/Logger.d.ts +0 -0
  177. /package/dist/{plugin → rimori-client/src/plugin}/Logger.js +0 -0
  178. /package/dist/{plugin → rimori-client/src/plugin}/StandaloneClient.d.ts +0 -0
  179. /package/dist/{plugin → rimori-client/src/plugin}/StandaloneClient.js +0 -0
  180. /package/dist/{utils → rimori-client/src/utils}/difficultyConverter.d.ts +0 -0
  181. /package/dist/{utils → rimori-client/src/utils}/difficultyConverter.js +0 -0
  182. /package/dist/{utils → rimori-client/src/utils}/endpoint.d.ts +0 -0
  183. /package/dist/{utils → rimori-client/src/utils}/endpoint.js +0 -0
  184. /package/dist/{worker → rimori-client/src/worker}/WorkerSetup.d.ts +0 -0
  185. /package/src/{plugin → controller}/AudioController.ts +0 -0
@@ -7,17 +7,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { generateText, streamChatGPT } from '../core/controller/AIController';
11
- import { generateObject } from '../core/controller/ObjectController';
12
- import { SettingsController } from '../core/controller/SettingsController';
13
- import { SharedContentController, } from '../core/controller/SharedContentController';
14
- import { getSTTResponse, getTTSResponse } from '../core/controller/VoiceController';
15
- import { ExerciseController } from '../core/controller/ExerciseController';
10
+ import { generateText, streamChatGPT } from '../controller/AIController';
11
+ import { generateObject } from '../controller/ObjectController';
12
+ import { SettingsController } from '../controller/SettingsController';
13
+ import { SharedContentController, } from '../controller/SharedContentController';
14
+ import { getSTTResponse, getTTSResponse } from '../controller/VoiceController';
15
+ import { ExerciseController } from '../controller/ExerciseController';
16
16
  import { EventBus } from '../fromRimori/EventBus';
17
- import { AccomplishmentHandler } from './AccomplishmentHandler';
18
- import { Translator } from './TranslationController';
17
+ import { AccomplishmentController } from '../controller/AccomplishmentController';
18
+ import { RimoriCommunicationHandler } from './CommunicationHandler';
19
+ import { Translator } from '../controller/TranslationController';
20
+ import { Logger } from './Logger';
19
21
  export class RimoriClient {
20
- constructor(supabase, info, pluginController) {
22
+ constructor(controller, supabase, info) {
21
23
  this.event = {
22
24
  /**
23
25
  * Emit an event to Rimori or a plugin.
@@ -94,10 +96,14 @@ export class RimoriClient {
94
96
  emitSidebarAction: (pluginId, actionKey, text) => {
95
97
  this.event.emit('global.sidebar.triggerAction', { plugin_id: pluginId, action_key: actionKey, text });
96
98
  },
97
- onMainPanelAction: (callback) => {
99
+ onMainPanelAction: (callback, actionsToListen = []) => {
98
100
  // this needs to be a emit and on because the main panel action is triggered by the user and not by the plugin
99
101
  this.event.emit('action.requestMain');
100
- this.event.on('action.requestMain', ({ data }) => callback(data));
102
+ this.event.on('action.requestMain', ({ data }) => {
103
+ if (actionsToListen.includes(data.action)) {
104
+ callback(data);
105
+ }
106
+ });
101
107
  },
102
108
  };
103
109
  this.navigation = {
@@ -233,7 +239,9 @@ export class RimoriClient {
233
239
  * @returns Created exercise object.
234
240
  */
235
241
  add: (params) => __awaiter(this, void 0, void 0, function* () {
236
- return this.exerciseController.addExercise(params);
242
+ const token = yield this.pluginController.getToken();
243
+ const backendUrl = this.pluginController.getBackendUrl();
244
+ return this.exerciseController.addExercise(token, backendUrl, params);
237
245
  }),
238
246
  /**
239
247
  * Deletes an exercise via the backend API.
@@ -241,37 +249,52 @@ export class RimoriClient {
241
249
  * @returns Success status.
242
250
  */
243
251
  delete: (id) => __awaiter(this, void 0, void 0, function* () {
244
- return this.exerciseController.deleteExercise(id);
252
+ const token = yield this.pluginController.getToken();
253
+ const backendUrl = this.pluginController.getBackendUrl();
254
+ return this.exerciseController.deleteExercise(token, backendUrl, id);
245
255
  }),
246
256
  };
247
257
  this.rimoriInfo = info;
248
258
  this.superbase = supabase;
249
- this.pluginController = pluginController;
259
+ this.pluginController = controller;
260
+ this.exerciseController = new ExerciseController(supabase);
261
+ this.accomplishmentHandler = new AccomplishmentController(info.pluginId);
250
262
  this.settingsController = new SettingsController(supabase, info.pluginId, info.guild);
251
- this.sharedContentController = new SharedContentController(this.superbase, this);
252
- this.exerciseController = new ExerciseController(supabase, pluginController);
253
- this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
263
+ this.sharedContentController = new SharedContentController(supabase, this);
254
264
  this.translator = new Translator(info.profile.mother_tongue.code);
255
- this.from = this.from.bind(this);
256
- this.getTableName = this.getTableName.bind(this);
257
- this.db = {
258
- from: this.from,
259
- // storage: this.superbase.storage,
260
- // functions: this.superbase.functions,
261
- tablePrefix: info.tablePrefix,
262
- getTableName: this.getTableName,
263
- };
264
- this.plugin = {
265
- pluginId: info.pluginId,
265
+ //only init logger in workers and on main plugin pages
266
+ if (this.getQueryParam('applicationMode') !== 'sidebar') {
267
+ Logger.getInstance(this);
268
+ }
269
+ }
270
+ get plugin() {
271
+ return {
272
+ pluginId: this.rimoriInfo.pluginId,
273
+ /**
274
+ * Set the settings for the plugin.
275
+ * @param settings The settings to set.
276
+ */
266
277
  setSettings: (settings) => __awaiter(this, void 0, void 0, function* () {
267
278
  yield this.settingsController.setSettings(settings);
268
279
  }),
280
+ /**
281
+ * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
282
+ * @param defaultSettings The default settings to use if no settings are found.
283
+ * @param genericSettings The type of settings to get.
284
+ * @returns The settings for the plugin.
285
+ */
269
286
  getSettings: (defaultSettings) => __awaiter(this, void 0, void 0, function* () {
270
287
  return yield this.settingsController.getSettings(defaultSettings);
271
288
  }),
272
289
  getUserInfo: () => {
273
290
  return this.rimoriInfo.profile;
274
291
  },
292
+ /**
293
+ * Retrieves information about plugins, including:
294
+ * - All installed plugins
295
+ * - The currently active plugin in the main panel
296
+ * - The currently active plugin in the side panel
297
+ */
275
298
  getPluginInfo: () => {
276
299
  return {
277
300
  installedPlugins: this.rimoriInfo.installedPlugins,
@@ -279,12 +302,51 @@ export class RimoriClient {
279
302
  sidePanelPlugin: this.rimoriInfo.sidePanelPlugin,
280
303
  };
281
304
  },
305
+ /**
306
+ * Get the translator for the plugin.
307
+ * @returns The translator for the plugin.
308
+ */
282
309
  getTranslator: () => __awaiter(this, void 0, void 0, function* () {
283
310
  yield this.translator.initialize();
284
311
  return this.translator;
285
312
  }),
286
313
  };
287
314
  }
315
+ get db() {
316
+ return {
317
+ // private from<
318
+ // TableName extends string & keyof GenericSchema['Tables'],
319
+ // Table extends GenericSchema['Tables'][TableName],
320
+ // >(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
321
+ // private from<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(
322
+ // relation: ViewName,
323
+ // ): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
324
+ from: (relation) => {
325
+ return this.superbase.from(this.db.getTableName(relation));
326
+ },
327
+ // storage: this.superbase.storage,
328
+ // functions: this.superbase.functions,
329
+ /**
330
+ * The table prefix for of database tables of the plugin.
331
+ */
332
+ tablePrefix: this.rimoriInfo.tablePrefix,
333
+ /**
334
+ * Get the table name for a given plugin table.
335
+ * Internally all tables are prefixed with the plugin id. This function is used to get the correct table name for a given public table.
336
+ * @param table The plugin table name to get the full table name for.
337
+ * @returns The full table name.
338
+ */
339
+ getTableName: (table) => {
340
+ if (/[A-Z]/.test(table)) {
341
+ throw new Error('Table name cannot include uppercase letters. Please use snake_case for table names.');
342
+ }
343
+ if (table.startsWith('global_')) {
344
+ return table.replace('global_', '');
345
+ }
346
+ return this.db.tablePrefix + '_' + table;
347
+ },
348
+ };
349
+ }
288
350
  /**
289
351
  * Get a query parameter value that was passed via MessageChannel
290
352
  * @param key The query parameter key
@@ -293,25 +355,21 @@ export class RimoriClient {
293
355
  getQueryParam(key) {
294
356
  return this.pluginController.getQueryParam(key);
295
357
  }
296
- static getInstance(pluginController) {
358
+ static getInstance(pluginId) {
297
359
  return __awaiter(this, void 0, void 0, function* () {
298
360
  if (!RimoriClient.instance) {
299
- const client = yield pluginController.getClient();
300
- RimoriClient.instance = new RimoriClient(client.supabase, client.info, pluginController);
361
+ if (!pluginId)
362
+ throw new Error('Plugin ID is required');
363
+ const controller = new RimoriCommunicationHandler(pluginId, false);
364
+ if (typeof WorkerGlobalScope === 'undefined') {
365
+ // In standalone mode, use URL fallback. In iframe mode, theme will be set after MessageChannel init
366
+ // setTheme();
367
+ // await StandaloneClient.initListeners(pluginId);
368
+ }
369
+ const client = yield controller.getClient();
370
+ RimoriClient.instance = new RimoriClient(controller, client.supabase, client.info);
301
371
  }
302
372
  return RimoriClient.instance;
303
373
  });
304
374
  }
305
- from(relation) {
306
- return this.superbase.from(this.getTableName(relation));
307
- }
308
- getTableName(table) {
309
- if (/[A-Z]/.test(table)) {
310
- throw new Error('Table name cannot include uppercase letters. Please use snake_case for table names.');
311
- }
312
- if (table.startsWith('global_')) {
313
- return table.replace('global_', '');
314
- }
315
- return this.db.tablePrefix + '_' + table;
316
- }
317
375
  }
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { RimoriClient } from '../plugin/RimoriClient';
10
11
  import { EventBusHandler } from '../fromRimori/EventBus';
11
- import { PluginController } from '../plugin/PluginController';
12
12
  /**
13
13
  * Sets up the web worker for the plugin to be able receive and send messages to Rimori.
14
14
  * @param pluginId - The id of the plugin to setup the worker for.
@@ -28,7 +28,7 @@ export function setupWorker(pluginId, init) {
28
28
  // Assign the mock to globalThis.
29
29
  Object.assign(globalThis, { window: mockWindow });
30
30
  EventBusHandler.getInstance('Worker EventBus');
31
- const rimoriClient = yield PluginController.getInstance(pluginId);
31
+ const rimoriClient = yield RimoriClient.getInstance(pluginId);
32
32
  console.debug('[Worker] RimoriClient initialized.');
33
33
  yield init(rimoriClient);
34
34
  console.debug('[Worker] Worker initialized.');
@@ -42,7 +42,7 @@ plugin.event.emit('pl123456789.flashcard.createLangCard', {
42
42
 
43
43
  ```javascript
44
44
  // Request word translation
45
- const translation = await plugin.event.request('pl123456789.lookup.requestBasic', {
45
+ const translation = await plugin.event.request('pl123456789.lookup.request', {
46
46
  word: 'laufen',
47
47
  language: 'de', // optional
48
48
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/client",
3
- "version": "1.4.9",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "bin": {
@@ -12,38 +12,18 @@
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
14
  "default": "./dist/index.js"
15
- },
16
- "./core": {
17
- "types": "./dist/core/core.d.ts",
18
- "default": "./dist/core/core.js"
19
- },
20
- "./components": {
21
- "types": "./dist/components.d.ts",
22
- "default": "./dist/components.js"
23
15
  }
24
16
  },
25
17
  "scripts": {
26
- "build": "tsc && sass src/style.scss:dist/style.css",
18
+ "build": "tsc",
27
19
  "dev": "tsc -w --preserveWatchOutput",
28
- "css-dev": "sass --watch src/style.scss:dist/style.css",
29
20
  "lint": "eslint . --fix",
30
21
  "format": "prettier --write ."
31
22
  },
32
- "peerDependencies": {
33
- "react": "^18.0.0",
34
- "react-dom": "^18.0.0"
35
- },
36
23
  "dependencies": {
37
24
  "@supabase/supabase-js": "2.49.4",
38
- "@tiptap/react": "2.10.3",
39
- "@tiptap/starter-kit": "2.10.3",
40
25
  "dotenv": "16.5.0",
41
- "html2canvas": "1.4.1",
42
- "i18next": "^25.6.0",
43
- "prettier": "^3.6.2",
44
- "react-icons": "5.4.0",
45
- "react-markdown": "10.1.0",
46
- "tiptap-markdown": "0.8.10"
26
+ "i18next": "^25.6.0"
47
27
  },
48
28
  "devDependencies": {
49
29
  "@eslint/js": "^9.37.0",
@@ -51,10 +31,8 @@
51
31
  "eslint-plugin-prettier": "^5.5.4",
52
32
  "eslint-plugin-react-hooks": "^7.0.0",
53
33
  "eslint-plugin-react-refresh": "^0.4.23",
54
- "form-data": "^4.0.2",
55
34
  "globals": "^16.4.0",
56
- "node-fetch": "^3.3.2",
57
- "sass": "^1.82.0",
35
+ "prettier": "^3.6.2",
58
36
  "typescript": "^5.7.2",
59
37
  "typescript-eslint": "^8.46.0"
60
38
  }
@@ -1,4 +1,4 @@
1
- import { Tool } from '../../fromRimori/PluginTypes';
1
+ import { Tool } from '../fromRimori/PluginTypes';
2
2
 
3
3
  export interface ToolInvocation {
4
4
  toolCallId: string;
@@ -38,7 +38,7 @@ export async function streamChatGPT(
38
38
  token: string,
39
39
  ) {
40
40
  const messageId = Math.random().toString(36).substring(3);
41
- let currentMessages: Message[] = [...messages];
41
+ const currentMessages: Message[] = [...messages];
42
42
 
43
43
  console.log('Starting streamChatGPT with:', {
44
44
  messageId,
@@ -71,7 +71,7 @@ export async function streamChatGPT(
71
71
 
72
72
  let content = '';
73
73
  let done = false;
74
- let toolInvocations: { toolCallId: string; toolName: string; args: any }[] = [];
74
+ const toolInvocations: { toolCallId: string; toolName: string; args: any }[] = [];
75
75
  let currentTextId = '';
76
76
  let isToolCallMode = false;
77
77
  let buffer = ''; // Buffer for incomplete chunks
@@ -36,7 +36,7 @@ export interface MacroAccomplishmentPayload extends BaseAccomplishmentPayload {
36
36
 
37
37
  export type AccomplishmentPayload = MicroAccomplishmentPayload | MacroAccomplishmentPayload;
38
38
 
39
- export class AccomplishmentHandler {
39
+ export class AccomplishmentController {
40
40
  private pluginId: string;
41
41
 
42
42
  public constructor(pluginId: string) {
@@ -1,5 +1,4 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
- import { PluginController } from '../../plugin/PluginController';
3
2
 
4
3
  export type TriggerAction = { action_key: string } & Record<string, string | number | boolean>;
5
4
 
@@ -28,11 +27,9 @@ export interface Exercise {
28
27
 
29
28
  export class ExerciseController {
30
29
  private supabase: SupabaseClient;
31
- private pluginController: PluginController;
32
30
 
33
- constructor(supabase: SupabaseClient, pluginController: PluginController) {
31
+ constructor(supabase: SupabaseClient) {
34
32
  this.supabase = supabase;
35
- this.pluginController = pluginController;
36
33
  }
37
34
 
38
35
  /**
@@ -52,12 +49,13 @@ export class ExerciseController {
52
49
 
53
50
  /**
54
51
  * Creates a new exercise via the backend API.
52
+ * @param token The token to use for authentication.
53
+ * @param backendUrl The URL of the backend API.
55
54
  * @param params Exercise creation parameters.
56
55
  * @returns Created exercise object.
57
56
  */
58
- public async addExercise(params: CreateExerciseParams): Promise<Exercise> {
59
- const token = await this.pluginController.getToken();
60
- const response = await fetch(`${this.pluginController.getBackendUrl()}/exercises`, {
57
+ public async addExercise(token: string, backendUrl: string, params: CreateExerciseParams): Promise<Exercise> {
58
+ const response = await fetch(`${backendUrl}/exercises`, {
61
59
  method: 'POST',
62
60
  headers: {
63
61
  'Content-Type': 'application/json',
@@ -76,12 +74,17 @@ export class ExerciseController {
76
74
 
77
75
  /**
78
76
  * Deletes an exercise via the backend API.
79
- * @param id The exercise ID to delete.
77
+ * @param token The token to use for authentication.
78
+ * @param backendUrl The URL of the backend API.
79
+ * @param exerciseId The exercise ID to delete.
80
80
  * @returns Success status.
81
81
  */
82
- public async deleteExercise(id: string): Promise<{ success: boolean; message: string }> {
83
- const token = await this.pluginController.getToken();
84
- const response = await fetch(`${this.pluginController.getBackendUrl()}/exercises/${id}`, {
82
+ public async deleteExercise(
83
+ token: string,
84
+ backendUrl: string,
85
+ id: string,
86
+ ): Promise<{ success: boolean; message: string }> {
87
+ const response = await fetch(`${backendUrl}/exercises/${id}`, {
85
88
  method: 'DELETE',
86
89
  headers: {
87
90
  Authorization: `Bearer ${token}`,
@@ -41,7 +41,7 @@ export interface ObjectRequest {
41
41
  instructions: string;
42
42
  }
43
43
 
44
- export async function generateObject(backendUrl: string, request: ObjectRequest, token: string) {
44
+ export async function generateObject<T = any>(backendUrl: string, request: ObjectRequest, token: string): Promise<T> {
45
45
  return await fetch(`${backendUrl}/ai/llm-object`, {
46
46
  method: 'POST',
47
47
  body: JSON.stringify({
@@ -85,7 +85,7 @@ export async function streamObject(
85
85
 
86
86
  let content = '';
87
87
  let done = false;
88
- let toolInvocations: any[] = [];
88
+ const toolInvocations: any[] = [];
89
89
  while (!done) {
90
90
  const { value } = await reader.read();
91
91
 
@@ -1,6 +1,6 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
- import { LanguageLevel } from '../../utils/difficultyConverter';
3
- import { Guild } from '../core';
2
+ import { LanguageLevel } from '../utils/difficultyConverter';
3
+ import { Guild } from '../plugin/CommunicationHandler';
4
4
 
5
5
  export interface Buddy {
6
6
  id: string;
@@ -1,5 +1,5 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
- import { RimoriClient } from '../../plugin/RimoriClient';
2
+ import { RimoriClient } from '../plugin/RimoriClient';
3
3
  import { ObjectRequest } from './ObjectController';
4
4
 
5
5
  export interface SharedContentObjectRequest extends ObjectRequest {
@@ -39,11 +39,13 @@ export class Translator {
39
39
 
40
40
  private getTranslationUrl(language: string): string {
41
41
  // For localhost development, use local- prefix for non-English languages
42
- const isLocalhost = window.location.hostname === 'localhost';
43
- const isEnglish = language === 'en';
44
- const filename = isLocalhost && !isEnglish ? `local-${language}` : language;
42
+ if (window.location.hostname === 'localhost') {
43
+ const filename = language !== 'en' ? `local-${language}` : language;
45
44
 
46
- return `${window.location.origin}/locales/${filename}.json`;
45
+ return `${window.location.origin}/locales/${filename}.json`;
46
+ }
47
+
48
+ return `./locales/${language}.json`;
47
49
  }
48
50
 
49
51
  public usePlugin(plugin: ThirdPartyModule): void {
@@ -1,4 +1,4 @@
1
- export async function getSTTResponse(backendUrl: string, audio: Blob, token: string) {
1
+ export async function getSTTResponse(backendUrl: string, audio: Blob, token: string): Promise<string> {
2
2
  const formData = new FormData();
3
3
  formData.append('file', audio);
4
4
 
@@ -14,7 +14,7 @@ export async function getSTTResponse(backendUrl: string, audio: Blob, token: str
14
14
  });
15
15
  }
16
16
 
17
- export async function getTTSResponse(backendUrl: string, request: TTSRequest, token: string) {
17
+ export async function getTTSResponse(backendUrl: string, request: TTSRequest, token: string): Promise<Blob> {
18
18
  return await fetch(`${backendUrl}/voice/tts`, {
19
19
  method: 'POST',
20
20
  headers: {
@@ -1,2 +1,2 @@
1
- Files inside this folder are copied from Rimori and should not be changed.
1
+ Files inside this folder are copied from Rimori main repository and should not be changed.
2
2
  If change is needed adapt it in Rimori and copy the file then over.
package/src/index.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  // Re-export everything
2
- export * from './components';
3
- export * from './hooks/UseChatHook';
4
- export * from './plugin/PluginController';
5
- export * from './providers/PluginProvider';
2
+ export * from './plugin/CommunicationHandler';
6
3
  export * from './cli/types/DatabaseTypes';
7
4
  export * from './utils/difficultyConverter';
8
- export * from './utils/PluginUtils';
9
5
  export * from './fromRimori/PluginTypes';
10
- export { FirstMessages } from './components/ai/utils';
11
- export { AudioController } from './plugin/AudioController';
12
- export { useTranslation } from './hooks/I18nHooks';
6
+ export * from './fromRimori/EventBus';
7
+ export * from './plugin/RimoriClient';
8
+ export * from './plugin/StandaloneClient';
9
+ export { AudioController } from './controller/AudioController';
10
+ export { Translator } from './controller/TranslationController';
11
+ export type { Message, ToolInvocation } from './controller/AIController';
12
+ export type { TOptions } from 'i18next';
@@ -1,11 +1,7 @@
1
1
  import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
- import { UserInfo } from '../core/controller/SettingsController';
2
+ import { UserInfo } from '../controller/SettingsController';
3
3
  import { EventBus, EventBusMessage } from '../fromRimori/EventBus';
4
4
  import { ActivePlugin, Plugin } from '../fromRimori/PluginTypes';
5
- import { RimoriClient } from './RimoriClient';
6
- import { StandaloneClient } from './StandaloneClient';
7
- import { setTheme } from './ThemeSetter';
8
- import { Logger } from './Logger';
9
5
 
10
6
  // Add declaration for WorkerGlobalScope
11
7
  declare const WorkerGlobalScope: any;
@@ -31,35 +27,26 @@ export interface RimoriInfo {
31
27
  sidePanelPlugin?: ActivePlugin;
32
28
  }
33
29
 
34
- export class PluginController {
35
- private static client: RimoriClient;
36
- private static instance: PluginController;
30
+ export class RimoriCommunicationHandler {
37
31
  private port: MessagePort | null = null;
38
32
  private queryParams: Record<string, string> = {};
39
33
  private supabase: SupabaseClient | null = null;
40
34
  private rimoriInfo: RimoriInfo | null = null;
41
35
  private pluginId: string;
42
- private isMessageChannelReady: boolean = false;
36
+ private isMessageChannelReady = false;
43
37
  private pendingRequests: Array<() => void> = [];
44
38
 
45
- private constructor(pluginId: string, standalone: boolean) {
39
+ public constructor(pluginId: string, standalone: boolean) {
46
40
  this.pluginId = pluginId;
47
41
  this.getClient = this.getClient.bind(this);
48
42
 
49
- if (typeof WorkerGlobalScope === 'undefined') {
50
- // In standalone mode, use URL fallback. In iframe mode, theme will be set after MessageChannel init
51
- if (standalone) {
52
- setTheme();
53
- }
54
- }
55
-
56
43
  //no need to forward messages to parent in standalone mode or worker context
57
44
  if (standalone) return;
58
45
 
59
46
  this.initMessageChannel(typeof WorkerGlobalScope !== 'undefined');
60
47
  }
61
48
 
62
- private initMessageChannel(worker: boolean = false) {
49
+ private initMessageChannel(worker = false) {
63
50
  const listener = (event: MessageEvent) => {
64
51
  console.log('[PluginController] window message', { origin: event.origin, data: event.data });
65
52
  const { type, pluginId, queryParams, rimoriInfo } = event.data || {};
@@ -105,7 +92,8 @@ export class PluginController {
105
92
  // Set theme from MessageChannel query params
106
93
  if (!worker) {
107
94
  const theme = this.queryParams['rm_theme'];
108
- setTheme(theme);
95
+ // setTheme(theme);
96
+ console.log('TODO: set theme from MessageChannel query params');
109
97
  }
110
98
 
111
99
  // Forward plugin events to parent (only after MessageChannel is ready)
@@ -130,7 +118,7 @@ export class PluginController {
130
118
  this.sendHello(worker);
131
119
  }
132
120
 
133
- private sendHello(isWorker: boolean = false) {
121
+ private sendHello(isWorker = false): void {
134
122
  try {
135
123
  const payload = { type: 'rimori:hello', pluginId: this.pluginId };
136
124
  if (isWorker) {
@@ -143,22 +131,6 @@ export class PluginController {
143
131
  }
144
132
  }
145
133
 
146
- public static async getInstance(pluginId: string, standalone = false): Promise<RimoriClient> {
147
- if (!PluginController.instance) {
148
- if (standalone) {
149
- await StandaloneClient.initListeners(pluginId);
150
- }
151
- PluginController.instance = new PluginController(pluginId, standalone);
152
- PluginController.client = await RimoriClient.getInstance(PluginController.instance);
153
-
154
- //only init logger in workers and on main plugin pages
155
- if (PluginController.instance.getQueryParam('applicationMode') !== 'sidebar') {
156
- Logger.getInstance(PluginController.client);
157
- }
158
- }
159
- return PluginController.client;
160
- }
161
-
162
134
  public getQueryParam(key: string): string | null {
163
135
  return this.queryParams[key] || null;
164
136
  }