@rimori/client 1.1.10 → 1.3.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.
- package/README.md +189 -63
- package/dist/cli/scripts/init/dev-registration.d.ts +35 -0
- package/dist/cli/scripts/init/dev-registration.js +174 -0
- package/dist/cli/scripts/init/env-setup.d.ts +9 -0
- package/dist/cli/scripts/init/env-setup.js +43 -0
- package/dist/cli/scripts/init/file-operations.d.ts +4 -0
- package/dist/cli/scripts/init/file-operations.js +51 -0
- package/dist/cli/scripts/init/html-cleaner.d.ts +4 -0
- package/dist/cli/scripts/init/html-cleaner.js +38 -0
- package/dist/cli/scripts/init/main.d.ts +2 -0
- package/dist/cli/scripts/init/main.js +160 -0
- package/dist/cli/scripts/init/package-setup.d.ts +32 -0
- package/dist/cli/scripts/init/package-setup.js +75 -0
- package/dist/cli/scripts/init/router-transformer.d.ts +6 -0
- package/dist/cli/scripts/init/router-transformer.js +254 -0
- package/dist/cli/scripts/init/tailwind-config.d.ts +4 -0
- package/dist/cli/scripts/init/tailwind-config.js +56 -0
- package/dist/cli/scripts/init/vite-config.d.ts +20 -0
- package/dist/cli/scripts/init/vite-config.js +54 -0
- package/dist/cli/scripts/release/release-config-upload.d.ts +7 -0
- package/dist/cli/scripts/release/release-config-upload.js +116 -0
- package/dist/cli/scripts/release/release-db-update.d.ts +6 -0
- package/dist/cli/scripts/release/release-db-update.js +100 -0
- package/dist/cli/scripts/release/release-file-upload.d.ts +6 -0
- package/dist/cli/scripts/release/release-file-upload.js +136 -0
- package/dist/cli/scripts/release/release.d.ts +23 -0
- package/dist/cli/scripts/release/release.js +70 -0
- package/dist/cli/types/DatabaseTypes.d.ts +103 -0
- package/dist/cli/types/DatabaseTypes.js +2 -0
- package/dist/components/LoggerExample.d.ts +6 -0
- package/dist/components/LoggerExample.js +79 -0
- package/dist/components/ai/Assistant.js +5 -5
- package/dist/components/ai/Avatar.d.ts +3 -2
- package/dist/components/ai/Avatar.js +11 -6
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -1
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +1 -0
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +48 -33
- package/dist/components/ai/utils.js +0 -1
- package/dist/components/audio/Playbutton.js +4 -4
- package/dist/{core → components}/components/ContextMenu.js +50 -11
- package/dist/components.d.ts +5 -5
- package/dist/components.js +5 -5
- package/dist/core/controller/AIController.d.ts +15 -0
- package/dist/core/controller/AIController.js +253 -0
- package/dist/core/controller/AudioController.d.ts +0 -0
- package/dist/core/controller/AudioController.js +1 -0
- package/dist/{controller → core/controller}/ObjectController.d.ts +10 -2
- package/dist/{controller → core/controller}/ObjectController.js +8 -8
- package/dist/{controller → core/controller}/SettingsController.d.ts +28 -4
- package/dist/{controller → core/controller}/SettingsController.js +0 -25
- package/dist/{controller → core/controller}/SharedContentController.d.ts +31 -3
- package/dist/{controller → core/controller}/SharedContentController.js +77 -26
- package/dist/core/controller/VoiceController.d.ts +9 -0
- package/dist/{controller → core/controller}/VoiceController.js +11 -4
- package/dist/core/core.d.ts +14 -0
- package/dist/core/core.js +8 -0
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.d.ts +3 -3
- package/dist/{plugin/fromRimori → fromRimori}/EventBus.js +26 -9
- package/dist/fromRimori/PluginTypes.d.ts +174 -0
- package/dist/hooks/UseChatHook.d.ts +2 -1
- package/dist/hooks/UseChatHook.js +6 -4
- package/dist/hooks/UseLogger.d.ts +30 -0
- package/dist/hooks/UseLogger.js +122 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -3
- package/dist/plugin/AccomplishmentHandler.d.ts +1 -1
- package/dist/plugin/AccomplishmentHandler.js +1 -1
- package/dist/plugin/AudioController.d.ts +37 -0
- package/dist/plugin/AudioController.js +68 -0
- package/dist/plugin/Logger.d.ts +68 -0
- package/dist/plugin/Logger.js +256 -0
- package/dist/plugin/LoggerExample.d.ts +16 -0
- package/dist/plugin/LoggerExample.js +140 -0
- package/dist/plugin/PluginController.d.ts +30 -5
- package/dist/plugin/PluginController.js +182 -53
- package/dist/plugin/RimoriClient.d.ts +68 -21
- package/dist/plugin/RimoriClient.js +88 -41
- package/dist/plugin/StandaloneClient.d.ts +1 -0
- package/dist/plugin/StandaloneClient.js +24 -10
- package/dist/plugin/ThemeSetter.d.ts +2 -1
- package/dist/plugin/ThemeSetter.js +13 -7
- package/dist/providers/PluginProvider.d.ts +4 -1
- package/dist/providers/PluginProvider.js +39 -13
- package/dist/utils/Language.d.ts +2 -1
- package/dist/utils/Language.js +4 -2
- package/dist/utils/audioFormats.d.ts +26 -0
- package/dist/utils/audioFormats.js +67 -0
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.d.ts +2 -0
- package/dist/utils/endpoint.js +2 -0
- package/dist/worker/WorkerSetup.d.ts +3 -2
- package/dist/worker/WorkerSetup.js +22 -65
- package/example/docs/devdocs.md +231 -0
- package/example/docs/overview.md +29 -0
- package/example/docs/userdocs.md +123 -0
- package/example/rimori.config.ts +89 -0
- package/example/worker/vite.config.ts +23 -0
- package/example/worker/worker.ts +11 -0
- package/package.json +16 -9
- package/src/cli/scripts/init/dev-registration.ts +192 -0
- package/src/cli/scripts/init/env-setup.ts +44 -0
- package/src/cli/scripts/init/file-operations.ts +58 -0
- package/src/cli/scripts/init/html-cleaner.ts +48 -0
- package/src/cli/scripts/init/main.ts +172 -0
- package/src/cli/scripts/init/package-setup.ts +117 -0
- package/src/cli/scripts/init/router-transformer.ts +329 -0
- package/src/cli/scripts/init/tailwind-config.ts +75 -0
- package/src/cli/scripts/init/vite-config.ts +73 -0
- package/src/cli/scripts/release/release-config-upload.ts +114 -0
- package/src/cli/scripts/release/release-db-update.ts +97 -0
- package/src/cli/scripts/release/release-file-upload.ts +138 -0
- package/src/cli/scripts/release/release.ts +69 -0
- package/src/cli/types/DatabaseTypes.ts +117 -0
- package/src/components/ai/Assistant.tsx +5 -5
- package/src/components/ai/Avatar.tsx +25 -8
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +1 -1
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +50 -35
- package/src/components/ai/utils.ts +0 -2
- package/src/components/audio/Playbutton.tsx +4 -4
- package/src/{core → components}/components/ContextMenu.tsx +56 -12
- package/src/components.ts +6 -6
- package/src/core/controller/AIController.ts +283 -0
- package/src/core/controller/ObjectController.ts +115 -0
- package/src/{controller → core/controller}/SettingsController.ts +29 -29
- package/src/{controller → core/controller}/SharedContentController.ts +91 -29
- package/src/core/controller/VoiceController.ts +31 -0
- package/src/core/core.ts +16 -0
- package/src/{plugin/fromRimori → fromRimori}/EventBus.ts +29 -11
- package/src/fromRimori/PluginTypes.ts +205 -0
- package/src/hooks/UseChatHook.ts +8 -5
- package/src/index.ts +6 -3
- package/src/plugin/AccomplishmentHandler.ts +1 -1
- package/src/plugin/AudioController.ts +58 -0
- package/src/plugin/Logger.ts +324 -0
- package/src/plugin/PluginController.ts +203 -63
- package/src/plugin/RimoriClient.ts +127 -55
- package/src/plugin/StandaloneClient.ts +30 -11
- package/src/plugin/ThemeSetter.ts +16 -9
- package/src/providers/PluginProvider.tsx +46 -13
- package/src/utils/Language.ts +4 -2
- package/src/utils/difficultyConverter.ts +3 -3
- package/src/utils/endpoint.ts +2 -0
- package/src/worker/WorkerSetup.ts +13 -60
- package/dist/components/PluginController.d.ts +0 -21
- package/dist/components/PluginController.js +0 -116
- package/dist/controller/AIController.d.ts +0 -23
- package/dist/controller/AIController.js +0 -93
- package/dist/controller/SidePluginController.d.ts +0 -3
- package/dist/controller/SidePluginController.js +0 -31
- package/dist/controller/VoiceController.d.ts +0 -10
- package/dist/core.d.ts +0 -7
- package/dist/core.js +0 -7
- package/dist/plugin/ContextMenu.d.ts +0 -17
- package/dist/plugin/ContextMenu.js +0 -45
- package/dist/plugin/fromRimori/PluginTypes.d.ts +0 -48
- package/dist/plugin/fromRimori/SupabaseHandler.d.ts +0 -13
- package/dist/plugin/fromRimori/SupabaseHandler.js +0 -55
- package/dist/providers/PluginController.d.ts +0 -21
- package/dist/providers/PluginController.js +0 -116
- package/dist/types/Actions.d.ts +0 -4
- package/dist/types/Actions.js +0 -1
- package/src/controller/AIController.ts +0 -112
- package/src/controller/ObjectController.ts +0 -107
- package/src/controller/SidePluginController.ts +0 -25
- package/src/controller/VoiceController.ts +0 -26
- package/src/core.ts +0 -8
- package/src/plugin/fromRimori/PluginTypes.ts +0 -64
- package/src/types/Actions.ts +0 -6
- /package/dist/{core → components}/components/ContextMenu.d.ts +0 -0
- /package/dist/{plugin/fromRimori → fromRimori}/PluginTypes.js +0 -0
- /package/src/{plugin/fromRimori → fromRimori}/readme.md +0 -0
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
import { PostgrestQueryBuilder } from "@supabase/postgrest-js";
|
|
2
2
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
3
3
|
import { GenericSchema } from "@supabase/supabase-js/dist/module/lib/types";
|
|
4
|
-
import { generateText, Message, OnLLMResponse, streamChatGPT
|
|
5
|
-
import { generateObject
|
|
6
|
-
import { SettingsController, UserInfo } from "../controller/SettingsController";
|
|
7
|
-
import { SharedContent, SharedContentController, SharedContentFilter, SharedContentObjectRequest } from "../controller/SharedContentController";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { generateText, Message, OnLLMResponse, streamChatGPT } from "../core/controller/AIController";
|
|
5
|
+
import { generateObject, ObjectRequest } from "../core/controller/ObjectController";
|
|
6
|
+
import { SettingsController, UserInfo } from "../core/controller/SettingsController";
|
|
7
|
+
import { SharedContent, SharedContentController, SharedContentFilter, SharedContentObjectRequest } from "../core/controller/SharedContentController";
|
|
8
|
+
import { getSTTResponse, getTTSResponse } from "../core/controller/VoiceController";
|
|
9
|
+
import { EventBus, EventBusMessage, EventHandler, EventPayload } from "../fromRimori/EventBus";
|
|
10
|
+
import { ActivePlugin, MainPanelAction, Plugin, Tool } from "../fromRimori/PluginTypes";
|
|
10
11
|
import { AccomplishmentHandler, AccomplishmentPayload } from "./AccomplishmentHandler";
|
|
11
|
-
import {
|
|
12
|
-
import { Plugin } from "./fromRimori/PluginTypes";
|
|
13
|
-
import { PluginController } from "./PluginController";
|
|
12
|
+
import { PluginController, RimoriInfo } from "./PluginController";
|
|
14
13
|
|
|
15
|
-
interface RimoriClientOptions {
|
|
16
|
-
pluginController: PluginController;
|
|
17
|
-
supabase: SupabaseClient;
|
|
18
|
-
tablePrefix: string;
|
|
19
|
-
pluginId: string;
|
|
20
|
-
}
|
|
21
14
|
|
|
22
15
|
interface Db {
|
|
23
16
|
from: {
|
|
24
17
|
<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
|
|
25
18
|
<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
|
|
26
19
|
};
|
|
27
|
-
storage: SupabaseClient["storage"];
|
|
20
|
+
// storage: SupabaseClient["storage"];
|
|
28
21
|
|
|
29
22
|
// functions: SupabaseClient["functions"];
|
|
30
23
|
/**
|
|
@@ -51,11 +44,26 @@ interface PluginInterface {
|
|
|
51
44
|
*/
|
|
52
45
|
getSettings: <T extends object>(defaultSettings: T) => Promise<T>;
|
|
53
46
|
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
* Retrieves information about plugins, including:
|
|
48
|
+
* - All installed plugins
|
|
49
|
+
* - The currently active plugin in the main panel
|
|
50
|
+
* - The currently active plugin in the side panel
|
|
51
|
+
*/
|
|
52
|
+
getPluginInfo: () => {
|
|
53
|
+
/**
|
|
54
|
+
* All installed plugins.
|
|
55
|
+
*/
|
|
56
|
+
installedPlugins: Plugin[],
|
|
57
|
+
/**
|
|
58
|
+
* The plugin that is loaded in the main panel.
|
|
59
|
+
*/
|
|
60
|
+
mainPanelPlugin?: ActivePlugin,
|
|
61
|
+
/**
|
|
62
|
+
* The plugin that is loaded in the side panel.
|
|
63
|
+
*/
|
|
64
|
+
sidePanelPlugin?: ActivePlugin,
|
|
65
|
+
};
|
|
66
|
+
getUserInfo: () => UserInfo;
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
export class RimoriClient {
|
|
@@ -65,40 +73,44 @@ export class RimoriClient {
|
|
|
65
73
|
private settingsController: SettingsController;
|
|
66
74
|
private sharedContentController: SharedContentController;
|
|
67
75
|
private accomplishmentHandler: AccomplishmentHandler;
|
|
68
|
-
private
|
|
69
|
-
public db: Db;
|
|
76
|
+
private rimoriInfo: RimoriInfo;
|
|
70
77
|
public plugin: PluginInterface;
|
|
78
|
+
public db: Db;
|
|
71
79
|
|
|
72
|
-
private constructor(
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
80
|
+
private constructor(supabase: SupabaseClient, info: RimoriInfo, pluginController: PluginController) {
|
|
81
|
+
this.rimoriInfo = info;
|
|
82
|
+
this.superbase = supabase;
|
|
83
|
+
this.pluginController = pluginController;
|
|
84
|
+
this.settingsController = new SettingsController(supabase, info.pluginId);
|
|
76
85
|
this.sharedContentController = new SharedContentController(this.superbase, this);
|
|
77
|
-
this.
|
|
78
|
-
this.accomplishmentHandler = new AccomplishmentHandler(options.pluginId);
|
|
86
|
+
this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
|
|
79
87
|
|
|
80
88
|
this.from = this.from.bind(this);
|
|
81
89
|
|
|
82
90
|
this.db = {
|
|
83
91
|
from: this.from,
|
|
84
|
-
storage: this.superbase.storage,
|
|
92
|
+
// storage: this.superbase.storage,
|
|
85
93
|
// functions: this.superbase.functions,
|
|
86
|
-
tablePrefix:
|
|
94
|
+
tablePrefix: info.tablePrefix,
|
|
87
95
|
getTableName: this.getTableName.bind(this),
|
|
88
96
|
}
|
|
89
97
|
this.plugin = {
|
|
90
|
-
pluginId:
|
|
98
|
+
pluginId: info.pluginId,
|
|
91
99
|
setSettings: async (settings: any) => {
|
|
92
100
|
await this.settingsController.setSettings(settings);
|
|
93
101
|
},
|
|
94
102
|
getSettings: async <T extends object>(defaultSettings: T): Promise<T> => {
|
|
95
103
|
return await this.settingsController.getSettings<T>(defaultSettings);
|
|
96
104
|
},
|
|
97
|
-
|
|
98
|
-
return
|
|
105
|
+
getUserInfo: (): UserInfo => {
|
|
106
|
+
return this.rimoriInfo.profile;
|
|
99
107
|
},
|
|
100
|
-
|
|
101
|
-
return
|
|
108
|
+
getPluginInfo: () => {
|
|
109
|
+
return {
|
|
110
|
+
installedPlugins: this.rimoriInfo.installedPlugins,
|
|
111
|
+
mainPanelPlugin: this.rimoriInfo.mainPanelPlugin,
|
|
112
|
+
sidePanelPlugin: this.rimoriInfo.sidePanelPlugin,
|
|
113
|
+
}
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
}
|
|
@@ -132,11 +144,11 @@ export class RimoriClient {
|
|
|
132
144
|
* Subscribe to an event.
|
|
133
145
|
* @param topic The topic to subscribe to.
|
|
134
146
|
* @param callback The callback to call when the event is emitted.
|
|
135
|
-
* @returns
|
|
147
|
+
* @returns An EventListener object containing an off() method to unsubscribe the listeners.
|
|
136
148
|
*/
|
|
137
149
|
on: <T = EventPayload>(topic: string | string[], callback: EventHandler<T>) => {
|
|
138
150
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
139
|
-
return topics.map(
|
|
151
|
+
return EventBus.on<T>(topics.map(t => this.pluginController.getGlobalEventTopic(t)), callback);
|
|
140
152
|
},
|
|
141
153
|
/**
|
|
142
154
|
* Subscribe to an event once.
|
|
@@ -151,8 +163,9 @@ export class RimoriClient {
|
|
|
151
163
|
* @param topic The topic to respond to.
|
|
152
164
|
* @param data The data to respond with.
|
|
153
165
|
*/
|
|
154
|
-
respond: <T = EventPayload>(topic: string, data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => {
|
|
155
|
-
|
|
166
|
+
respond: <T = EventPayload>(topic: string | string[], data: EventPayload | ((data: EventBusMessage<T>) => EventPayload | Promise<EventPayload>)) => {
|
|
167
|
+
const topics = Array.isArray(topic) ? topic : [topic];
|
|
168
|
+
EventBus.respond(this.plugin.pluginId, topics.map(t => this.pluginController.getGlobalEventTopic(t)), data);
|
|
156
169
|
},
|
|
157
170
|
/**
|
|
158
171
|
* Emit an accomplishment.
|
|
@@ -176,14 +189,35 @@ export class RimoriClient {
|
|
|
176
189
|
* @param text Optional text to be used for the action like for example text that the translator would look up.
|
|
177
190
|
*/
|
|
178
191
|
emitSidebarAction: (pluginId: string, actionKey: string, text?: string) => {
|
|
179
|
-
this.event.emit("global.sidebar.triggerAction", { pluginId, actionKey, text });
|
|
192
|
+
this.event.emit("global.sidebar.triggerAction", { plugin_id: pluginId, action_key: actionKey, text });
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
onMainPanelAction: (callback: (data: MainPanelAction) => void) => {
|
|
196
|
+
// this needs to be a emit and on because the main panel action is triggered by the user and not by the plugin
|
|
197
|
+
this.event.emit("action.requestMain")
|
|
198
|
+
this.event.on<MainPanelAction>("action.requestMain", ({ data }) => callback(data));
|
|
180
199
|
}
|
|
181
200
|
}
|
|
182
201
|
|
|
202
|
+
public navigation = {
|
|
203
|
+
toDashboard: () => {
|
|
204
|
+
this.event.emit("global.navigation.triggerToDashboard");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get a query parameter value that was passed via MessageChannel
|
|
210
|
+
* @param key The query parameter key
|
|
211
|
+
* @returns The query parameter value or null if not found
|
|
212
|
+
*/
|
|
213
|
+
public getQueryParam(key: string): string | null {
|
|
214
|
+
return this.pluginController.getQueryParam(key);
|
|
215
|
+
}
|
|
216
|
+
|
|
183
217
|
public static async getInstance(pluginController: PluginController): Promise<RimoriClient> {
|
|
184
218
|
if (!RimoriClient.instance) {
|
|
185
|
-
const
|
|
186
|
-
RimoriClient.instance = new RimoriClient(
|
|
219
|
+
const client = await pluginController.getClient();
|
|
220
|
+
RimoriClient.instance = new RimoriClient(client.supabase, client.info, pluginController);
|
|
187
221
|
}
|
|
188
222
|
return RimoriClient.instance;
|
|
189
223
|
}
|
|
@@ -200,33 +234,53 @@ export class RimoriClient {
|
|
|
200
234
|
return this.superbase.from(this.getTableName(relation));
|
|
201
235
|
}
|
|
202
236
|
|
|
203
|
-
private getTableName(
|
|
204
|
-
|
|
237
|
+
private getTableName(table: string) {
|
|
238
|
+
if (/[A-Z]/.test(table)) {
|
|
239
|
+
throw new Error("Table name cannot include uppercase letters. Please use snake_case for table names.");
|
|
240
|
+
}
|
|
241
|
+
if (table.startsWith("global_")) {
|
|
242
|
+
return table.replace("global_", "");
|
|
243
|
+
}
|
|
244
|
+
return this.db.tablePrefix + "_" + table;
|
|
205
245
|
}
|
|
206
246
|
|
|
207
|
-
public
|
|
247
|
+
public ai = {
|
|
208
248
|
getText: async (messages: Message[], tools?: Tool[]): Promise<string> => {
|
|
209
249
|
const token = await this.pluginController.getToken();
|
|
210
|
-
return generateText(this.
|
|
250
|
+
return generateText(this.pluginController.getBackendUrl(), messages, tools || [], token).then(({ messages }) => messages[0].content[0].text);
|
|
211
251
|
},
|
|
212
252
|
getSteamedText: async (messages: Message[], onMessage: OnLLMResponse, tools?: Tool[]) => {
|
|
213
253
|
const token = await this.pluginController.getToken();
|
|
214
|
-
streamChatGPT(this.
|
|
254
|
+
streamChatGPT(this.pluginController.getBackendUrl(), messages, tools || [], onMessage, token);
|
|
215
255
|
},
|
|
216
256
|
getVoice: async (text: string, voice = "alloy", speed = 1, language?: string): Promise<Blob> => {
|
|
217
257
|
const token = await this.pluginController.getToken();
|
|
218
|
-
return getTTSResponse(this.
|
|
258
|
+
return getTTSResponse(this.pluginController.getBackendUrl(), { input: text, voice, speed, language }, token);
|
|
219
259
|
},
|
|
220
|
-
getTextFromVoice: (file: Blob): Promise<string> => {
|
|
221
|
-
|
|
260
|
+
getTextFromVoice: async (file: Blob): Promise<string> => {
|
|
261
|
+
const token = await this.pluginController.getToken();
|
|
262
|
+
return getSTTResponse(this.pluginController.getBackendUrl(), file, token);
|
|
222
263
|
},
|
|
223
264
|
getObject: async (request: ObjectRequest): Promise<any> => {
|
|
224
265
|
const token = await this.pluginController.getToken();
|
|
225
|
-
return
|
|
266
|
+
return generateObject(this.pluginController.getBackendUrl(), request, token);
|
|
226
267
|
},
|
|
227
268
|
// getSteamedObject: this.generateObjectStream,
|
|
228
269
|
}
|
|
229
270
|
|
|
271
|
+
public runtime = {
|
|
272
|
+
fetchBackend: async (url: string, options: RequestInit) => {
|
|
273
|
+
const token = await this.pluginController.getToken();
|
|
274
|
+
return fetch(this.pluginController.getBackendUrl() + url, {
|
|
275
|
+
...options,
|
|
276
|
+
headers: {
|
|
277
|
+
...options.headers,
|
|
278
|
+
'Authorization': `Bearer ${token}`
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
230
284
|
public community = {
|
|
231
285
|
/**
|
|
232
286
|
* Shared content is a way to share completable content with other users using this plugin.
|
|
@@ -258,16 +312,20 @@ export class RimoriClient {
|
|
|
258
312
|
* @param contentType The type of shared content to fetch. E.g. assignments, exercises, etc.
|
|
259
313
|
* @param generatorInstructions The instructions for the creation of new shared content. The object will automatically be extended with a tool property with a topic and keywords property to let a new unique topic be generated.
|
|
260
314
|
* @param filter The optional additional filter for checking new shared content based on a column and value. This is useful if the aditional information stored on the shared content is used to further narrow down the kind of shared content wanted to be received. E.g. only adjective grammar exercises.
|
|
261
|
-
* @param
|
|
315
|
+
* @param options An optional object with options for the new shared content.
|
|
316
|
+
* @param options.privateTopic An optional flag to indicate if the topic should be private and only be visible to the user. This is useful if the topic is not meant to be shared with other users. Like for personal topics or if the content is based on the personal study goal.
|
|
317
|
+
* @param options.skipDbSave An optional flag to indicate if the new shared content should not be saved to the database. This is useful if the new shared content is not meant to be saved to the database.
|
|
318
|
+
* @param options.alwaysGenerateNew An optional flag to indicate if the new shared content should always be generated even if there is already a content with the same filter. This is useful if the new shared content is not meant to be saved to the database.
|
|
319
|
+
* @param options.excludeIds An optional list of ids to exclude from the selection. This is useful if the new shared content is not meant to be saved to the database.
|
|
262
320
|
* @returns The new shared content.
|
|
263
321
|
*/
|
|
264
322
|
getNew: async <T = any>(
|
|
265
323
|
contentType: string,
|
|
266
324
|
generatorInstructions: SharedContentObjectRequest,
|
|
267
325
|
filter?: SharedContentFilter,
|
|
268
|
-
privateTopic?: boolean,
|
|
326
|
+
options?: { privateTopic?: boolean; skipDbSave?: boolean; alwaysGenerateNew?: boolean; excludeIds?: string[] },
|
|
269
327
|
): Promise<SharedContent<T>> => {
|
|
270
|
-
return await this.sharedContentController.getNewSharedContent(contentType, generatorInstructions, filter,
|
|
328
|
+
return await this.sharedContentController.getNewSharedContent(contentType, generatorInstructions, filter, options);
|
|
271
329
|
},
|
|
272
330
|
/**
|
|
273
331
|
* Create a new shared content item.
|
|
@@ -294,6 +352,20 @@ export class RimoriClient {
|
|
|
294
352
|
complete: async (contentType: string, assignmentId: string) => {
|
|
295
353
|
return await this.sharedContentController.completeSharedContent(contentType, assignmentId);
|
|
296
354
|
},
|
|
355
|
+
/**
|
|
356
|
+
/**
|
|
357
|
+
* Update the state of a shared content item for a specific user.
|
|
358
|
+
* Useful for marking content as completed, ongoing, hidden, liked, disliked, or bookmarked.
|
|
359
|
+
*/
|
|
360
|
+
updateState: async (params: {
|
|
361
|
+
contentType: string
|
|
362
|
+
id: string
|
|
363
|
+
state?: 'completed' | 'ongoing' | 'hidden'
|
|
364
|
+
reaction?: 'liked' | 'disliked' | null
|
|
365
|
+
bookmarked?: boolean
|
|
366
|
+
}): Promise<void> => {
|
|
367
|
+
return await this.sharedContentController.updateSharedContentState(params);
|
|
368
|
+
},
|
|
297
369
|
/**
|
|
298
370
|
* Remove a shared content item.
|
|
299
371
|
* @param id The id of the shared content item to remove.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { EventBus } from "./fromRimori/EventBus";
|
|
2
1
|
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { EventBus } from "../fromRimori/EventBus";
|
|
3
|
+
import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from "../utils/endpoint";
|
|
3
4
|
|
|
4
5
|
export interface StandaloneConfig {
|
|
5
6
|
url: string,
|
|
6
|
-
key: string
|
|
7
|
+
key: string,
|
|
8
|
+
backendUrl?: string
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
export class StandaloneClient {
|
|
@@ -18,14 +20,14 @@ export class StandaloneClient {
|
|
|
18
20
|
|
|
19
21
|
public static async getInstance(): Promise<StandaloneClient> {
|
|
20
22
|
if (!StandaloneClient.instance) {
|
|
21
|
-
const config = await fetch("
|
|
23
|
+
const config = await fetch("https://app.rimori.se/config.json").then(res => res.json()).catch(err => {
|
|
22
24
|
console.warn("Error fetching config.json, using default values", err);
|
|
23
|
-
return {
|
|
24
|
-
SUPABASE_URL: "https://pheptqdoqsdnadgoihvr.supabase.co",
|
|
25
|
-
SUPABASE_ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0",
|
|
26
|
-
}
|
|
27
25
|
});
|
|
28
|
-
StandaloneClient.instance = new StandaloneClient({
|
|
26
|
+
StandaloneClient.instance = new StandaloneClient({
|
|
27
|
+
url: config?.SUPABASE_URL || DEFAULT_ENDPOINT,
|
|
28
|
+
key: config?.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY,
|
|
29
|
+
backendUrl: config?.BACKEND_URL || 'https://api.rimori.se',
|
|
30
|
+
});
|
|
29
31
|
}
|
|
30
32
|
return StandaloneClient.instance;
|
|
31
33
|
}
|
|
@@ -58,15 +60,32 @@ export class StandaloneClient {
|
|
|
58
60
|
EventBus.respond("standalone", "global.supabase.requestAccess", async () => {
|
|
59
61
|
const session = await supabase.auth.getSession();
|
|
60
62
|
console.log("session", session);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
|
|
64
|
+
// Call the NestJS backend endpoint instead of the Supabase edge function
|
|
65
|
+
const response = await fetch(`${config.backendUrl}/plugin/token`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
'Authorization': `Bearer ${session.data.session?.access_token}`
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify({
|
|
72
|
+
pluginId: pluginId
|
|
73
|
+
})
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
const errorText = await response.text();
|
|
78
|
+
throw new Error(`Failed to get plugin token. ${response.status}: ${errorText}`);
|
|
64
79
|
}
|
|
80
|
+
|
|
81
|
+
const data = await response.json();
|
|
82
|
+
|
|
65
83
|
return {
|
|
66
84
|
token: data.token,
|
|
67
85
|
pluginId: pluginId,
|
|
68
86
|
url: config.url,
|
|
69
87
|
key: config.key,
|
|
88
|
+
backendUrl: config.backendUrl,
|
|
70
89
|
tablePrefix: pluginId,
|
|
71
90
|
expiration: new Date(Date.now() + 1000 * 60 * 60 * 1.5), // 1.5 hours
|
|
72
91
|
}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
export function setTheme() {
|
|
2
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
3
|
-
|
|
4
|
-
let theme = urlParams.get('theme');
|
|
5
|
-
if (!theme || theme === 'system') {
|
|
6
|
-
theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
7
|
-
}
|
|
8
|
-
|
|
1
|
+
export function setTheme(theme?: string | null) {
|
|
9
2
|
document.documentElement.classList.add("dark:text-gray-200");
|
|
10
3
|
|
|
11
|
-
if (theme
|
|
4
|
+
if (isDarkTheme(theme)) {
|
|
12
5
|
document.documentElement.setAttribute("data-theme", "dark");
|
|
13
6
|
document.documentElement.classList.add('dark', "dark:bg-gray-950");
|
|
14
7
|
document.documentElement.style.background = "hsl(var(--background))";
|
|
15
8
|
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isDarkTheme(theme?: string | null): boolean {
|
|
12
|
+
// If no theme provided, try to get from URL as fallback (for standalone mode)
|
|
13
|
+
if (!theme) {
|
|
14
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
15
|
+
theme = urlParams.get('theme');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!theme || theme === 'system') {
|
|
19
|
+
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return theme === 'dark';
|
|
16
23
|
}
|
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
import React, { createContext, useContext, ReactNode, useEffect, useState } from 'react';
|
|
2
2
|
import { PluginController } from '../plugin/PluginController';
|
|
3
3
|
import { RimoriClient } from '../plugin/RimoriClient';
|
|
4
|
-
import { EventBusHandler } from '../
|
|
5
|
-
import ContextMenu from '../
|
|
4
|
+
import { EventBusHandler } from '../fromRimori/EventBus';
|
|
5
|
+
import ContextMenu from '../components/components/ContextMenu';
|
|
6
6
|
import { StandaloneClient } from '../plugin/StandaloneClient';
|
|
7
7
|
|
|
8
8
|
interface PluginProviderProps {
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
pluginId: string;
|
|
11
|
+
settings?: {
|
|
12
|
+
disableContextMenu?: boolean;
|
|
13
|
+
}
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
const PluginContext = createContext<RimoriClient | null>(null);
|
|
14
17
|
|
|
15
|
-
export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId }) => {
|
|
18
|
+
export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId, settings }) => {
|
|
16
19
|
const [plugin, setPlugin] = useState<RimoriClient | null>(null);
|
|
17
20
|
const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
|
|
21
|
+
const [applicationMode, setApplicationMode] = useState<string | null>(null);
|
|
22
|
+
const [theme, setTheme] = useState<string | null>(null);
|
|
23
|
+
|
|
24
|
+
const isSidebar = applicationMode === "sidebar";
|
|
25
|
+
const isSettings = applicationMode === "settings";
|
|
18
26
|
|
|
19
27
|
useEffect(() => {
|
|
20
28
|
initEventBus(pluginId);
|
|
21
|
-
|
|
29
|
+
|
|
30
|
+
// Check if we're in an iframe context - if not, we're standalone
|
|
31
|
+
const standaloneDetected = window === window.parent;
|
|
32
|
+
|
|
22
33
|
if (standaloneDetected && !standaloneClient) {
|
|
23
34
|
StandaloneClient.getInstance().then(client => {
|
|
24
35
|
client.needsLogin().then((needLogin) => setStandaloneClient(needLogin ? client : true));
|
|
@@ -26,7 +37,16 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
|
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
if ((!standaloneDetected && !plugin) || (standaloneDetected && standaloneClient === true)) {
|
|
29
|
-
PluginController.getInstance(pluginId, standaloneDetected).then(
|
|
40
|
+
PluginController.getInstance(pluginId, standaloneDetected).then(client => {
|
|
41
|
+
setPlugin(client);
|
|
42
|
+
// Get applicationMode and theme from MessageChannel query params
|
|
43
|
+
if (!standaloneDetected) {
|
|
44
|
+
const mode = client.getQueryParam("applicationMode");
|
|
45
|
+
const themeParam = client.getQueryParam("rm_theme");
|
|
46
|
+
setApplicationMode(mode);
|
|
47
|
+
setTheme(themeParam);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
30
50
|
}
|
|
31
51
|
}, [pluginId, standaloneClient]);
|
|
32
52
|
|
|
@@ -34,11 +54,10 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
|
|
|
34
54
|
useEffect(() => {
|
|
35
55
|
if (!plugin) return;
|
|
36
56
|
|
|
37
|
-
const url = new URL(window.location.href);
|
|
38
57
|
//sidebar pages should not report url changes
|
|
39
|
-
if (
|
|
58
|
+
if (isSidebar) return;
|
|
40
59
|
|
|
41
|
-
let lastHash =
|
|
60
|
+
let lastHash = window.location.hash;
|
|
42
61
|
const emitUrlChange = (url: string) => plugin.event.emit('session.triggerUrlChange', { url });
|
|
43
62
|
|
|
44
63
|
const interval = setInterval(() => {
|
|
@@ -73,23 +92,37 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
|
|
|
73
92
|
|
|
74
93
|
return (
|
|
75
94
|
<PluginContext.Provider value={plugin}>
|
|
76
|
-
<ContextMenu client={plugin} />
|
|
95
|
+
{!settings?.disableContextMenu && !isSidebar && !isSettings && <ContextMenu client={plugin} />}
|
|
77
96
|
{children}
|
|
78
97
|
</PluginContext.Provider>
|
|
79
98
|
);
|
|
80
99
|
};
|
|
81
100
|
|
|
82
|
-
export const
|
|
101
|
+
export const useRimori = () => {
|
|
83
102
|
const context = useContext(PluginContext);
|
|
84
103
|
if (context === null) {
|
|
85
|
-
throw new Error('
|
|
104
|
+
throw new Error('useRimori must be used within an PluginProvider');
|
|
86
105
|
}
|
|
87
106
|
return context;
|
|
88
107
|
};
|
|
89
108
|
|
|
90
|
-
function
|
|
109
|
+
function getUrlParam(name: string) {
|
|
110
|
+
// First try to get from URL hash query params (for compatibility)
|
|
111
|
+
const hashParts = window.location.hash.split('?');
|
|
112
|
+
if (hashParts.length > 1) {
|
|
113
|
+
const hashParams = new URLSearchParams(hashParts[1]);
|
|
114
|
+
const hashValue = hashParams.get(name);
|
|
115
|
+
if (hashValue) return hashValue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Fallback to regular URL search params
|
|
91
119
|
const url = new URL(window.location.href);
|
|
92
|
-
|
|
120
|
+
return url.searchParams.get(name);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function initEventBus(pluginId: string) {
|
|
124
|
+
// For now, use URL fallback for EventBus naming - this will be updated once MessageChannel is ready
|
|
125
|
+
const isSidebar = getUrlParam("applicationMode") === "sidebar";
|
|
93
126
|
EventBusHandler.getInstance("Plugin EventBus " + pluginId + " " + (isSidebar ? "sidebar" : "main"));
|
|
94
127
|
}
|
|
95
128
|
|
package/src/utils/Language.ts
CHANGED
|
@@ -63,8 +63,10 @@ export type Language = keyof typeof languageKeys;
|
|
|
63
63
|
/**
|
|
64
64
|
* Get the language name from the language code
|
|
65
65
|
* @param languageCode The code of the language
|
|
66
|
+
* @param capitalize Whether to capitalize the first letter of the language name
|
|
66
67
|
* @returns The language name
|
|
67
68
|
*/
|
|
68
|
-
export function getLanguageName(languageCode: Language): string {
|
|
69
|
-
|
|
69
|
+
export function getLanguageName(languageCode: Language, capitalize: boolean = false): string {
|
|
70
|
+
const lang = languageKeys[languageCode];
|
|
71
|
+
return capitalize ? lang.charAt(0).toUpperCase() + lang.slice(1) : lang;
|
|
70
72
|
}
|
|
@@ -3,13 +3,13 @@ const codes = ["Pre-A1", "A1", "A2", "B1", "B2", "C1", "C2", "Post-C2"];
|
|
|
3
3
|
export type LanguageLevel = "Pre-A1" | "A1" | "A2" | "B1" | "B2" | "C1" | "C2" | "Post-C2";
|
|
4
4
|
|
|
5
5
|
export function getDifficultyLevel(difficulty: LanguageLevel): number {
|
|
6
|
-
|
|
6
|
+
return codes.indexOf(difficulty) + 1;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function getDifficultyLabel(difficulty: number): LanguageLevel {
|
|
10
|
-
|
|
10
|
+
return codes[difficulty] as LanguageLevel;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function getNeighborDifficultyLevel(difficulty: LanguageLevel, difficultyAdjustment: number): LanguageLevel {
|
|
14
|
-
|
|
14
|
+
return getDifficultyLabel(getDifficultyLevel(difficulty) + difficultyAdjustment - 1);
|
|
15
15
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const DEFAULT_ENDPOINT = "https://pheptqdoqsdnadgoihvr.supabase.co";
|
|
2
|
+
export const DEFAULT_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0";
|
|
@@ -1,35 +1,22 @@
|
|
|
1
1
|
import { RimoriClient } from "../plugin/RimoriClient";
|
|
2
|
+
import { EventBusHandler } from "../fromRimori/EventBus";
|
|
2
3
|
import { PluginController } from "../plugin/PluginController";
|
|
3
|
-
import { EventBus, EventBusHandler, EventBusMessage } from "../plugin/fromRimori/EventBus";
|
|
4
|
-
|
|
5
|
-
let controller: RimoriClient | null = null;
|
|
6
|
-
const listeners: ((event: { data: { event: EventBusMessage, secret: string } }) => void)[] = [];
|
|
7
|
-
let debugEnabled = false;
|
|
8
4
|
|
|
9
5
|
/**
|
|
10
6
|
* Sets up the web worker for the plugin to be able receive and send messages to Rimori.
|
|
11
|
-
* @param
|
|
7
|
+
* @param pluginId - The id of the plugin to setup the worker for.
|
|
8
|
+
* @param init - The function containing the initialization logic.
|
|
12
9
|
*/
|
|
13
|
-
export function setupWorker(init: (
|
|
10
|
+
export async function setupWorker(pluginId: string, init: (client: RimoriClient) => void | Promise<void>) {
|
|
11
|
+
|
|
14
12
|
// Mock of the window object for the worker context to be able to use the PluginController.
|
|
15
13
|
const mockWindow = {
|
|
16
14
|
isWorker: true,
|
|
17
|
-
location: {
|
|
15
|
+
location: {},
|
|
18
16
|
parent: {
|
|
19
|
-
postMessage: (
|
|
20
|
-
message.event.sender = "worker." + message.event.sender;
|
|
21
|
-
checkDebugMode(message.event);
|
|
22
|
-
logIfDebug('sending event to Rimori', message.event);
|
|
23
|
-
self.postMessage(message)
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
addEventListener: (_: string, listener: any) => {
|
|
27
|
-
listeners.push(listener);
|
|
28
|
-
},
|
|
29
|
-
APP_CONFIG: {
|
|
30
|
-
SUPABASE_URL: 'NOT_SET',
|
|
31
|
-
SUPABASE_ANON_KEY: 'NOT_SET',
|
|
17
|
+
postMessage: () => { }
|
|
32
18
|
},
|
|
19
|
+
addEventListener: () => { }
|
|
33
20
|
};
|
|
34
21
|
|
|
35
22
|
// Assign the mock to globalThis.
|
|
@@ -37,45 +24,11 @@ export function setupWorker(init: (controller: RimoriClient) => void | Promise<v
|
|
|
37
24
|
|
|
38
25
|
EventBusHandler.getInstance("Worker EventBus");
|
|
39
26
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
checkDebugMode(response.data);
|
|
43
|
-
logIfDebug('Message received', response.data);
|
|
44
|
-
|
|
45
|
-
const event = response.data as EventBusMessage;
|
|
46
|
-
|
|
47
|
-
if (event.topic === 'global.worker.requestInit') {
|
|
48
|
-
if (!controller) {
|
|
49
|
-
mockWindow.APP_CONFIG.SUPABASE_URL = event.data.supabaseUrl;
|
|
50
|
-
mockWindow.APP_CONFIG.SUPABASE_ANON_KEY = event.data.supabaseAnonKey;
|
|
51
|
-
controller = await PluginController.getInstance(event.data.pluginId);
|
|
52
|
-
logIfDebug('Worker initialized.');
|
|
53
|
-
await init(controller);
|
|
54
|
-
logIfDebug('Plugin listeners initialized.');
|
|
55
|
-
}
|
|
56
|
-
const initEvent: EventBusMessage = {
|
|
57
|
-
timestamp: new Date().toISOString(),
|
|
58
|
-
eventId: event.eventId,
|
|
59
|
-
sender: "worker." + event.sender,
|
|
60
|
-
topic: 'global.worker.requestInit',
|
|
61
|
-
data: { success: true },
|
|
62
|
-
debug: debugEnabled
|
|
63
|
-
};
|
|
64
|
-
return self.postMessage({ secret: "123", event: initEvent });
|
|
65
|
-
}
|
|
66
|
-
listeners.forEach(listener => listener({ data: { event: response.data, secret: "123" } }));
|
|
67
|
-
};
|
|
68
|
-
}
|
|
27
|
+
const rimoriClient = await PluginController.getInstance(pluginId);
|
|
28
|
+
console.debug('[Worker] RimoriClient initialized.');
|
|
69
29
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
debugEnabled = true;
|
|
73
|
-
EventBus.emit("worker", "global.system.requestDebug");
|
|
74
|
-
}
|
|
75
|
-
}
|
|
30
|
+
await init(rimoriClient);
|
|
31
|
+
console.debug('[Worker] Worker initialized.');
|
|
76
32
|
|
|
77
|
-
|
|
78
|
-
if (debugEnabled) {
|
|
79
|
-
console.debug('[Worker] ' + args[0], ...args.slice(1));
|
|
80
|
-
}
|
|
33
|
+
self.postMessage({ type: "rimori:acknowledged", pluginId: pluginId });
|
|
81
34
|
}
|