@rimori/client 2.5.29-next.0 → 2.5.29-next.1
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/dist/controller/AccomplishmentController.d.ts +3 -2
- package/dist/controller/AccomplishmentController.js +4 -3
- package/dist/controller/TranslationController.js +4 -3
- package/dist/fromRimori/EventBus.d.ts +9 -0
- package/dist/fromRimori/EventBus.js +22 -1
- package/dist/fromRimori/PluginTypes.d.ts +2 -0
- package/dist/plugin/CommunicationHandler.d.ts +2 -1
- package/dist/plugin/CommunicationHandler.js +4 -2
- package/dist/plugin/RimoriClient.d.ts +10 -0
- package/dist/plugin/RimoriClient.js +32 -4
- package/dist/plugin/module/EventModule.d.ts +3 -2
- package/dist/plugin/module/EventModule.js +20 -13
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventBusMessage } from '../fromRimori/EventBus';
|
|
1
|
+
import { EventBusHandler, EventBusMessage } from '../fromRimori/EventBus';
|
|
2
2
|
export type AccomplishmentMessage = EventBusMessage<MicroAccomplishmentPayload>;
|
|
3
3
|
export declare const skillCategories: readonly ["reading", "listening", "speaking", "writing", "learning", "community"];
|
|
4
4
|
interface BaseAccomplishmentPayload {
|
|
@@ -23,7 +23,8 @@ export interface MacroAccomplishmentPayload extends BaseAccomplishmentPayload {
|
|
|
23
23
|
export type AccomplishmentPayload = MicroAccomplishmentPayload | MacroAccomplishmentPayload;
|
|
24
24
|
export declare class AccomplishmentController {
|
|
25
25
|
private pluginId;
|
|
26
|
-
|
|
26
|
+
private eventBus;
|
|
27
|
+
constructor(pluginId: string, eventBus?: EventBusHandler);
|
|
27
28
|
emitAccomplishment(payload: Omit<AccomplishmentPayload, 'type'>): void;
|
|
28
29
|
private validateAccomplishment;
|
|
29
30
|
private sanitizeAccomplishment;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { EventBus } from '../fromRimori/EventBus';
|
|
2
2
|
export const skillCategories = ['reading', 'listening', 'speaking', 'writing', 'learning', 'community'];
|
|
3
3
|
export class AccomplishmentController {
|
|
4
|
-
constructor(pluginId) {
|
|
4
|
+
constructor(pluginId, eventBus) {
|
|
5
5
|
this.pluginId = pluginId;
|
|
6
|
+
this.eventBus = eventBus !== null && eventBus !== void 0 ? eventBus : EventBus;
|
|
6
7
|
}
|
|
7
8
|
emitAccomplishment(payload) {
|
|
8
9
|
const accomplishmentPayload = Object.assign(Object.assign({}, payload), { type: 'durationMinutes' in payload ? 'macro' : 'micro' });
|
|
@@ -11,7 +12,7 @@ export class AccomplishmentController {
|
|
|
11
12
|
}
|
|
12
13
|
const sanitizedPayload = this.sanitizeAccomplishment(accomplishmentPayload);
|
|
13
14
|
const topic = 'global.accomplishment.trigger' + (accomplishmentPayload.type === 'macro' ? 'Macro' : 'Micro');
|
|
14
|
-
|
|
15
|
+
this.eventBus.emit(this.pluginId, topic, sanitizedPayload);
|
|
15
16
|
}
|
|
16
17
|
validateAccomplishment(payload) {
|
|
17
18
|
if (!skillCategories.includes(payload.skillCategory)) {
|
|
@@ -85,7 +86,7 @@ export class AccomplishmentController {
|
|
|
85
86
|
else if (topicLength !== 3) {
|
|
86
87
|
throw new Error('Invalid accomplishment topic pattern. The pattern must be plugin.skillCategory.accomplishmentKeyword or an * as wildcard for any plugin, skill category or accomplishment keyword');
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
+
this.eventBus.on(['global.accomplishment.triggerMicro', 'global.accomplishment.triggerMacro'], (event) => {
|
|
89
90
|
const { plugin, skillCategory, accomplishmentKeyword } = this.getDecoupledTopic(accomplishmentTopic);
|
|
90
91
|
if (plugin !== '*' && event.sender !== plugin)
|
|
91
92
|
return;
|
|
@@ -79,12 +79,13 @@ export class Translator {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
getTranslationUrl(language) {
|
|
82
|
+
const baseUrl = this.translationUrl || window.location.origin;
|
|
82
83
|
// For localhost development, use local- prefix for non-English languages
|
|
83
|
-
if (window.location.hostname === 'localhost') {
|
|
84
|
+
if (window.location.hostname === 'localhost' || new URL(baseUrl).hostname === 'localhost') {
|
|
84
85
|
const filename = language !== 'en' ? `local-${language}` : language;
|
|
85
|
-
return `${
|
|
86
|
+
return `${baseUrl}/locales/${filename}.json`;
|
|
86
87
|
}
|
|
87
|
-
return `${
|
|
88
|
+
return `${baseUrl}/locales/${language}.json`;
|
|
88
89
|
}
|
|
89
90
|
usePlugin(plugin) {
|
|
90
91
|
if (!this.i18n) {
|
|
@@ -29,6 +29,11 @@ export declare class EventBusHandler {
|
|
|
29
29
|
private generatedIds;
|
|
30
30
|
private cleanupInterval;
|
|
31
31
|
private constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new non-singleton EventBusHandler instance.
|
|
34
|
+
* Used in federation mode where each plugin needs its own isolated EventBus.
|
|
35
|
+
*/
|
|
36
|
+
static create(name?: string): EventBusHandler;
|
|
32
37
|
static getInstance(name?: string): EventBusHandler;
|
|
33
38
|
/**
|
|
34
39
|
* Starts the interval to cleanup the generated ids.
|
|
@@ -109,6 +114,10 @@ export declare class EventBusHandler {
|
|
|
109
114
|
*/
|
|
110
115
|
private validateTopic;
|
|
111
116
|
private logIfDebug;
|
|
117
|
+
/**
|
|
118
|
+
* Destroys this EventBus instance, cleaning up all listeners and intervals.
|
|
119
|
+
*/
|
|
120
|
+
destroy(): void;
|
|
112
121
|
private logAndThrowError;
|
|
113
122
|
}
|
|
114
123
|
export declare const EventBus: EventBusHandler;
|
|
@@ -15,9 +15,18 @@ export class EventBusHandler {
|
|
|
15
15
|
this.evName = '';
|
|
16
16
|
this.generatedIds = new Map(); // Map<id, timestamp>
|
|
17
17
|
this.cleanupInterval = null;
|
|
18
|
-
//private constructor
|
|
19
18
|
this.startIdCleanup();
|
|
20
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new non-singleton EventBusHandler instance.
|
|
22
|
+
* Used in federation mode where each plugin needs its own isolated EventBus.
|
|
23
|
+
*/
|
|
24
|
+
static create(name) {
|
|
25
|
+
const instance = new EventBusHandler();
|
|
26
|
+
if (name)
|
|
27
|
+
instance.evName = name;
|
|
28
|
+
return instance;
|
|
29
|
+
}
|
|
21
30
|
static getInstance(name) {
|
|
22
31
|
if (!EventBusHandler.instance) {
|
|
23
32
|
EventBusHandler.instance = new EventBusHandler();
|
|
@@ -307,6 +316,18 @@ export class EventBusHandler {
|
|
|
307
316
|
console.debug(`[${this.evName}] ` + args[0], ...args.slice(1));
|
|
308
317
|
}
|
|
309
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Destroys this EventBus instance, cleaning up all listeners and intervals.
|
|
321
|
+
*/
|
|
322
|
+
destroy() {
|
|
323
|
+
this.listeners.clear();
|
|
324
|
+
this.responseResolvers.clear();
|
|
325
|
+
if (this.cleanupInterval) {
|
|
326
|
+
clearInterval(this.cleanupInterval);
|
|
327
|
+
this.cleanupInterval = null;
|
|
328
|
+
}
|
|
329
|
+
this.generatedIds.clear();
|
|
330
|
+
}
|
|
310
331
|
logAndThrowError(throwError, ...args) {
|
|
311
332
|
const message = `[${this.evName}] ` + args[0];
|
|
312
333
|
console.error(message, ...args.slice(1));
|
|
@@ -86,6 +86,8 @@ export interface RimoriPluginConfig<T extends object = object> {
|
|
|
86
86
|
sidebar: (SidebarPage & T)[];
|
|
87
87
|
/** Optional path to the plugin's settings/configuration page */
|
|
88
88
|
settings?: string;
|
|
89
|
+
/** When true, rimori-main loads this plugin via Module Federation instead of an iframe. */
|
|
90
|
+
federated?: boolean;
|
|
89
91
|
/** Optional array of event topics the plugin pages can listen to for cross-plugin communication */
|
|
90
92
|
topics?: string[];
|
|
91
93
|
};
|
|
@@ -67,8 +67,9 @@ export declare class RimoriCommunicationHandler {
|
|
|
67
67
|
/**
|
|
68
68
|
* Handles updates to RimoriInfo from rimori-main.
|
|
69
69
|
* Updates the cached info and Supabase client, then notifies all registered callbacks.
|
|
70
|
+
* Public so that federated mode can call it when the update event arrives via the plugin's isolated EventBus.
|
|
70
71
|
*/
|
|
71
|
-
|
|
72
|
+
handleRimoriInfoUpdate(newInfo: RimoriInfo): void;
|
|
72
73
|
/**
|
|
73
74
|
* Registers a callback to be called when RimoriInfo is updated.
|
|
74
75
|
* @param callback - Function to call with the new RimoriInfo
|
|
@@ -77,7 +77,7 @@ export class RimoriCommunicationHandler {
|
|
|
77
77
|
// Listen for updates from rimori-main (data changes, token refresh, etc.)
|
|
78
78
|
// Topic format: {pluginId}.supabase.triggerUpdate
|
|
79
79
|
EventBus.on(`${this.pluginId}.supabase.triggerUpdate`, (ev) => {
|
|
80
|
-
// console.log('[RimoriCommunicationHandler] Received
|
|
80
|
+
// console.log('[RimoriCommunicationHandler] Received triggerUpdate via MessageChannel for', this.pluginId);
|
|
81
81
|
this.handleRimoriInfoUpdate(ev.data);
|
|
82
82
|
});
|
|
83
83
|
// Mark MessageChannel as ready and process pending requests
|
|
@@ -205,12 +205,14 @@ export class RimoriCommunicationHandler {
|
|
|
205
205
|
/**
|
|
206
206
|
* Handles updates to RimoriInfo from rimori-main.
|
|
207
207
|
* Updates the cached info and Supabase client, then notifies all registered callbacks.
|
|
208
|
+
* Public so that federated mode can call it when the update event arrives via the plugin's isolated EventBus.
|
|
208
209
|
*/
|
|
209
210
|
handleRimoriInfoUpdate(newInfo) {
|
|
210
211
|
if (JSON.stringify(this.rimoriInfo) === JSON.stringify(newInfo)) {
|
|
211
|
-
// console.log('[RimoriCommunicationHandler] RimoriInfo update
|
|
212
|
+
// console.log('[RimoriCommunicationHandler] RimoriInfo update identical to cached info, skipping', this.pluginId);
|
|
212
213
|
return;
|
|
213
214
|
}
|
|
215
|
+
// console.log('[RimoriCommunicationHandler] Applying RimoriInfo update for', this.pluginId, '| ttsEnabled:', newInfo.ttsEnabled);
|
|
214
216
|
// Update cached rimoriInfo
|
|
215
217
|
this.rimoriInfo = newInfo;
|
|
216
218
|
// Update Supabase client with new token
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { SharedContentController } from './module/SharedContentController';
|
|
2
|
+
import { RimoriInfo } from './CommunicationHandler';
|
|
2
3
|
import { PluginModule } from './module/PluginModule';
|
|
3
4
|
import { DbModule } from './module/DbModule';
|
|
4
5
|
import { EventModule } from './module/EventModule';
|
|
5
6
|
import { AIModule } from './module/AIModule';
|
|
6
7
|
import { ExerciseModule } from './module/ExerciseModule';
|
|
7
8
|
import { StorageModule } from './module/StorageModule';
|
|
9
|
+
import { EventBusHandler } from '../fromRimori/EventBus';
|
|
8
10
|
export declare class RimoriClient {
|
|
9
11
|
private static instance;
|
|
10
12
|
sharedContent: SharedContentController;
|
|
@@ -16,7 +18,15 @@ export declare class RimoriClient {
|
|
|
16
18
|
/** Upload and manage images stored in Supabase via the backend. */
|
|
17
19
|
storage: StorageModule;
|
|
18
20
|
private rimoriInfo;
|
|
21
|
+
/** The EventBus instance used by this client. In federation mode this is a per-plugin instance. */
|
|
22
|
+
eventBus: EventBusHandler;
|
|
19
23
|
private constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Creates a RimoriClient with pre-existing RimoriInfo (federation mode).
|
|
26
|
+
* Uses a fresh per-plugin EventBus instance instead of the global singleton.
|
|
27
|
+
* Creates the Supabase PostgrestClient internally from the info.
|
|
28
|
+
*/
|
|
29
|
+
static createWithInfo(info: RimoriInfo): RimoriClient;
|
|
20
30
|
static getInstance(pluginId?: string): Promise<RimoriClient>;
|
|
21
31
|
navigation: {
|
|
22
32
|
toDashboard: () => void;
|
|
@@ -16,9 +16,10 @@ import { EventModule } from './module/EventModule';
|
|
|
16
16
|
import { AIModule } from './module/AIModule';
|
|
17
17
|
import { ExerciseModule } from './module/ExerciseModule';
|
|
18
18
|
import { StorageModule } from './module/StorageModule';
|
|
19
|
-
import {
|
|
19
|
+
import { PostgrestClient } from '@supabase/postgrest-js';
|
|
20
|
+
import { EventBus, EventBusHandler } from '../fromRimori/EventBus';
|
|
20
21
|
export class RimoriClient {
|
|
21
|
-
constructor(controller, supabase, info) {
|
|
22
|
+
constructor(controller, supabase, info, eventBus) {
|
|
22
23
|
this.navigation = {
|
|
23
24
|
toDashboard: () => {
|
|
24
25
|
this.event.emit('global.navigation.triggerToDashboard');
|
|
@@ -30,12 +31,13 @@ export class RimoriClient {
|
|
|
30
31
|
}),
|
|
31
32
|
};
|
|
32
33
|
this.rimoriInfo = info;
|
|
34
|
+
this.eventBus = eventBus !== null && eventBus !== void 0 ? eventBus : EventBus;
|
|
33
35
|
this.sharedContent = new SharedContentController(supabase, this);
|
|
34
36
|
this.ai = new AIModule(info.backendUrl, () => this.rimoriInfo.token, info.pluginId);
|
|
35
37
|
this.ai.setOnRateLimited((exercisesRemaining) => {
|
|
36
|
-
|
|
38
|
+
this.eventBus.emit(info.pluginId, 'global.quota.triggerExceeded', { exercises_remaining: exercisesRemaining });
|
|
37
39
|
});
|
|
38
|
-
this.event = new EventModule(info.pluginId, info.backendUrl, () => this.rimoriInfo.token, this.ai);
|
|
40
|
+
this.event = new EventModule(info.pluginId, info.backendUrl, () => this.rimoriInfo.token, this.ai, this.eventBus);
|
|
39
41
|
this.db = new DbModule(supabase, controller, info);
|
|
40
42
|
this.plugin = new PluginModule(supabase, controller, info, this.ai);
|
|
41
43
|
this.exercise = new ExerciseModule(supabase, controller, info, this.event);
|
|
@@ -48,6 +50,32 @@ export class RimoriClient {
|
|
|
48
50
|
Logger.getInstance(this);
|
|
49
51
|
}
|
|
50
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Creates a RimoriClient with pre-existing RimoriInfo (federation mode).
|
|
55
|
+
* Uses a fresh per-plugin EventBus instance instead of the global singleton.
|
|
56
|
+
* Creates the Supabase PostgrestClient internally from the info.
|
|
57
|
+
*/
|
|
58
|
+
static createWithInfo(info) {
|
|
59
|
+
const eventBus = EventBusHandler.create('Plugin EventBus ' + info.pluginId);
|
|
60
|
+
const controller = new RimoriCommunicationHandler(info.pluginId, true);
|
|
61
|
+
const supabase = new PostgrestClient(`${info.url}/rest/v1`, {
|
|
62
|
+
schema: info.dbSchema,
|
|
63
|
+
headers: {
|
|
64
|
+
apikey: info.key,
|
|
65
|
+
Authorization: `Bearer ${info.token}`,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const client = new RimoriClient(controller, supabase, info, eventBus);
|
|
69
|
+
// In federated mode, CommunicationHandler skips MessageChannel setup so it never
|
|
70
|
+
// subscribes to triggerUpdate events. PluginEventBridge forwards host-bus events to
|
|
71
|
+
// this plugin's isolated eventBus, so we listen here and hand off to the controller.
|
|
72
|
+
eventBus.on(`${info.pluginId}.supabase.triggerUpdate`, (ev) => {
|
|
73
|
+
var _a;
|
|
74
|
+
console.log('[RimoriClient] Federated triggerUpdate received for', info.pluginId, '| ttsEnabled:', (_a = ev.data) === null || _a === void 0 ? void 0 : _a.ttsEnabled);
|
|
75
|
+
controller.handleRimoriInfoUpdate(ev.data);
|
|
76
|
+
});
|
|
77
|
+
return client;
|
|
78
|
+
}
|
|
51
79
|
static getInstance(pluginId) {
|
|
52
80
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
81
|
if (!RimoriClient.instance) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MainPanelAction, SidebarAction } from '../../fromRimori/PluginTypes';
|
|
2
2
|
import { AccomplishmentPayload } from '../../controller/AccomplishmentController';
|
|
3
|
-
import { EventBusMessage, EventHandler, EventPayload, EventListener } from '../../fromRimori/EventBus';
|
|
3
|
+
import { EventBusHandler, EventBusMessage, EventHandler, EventPayload, EventListener } from '../../fromRimori/EventBus';
|
|
4
4
|
import { AIModule } from './AIModule';
|
|
5
5
|
/**
|
|
6
6
|
* Event module for plugin event bus operations.
|
|
@@ -12,7 +12,8 @@ export declare class EventModule {
|
|
|
12
12
|
private aiModule;
|
|
13
13
|
private backendUrl;
|
|
14
14
|
private getToken;
|
|
15
|
-
|
|
15
|
+
private eventBus;
|
|
16
|
+
constructor(pluginId: string, backendUrl: string, getToken: () => string, aiModule: AIModule, eventBus?: EventBusHandler);
|
|
16
17
|
getGlobalEventTopic(preliminaryTopic: string): string;
|
|
17
18
|
/**
|
|
18
19
|
* Emit an event to Rimori or a plugin.
|
|
@@ -14,12 +14,13 @@ import { EventBus } from '../../fromRimori/EventBus';
|
|
|
14
14
|
* Provides methods for emitting, listening to, and responding to events.
|
|
15
15
|
*/
|
|
16
16
|
export class EventModule {
|
|
17
|
-
constructor(pluginId, backendUrl, getToken, aiModule) {
|
|
17
|
+
constructor(pluginId, backendUrl, getToken, aiModule, eventBus) {
|
|
18
18
|
this.pluginId = pluginId;
|
|
19
19
|
this.backendUrl = backendUrl;
|
|
20
20
|
this.getToken = getToken;
|
|
21
21
|
this.aiModule = aiModule;
|
|
22
|
-
this.
|
|
22
|
+
this.eventBus = eventBus !== null && eventBus !== void 0 ? eventBus : EventBus;
|
|
23
|
+
this.accomplishmentController = new AccomplishmentController(pluginId, this.eventBus);
|
|
23
24
|
}
|
|
24
25
|
getGlobalEventTopic(preliminaryTopic) {
|
|
25
26
|
var _a;
|
|
@@ -54,7 +55,7 @@ export class EventModule {
|
|
|
54
55
|
*/
|
|
55
56
|
emit(topic, data, eventId) {
|
|
56
57
|
const globalTopic = this.getGlobalEventTopic(topic);
|
|
57
|
-
|
|
58
|
+
this.eventBus.emit(this.pluginId, globalTopic, data, eventId);
|
|
58
59
|
}
|
|
59
60
|
/**
|
|
60
61
|
* Request an event.
|
|
@@ -68,7 +69,7 @@ export class EventModule {
|
|
|
68
69
|
const globalTopic = this.getGlobalEventTopic(topic);
|
|
69
70
|
yield this.aiModule.session.ensure();
|
|
70
71
|
const sessionToken = (_a = this.aiModule.session.get()) !== null && _a !== void 0 ? _a : undefined;
|
|
71
|
-
return
|
|
72
|
+
return this.eventBus.request(this.pluginId, globalTopic, data, sessionToken);
|
|
72
73
|
});
|
|
73
74
|
}
|
|
74
75
|
/**
|
|
@@ -79,7 +80,7 @@ export class EventModule {
|
|
|
79
80
|
*/
|
|
80
81
|
on(topic, callback) {
|
|
81
82
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
82
|
-
return
|
|
83
|
+
return this.eventBus.on(topics.map((t) => this.getGlobalEventTopic(t)), (event) => {
|
|
83
84
|
if (event.ai_session_token && !this.aiModule.session.get()) {
|
|
84
85
|
this.aiModule.session.set(event.ai_session_token);
|
|
85
86
|
}
|
|
@@ -92,7 +93,7 @@ export class EventModule {
|
|
|
92
93
|
* @param callback The callback to call when the event is emitted.
|
|
93
94
|
*/
|
|
94
95
|
once(topic, callback) {
|
|
95
|
-
|
|
96
|
+
this.eventBus.once(this.getGlobalEventTopic(topic), callback);
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
99
|
* Respond to an event.
|
|
@@ -124,7 +125,7 @@ export class EventModule {
|
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
|
-
|
|
128
|
+
this.eventBus.respond(this.pluginId, topics.map((t) => this.getGlobalEventTopic(t)), wrappedData);
|
|
128
129
|
}
|
|
129
130
|
/**
|
|
130
131
|
* Emit an accomplishment.
|
|
@@ -219,15 +220,21 @@ export class EventModule {
|
|
|
219
220
|
*/
|
|
220
221
|
onSidePanelAction(callback, actionsToListen = []) {
|
|
221
222
|
const listeningActions = Array.isArray(actionsToListen) ? actionsToListen : [actionsToListen];
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
// console.log('Listening to actions', listeningActions);
|
|
223
|
+
// Register the listener BEFORE emitting the request, so the synchronous response
|
|
224
|
+
// from the bridge/responder is captured (emit → bridge outbound → host respond → bridge inbound is synchronous).
|
|
225
|
+
console.log('[EventModule] onSidePanelAction: setting up listener for', this.pluginId, 'listening to:', listeningActions);
|
|
226
|
+
const listener = this.on('action.requestSidebar', ({ data }) => {
|
|
227
|
+
console.log('[EventModule] onSidePanelAction: received event', { data, listeningActions });
|
|
228
228
|
if (listeningActions.length === 0 || listeningActions.includes(data.action)) {
|
|
229
|
+
console.log('[EventModule] onSidePanelAction: action matched, calling callback');
|
|
229
230
|
callback(data);
|
|
230
231
|
}
|
|
232
|
+
else {
|
|
233
|
+
console.log('[EventModule] onSidePanelAction: action NOT matched. Got:', data.action, 'expected:', listeningActions);
|
|
234
|
+
}
|
|
231
235
|
});
|
|
236
|
+
console.log('[EventModule] onSidePanelAction: emitting action.requestSidebar for', this.pluginId);
|
|
237
|
+
this.emit('action.requestSidebar');
|
|
238
|
+
return listener;
|
|
232
239
|
}
|
|
233
240
|
}
|