@todesktop/plugin-recall 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.d.ts +9 -4
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +183 -364
- package/dist/main.js.map +1 -1
- package/dist/preload.js +14 -14
- package/dist/shared.d.ts +41 -6
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js.map +1 -1
- package/dist/store.d.ts +10 -82
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +14 -7
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
- package/src/main.ts +314 -327
- package/src/shared.ts +74 -39
- package/src/store.ts +41 -166
package/dist/main.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
var electron = require('electron');
|
|
6
|
+
var RecallAiSdk = require('@recallai/desktop-sdk');
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Shared types and constants for Recall Desktop SDK integration
|
|
@@ -8,32 +11,32 @@ var electron = require('electron');
|
|
|
8
11
|
// IPC channel names - use unique namespace to avoid conflicts
|
|
9
12
|
const IPC_CHANNELS = {
|
|
10
13
|
// SDK lifecycle
|
|
11
|
-
INIT_SDK:
|
|
12
|
-
SHUTDOWN_SDK:
|
|
13
|
-
GET_STATUS:
|
|
14
|
+
INIT_SDK: "recall-desktop:init-sdk",
|
|
15
|
+
SHUTDOWN_SDK: "recall-desktop:shutdown-sdk",
|
|
16
|
+
GET_STATUS: "recall-desktop:get-status",
|
|
14
17
|
// Recording management
|
|
15
|
-
START_RECORDING:
|
|
16
|
-
STOP_RECORDING:
|
|
17
|
-
PAUSE_RECORDING:
|
|
18
|
-
RESUME_RECORDING:
|
|
19
|
-
UPLOAD_RECORDING:
|
|
18
|
+
START_RECORDING: "recall-desktop:start-recording",
|
|
19
|
+
STOP_RECORDING: "recall-desktop:stop-recording",
|
|
20
|
+
PAUSE_RECORDING: "recall-desktop:pause-recording",
|
|
21
|
+
RESUME_RECORDING: "recall-desktop:resume-recording",
|
|
22
|
+
UPLOAD_RECORDING: "recall-desktop:upload-recording",
|
|
20
23
|
// Desktop audio recording
|
|
21
|
-
PREPARE_DESKTOP_AUDIO:
|
|
24
|
+
PREPARE_DESKTOP_AUDIO: "recall-desktop:prepare-desktop-audio",
|
|
22
25
|
// Permission management
|
|
23
|
-
REQUEST_PERMISSION:
|
|
26
|
+
REQUEST_PERMISSION: "recall-desktop:request-permission",
|
|
24
27
|
// Configuration
|
|
25
|
-
SET_CONFIG:
|
|
26
|
-
GET_CONFIG:
|
|
28
|
+
SET_CONFIG: "recall-desktop:set-config",
|
|
29
|
+
GET_CONFIG: "recall-desktop:get-config",
|
|
27
30
|
// Event subscription
|
|
28
|
-
SUBSCRIBE_EVENTS:
|
|
29
|
-
UNSUBSCRIBE_EVENTS:
|
|
31
|
+
SUBSCRIBE_EVENTS: "recall-desktop:subscribe-events",
|
|
32
|
+
UNSUBSCRIBE_EVENTS: "recall-desktop:unsubscribe-events",
|
|
30
33
|
};
|
|
31
34
|
// Error types
|
|
32
35
|
class RecallSdkError extends Error {
|
|
33
36
|
constructor(message, code) {
|
|
34
37
|
super(message);
|
|
35
38
|
this.code = code;
|
|
36
|
-
this.name =
|
|
39
|
+
this.name = "RecallSdkError";
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -49,19 +52,6 @@ class RecallSdkStore {
|
|
|
49
52
|
};
|
|
50
53
|
this.initialized = false;
|
|
51
54
|
this.sdkInitialized = false;
|
|
52
|
-
this.currentSdkState = 'idle';
|
|
53
|
-
// Active meetings and recordings
|
|
54
|
-
this.activeMeetings = new Map();
|
|
55
|
-
this.activeRecordings = new Map();
|
|
56
|
-
// Permission status
|
|
57
|
-
this.permissions = {
|
|
58
|
-
accessibility: false,
|
|
59
|
-
screenCapture: false,
|
|
60
|
-
microphone: false,
|
|
61
|
-
systemAudio: false,
|
|
62
|
-
};
|
|
63
|
-
// Event listeners for SDK events
|
|
64
|
-
this.eventListeners = new Set();
|
|
65
55
|
}
|
|
66
56
|
/**
|
|
67
57
|
* Initialize the plugin store
|
|
@@ -132,148 +122,33 @@ class RecallSdkStore {
|
|
|
132
122
|
isSdkInitialized() {
|
|
133
123
|
return this.sdkInitialized;
|
|
134
124
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Set current SDK state
|
|
137
|
-
*/
|
|
138
|
-
setSdkState(state) {
|
|
139
|
-
this.currentSdkState = state;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Get current SDK state
|
|
143
|
-
*/
|
|
144
|
-
getSdkState() {
|
|
145
|
-
return this.currentSdkState;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Add an active meeting
|
|
149
|
-
*/
|
|
150
|
-
addMeeting(meeting) {
|
|
151
|
-
this.activeMeetings.set(meeting.id, meeting);
|
|
152
|
-
console.log(`RecallSdkStore: Added meeting ${meeting.id}:`, meeting);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Remove a meeting
|
|
156
|
-
*/
|
|
157
|
-
removeMeeting(windowId) {
|
|
158
|
-
this.activeMeetings.delete(windowId);
|
|
159
|
-
console.log(`RecallSdkStore: Removed meeting ${windowId}`);
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Get active meeting by window ID
|
|
163
|
-
*/
|
|
164
|
-
getMeeting(windowId) {
|
|
165
|
-
return this.activeMeetings.get(windowId);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Get all active meetings
|
|
169
|
-
*/
|
|
170
|
-
getAllMeetings() {
|
|
171
|
-
return Array.from(this.activeMeetings.values());
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Start a recording
|
|
175
|
-
*/
|
|
176
|
-
startRecording(windowId, uploadToken) {
|
|
177
|
-
const window = this.activeMeetings.get(windowId);
|
|
178
|
-
if (window) {
|
|
179
|
-
this.activeRecordings.set(windowId, { window, uploadToken });
|
|
180
|
-
console.log(`RecallSdkStore: Started recording for ${windowId}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Stop a recording
|
|
185
|
-
*/
|
|
186
|
-
stopRecording(windowId) {
|
|
187
|
-
this.activeRecordings.delete(windowId);
|
|
188
|
-
console.log(`RecallSdkStore: Stopped recording for ${windowId}`);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Get active recording by window ID
|
|
192
|
-
*/
|
|
193
|
-
getRecording(windowId) {
|
|
194
|
-
return this.activeRecordings.get(windowId);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Get all active recordings
|
|
198
|
-
*/
|
|
199
|
-
getAllRecordings() {
|
|
200
|
-
return Array.from(this.activeRecordings.values());
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Update permission status
|
|
204
|
-
*/
|
|
205
|
-
setPermissionStatus(permission, status) {
|
|
206
|
-
const granted = status === 'granted' || status === 'authorized' || status === 'ALLOWED';
|
|
207
|
-
if (permission === 'screen-capture') {
|
|
208
|
-
this.permissions.screenCapture = granted;
|
|
209
|
-
}
|
|
210
|
-
else if (permission === 'system-audio') {
|
|
211
|
-
this.permissions.systemAudio = granted;
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
// permission is 'accessibility' | 'microphone'
|
|
215
|
-
// @ts-ignore - index by key
|
|
216
|
-
this.permissions[permission] = granted;
|
|
217
|
-
}
|
|
218
|
-
console.log(`RecallSdkStore: Permission ${permission} status: ${status}`);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Get permission status
|
|
222
|
-
*/
|
|
223
|
-
getPermissions() {
|
|
224
|
-
return { ...this.permissions };
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Check if all required permissions are granted
|
|
228
|
-
*/
|
|
229
|
-
arePermissionsGranted() {
|
|
230
|
-
return (this.permissions.accessibility &&
|
|
231
|
-
this.permissions.screenCapture &&
|
|
232
|
-
this.permissions.microphone);
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Add event listener for SDK events
|
|
236
|
-
*/
|
|
237
|
-
addEventListener(listener) {
|
|
238
|
-
this.eventListeners.add(listener);
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Remove event listener
|
|
242
|
-
*/
|
|
243
|
-
removeEventListener(listener) {
|
|
244
|
-
this.eventListeners.delete(listener);
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Emit event to all listeners
|
|
248
|
-
*/
|
|
249
|
-
emitEvent(event) {
|
|
250
|
-
this.eventListeners.forEach(listener => {
|
|
251
|
-
try {
|
|
252
|
-
listener(event);
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
console.error('RecallSdkStore: Error in event listener:', error);
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
125
|
/**
|
|
260
126
|
* Clear all state (useful for shutdown/reset)
|
|
261
127
|
*/
|
|
262
128
|
clearState() {
|
|
263
|
-
this.activeMeetings.clear();
|
|
264
|
-
this.activeRecordings.clear();
|
|
265
129
|
this.setSdkInitialized(false);
|
|
266
|
-
this.setSdkState('idle');
|
|
267
|
-
this.permissions = {
|
|
268
|
-
accessibility: false,
|
|
269
|
-
screenCapture: false,
|
|
270
|
-
microphone: false,
|
|
271
|
-
systemAudio: false,
|
|
272
|
-
};
|
|
273
130
|
console.log('RecallSdkStore: Cleared all state');
|
|
274
131
|
}
|
|
275
132
|
}
|
|
276
133
|
const recallSdkStore = new RecallSdkStore();
|
|
134
|
+
/**
|
|
135
|
+
* Persist the ToDesktop plugin context and hydrate the store configuration.
|
|
136
|
+
*/
|
|
137
|
+
const setPluginContext = (input) => {
|
|
138
|
+
const [enabledPref, apiUrlPref, requestPref] = input.plugin?.todesktop?.preferences ?? [];
|
|
139
|
+
const preferences = {
|
|
140
|
+
enabled: typeof enabledPref?.spec?.value === 'boolean'
|
|
141
|
+
? enabledPref.spec.value
|
|
142
|
+
: undefined,
|
|
143
|
+
apiUrl: typeof apiUrlPref?.spec?.value === 'string' && apiUrlPref.spec.value.trim()
|
|
144
|
+
? apiUrlPref.spec.value
|
|
145
|
+
: undefined,
|
|
146
|
+
requestPermissionsOnStartup: typeof requestPref?.spec?.value === 'boolean'
|
|
147
|
+
? requestPref.spec.value
|
|
148
|
+
: undefined,
|
|
149
|
+
};
|
|
150
|
+
recallSdkStore.loadFromPreferences(preferences);
|
|
151
|
+
};
|
|
277
152
|
|
|
278
153
|
/**
|
|
279
154
|
* ToDesktop Recall Desktop SDK Plugin - Main Process
|
|
@@ -284,199 +159,114 @@ const recallSdkStore = new RecallSdkStore();
|
|
|
284
159
|
* - Meeting detection and recording management
|
|
285
160
|
* - Event forwarding from SDK to frontend
|
|
286
161
|
*/
|
|
287
|
-
let RecallAiSdk;
|
|
288
|
-
try {
|
|
289
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
290
|
-
const mod = require('@recallai/desktop-sdk');
|
|
291
|
-
RecallAiSdk = (mod && mod.default) ? mod.default : mod;
|
|
292
|
-
}
|
|
293
|
-
catch {
|
|
294
|
-
RecallAiSdk = {
|
|
295
|
-
init: async (config) => { console.log('RecallAiSdk.init called with:', config); return null; },
|
|
296
|
-
shutdown: async () => { console.log('RecallAiSdk.shutdown called'); return null; },
|
|
297
|
-
startRecording: async (params) => { console.log('RecallAiSdk.startRecording called with:', params); return null; },
|
|
298
|
-
stopRecording: async (params) => { console.log('RecallAiSdk.stopRecording called with:', params); return null; },
|
|
299
|
-
pauseRecording: async (params) => { console.log('RecallAiSdk.pauseRecording called with:', params); return null; },
|
|
300
|
-
resumeRecording: async (params) => { console.log('RecallAiSdk.resumeRecording called with:', params); return null; },
|
|
301
|
-
uploadRecording: async (params) => { console.log('RecallAiSdk.uploadRecording called with:', params); return null; },
|
|
302
|
-
prepareDesktopAudioRecording: async () => { console.log('RecallAiSdk.prepareDesktopAudioRecording called'); return 'mock-window-id'; },
|
|
303
|
-
requestPermission: async (permission) => { console.log(`RecallAiSdk.requestPermission called for: ${permission}`); return null; },
|
|
304
|
-
addEventListener: (_eventType) => { },
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
162
|
class RecallDesktopMain {
|
|
308
163
|
constructor() {
|
|
309
|
-
this.version =
|
|
164
|
+
this.version = "1.0.0";
|
|
310
165
|
this.isInitialized = false;
|
|
311
166
|
this.subscriptions = new Map();
|
|
312
167
|
this.trackedWebContents = new Map();
|
|
168
|
+
this.sdkEventHandlers = new Map();
|
|
169
|
+
this.eventSideEffects = {
|
|
170
|
+
shutdown: () => {
|
|
171
|
+
recallSdkStore.clearState();
|
|
172
|
+
},
|
|
173
|
+
};
|
|
313
174
|
}
|
|
314
175
|
async initialize() {
|
|
176
|
+
if (this.isInitialized) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!recallSdkStore.isEnabled()) {
|
|
180
|
+
console.log("RecallDesktopMain: Plugin is disabled");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
315
183
|
try {
|
|
316
184
|
// Initialize plugin store
|
|
317
185
|
await recallSdkStore.initialize();
|
|
318
|
-
// Load configuration from ToDesktop preferences
|
|
319
|
-
// In a real implementation, this would integrate with ToDesktop's preference system
|
|
320
|
-
this.loadPreferences();
|
|
321
186
|
// Register IPC handlers
|
|
322
187
|
this.registerIpcHandlers();
|
|
323
|
-
//
|
|
324
|
-
if (recallSdkStore.isEnabled()) {
|
|
325
|
-
await this.initializeSdk();
|
|
326
|
-
}
|
|
188
|
+
// SDK will now be initialized on-demand via IPC
|
|
327
189
|
this.isInitialized = true;
|
|
328
|
-
console.log(
|
|
190
|
+
console.log("RecallDesktopMain: Main process initialized");
|
|
329
191
|
}
|
|
330
192
|
catch (error) {
|
|
331
|
-
console.error(
|
|
193
|
+
console.error("RecallDesktopMain: Failed to initialize main process:", error);
|
|
332
194
|
throw error;
|
|
333
195
|
}
|
|
334
196
|
}
|
|
335
|
-
loadPreferences() {
|
|
336
|
-
// In a real implementation, this would load from ToDesktop's preference system
|
|
337
|
-
// For now, we'll use defaults
|
|
338
|
-
const preferences = {
|
|
339
|
-
enabled: true,
|
|
340
|
-
apiUrl: 'https://us-east-1.recall.ai',
|
|
341
|
-
requestPermissionsOnStartup: true,
|
|
342
|
-
};
|
|
343
|
-
recallSdkStore.loadFromPreferences(preferences);
|
|
344
|
-
}
|
|
345
197
|
async initializeSdk() {
|
|
346
198
|
try {
|
|
347
199
|
const config = recallSdkStore.getConfig();
|
|
348
200
|
const sdkOptions = {
|
|
349
201
|
apiUrl: config.apiUrl,
|
|
350
202
|
acquirePermissionsOnStartup: config.requestPermissionsOnStartup
|
|
351
|
-
? [
|
|
203
|
+
? ["accessibility", "screen-capture", "microphone", "system-audio"]
|
|
352
204
|
: undefined,
|
|
353
205
|
restartOnError: true,
|
|
354
206
|
};
|
|
207
|
+
console.log("RecallDesktopMain: SDK options:", sdkOptions);
|
|
355
208
|
// Initialize the Recall SDK
|
|
356
209
|
await RecallAiSdk.init(sdkOptions);
|
|
357
|
-
// Set up event listeners
|
|
358
|
-
this.setupSdkEventListeners();
|
|
359
210
|
recallSdkStore.setSdkInitialized(true);
|
|
360
|
-
console.log(
|
|
211
|
+
console.log("RecallDesktopMain: SDK initialized successfully");
|
|
361
212
|
}
|
|
362
213
|
catch (error) {
|
|
363
|
-
console.error(
|
|
364
|
-
throw new RecallSdkError(
|
|
214
|
+
console.error("RecallDesktopMain: Failed to initialize SDK:", error);
|
|
215
|
+
throw new RecallSdkError("SDK initialization failed", "SDK_INIT_ERROR");
|
|
365
216
|
}
|
|
366
217
|
}
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
218
|
+
broadcastEvent(type, data) {
|
|
219
|
+
const channel = `recall-desktop:event:${type}`;
|
|
220
|
+
const subs = this.subscriptions.get(type);
|
|
221
|
+
if (!subs)
|
|
222
|
+
return;
|
|
223
|
+
subs.forEach((_count, wcId) => {
|
|
224
|
+
const wc = this.trackedWebContents.get(wcId);
|
|
225
|
+
if (!wc)
|
|
372
226
|
return;
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
catch (err) {
|
|
381
|
-
console.error('RecallDesktopMain: Failed to send event to webContents', wcId, err);
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
};
|
|
385
|
-
// Permissions granted
|
|
386
|
-
RecallAiSdk.addEventListener('permissions-granted', (evt) => {
|
|
387
|
-
console.log('RecallDesktopMain: Permissions granted');
|
|
388
|
-
const type = 'permissions-granted';
|
|
389
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
390
|
-
broadcast(type, evt);
|
|
391
|
-
});
|
|
392
|
-
// Meeting detected
|
|
393
|
-
RecallAiSdk.addEventListener('meeting-detected', (evt) => {
|
|
394
|
-
console.log('RecallDesktopMain: Meeting detected:', evt);
|
|
395
|
-
const meeting = evt.window;
|
|
396
|
-
recallSdkStore.addMeeting(meeting);
|
|
397
|
-
const type = 'meeting-detected';
|
|
398
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
399
|
-
broadcast(type, evt);
|
|
400
|
-
});
|
|
401
|
-
// SDK state change
|
|
402
|
-
RecallAiSdk.addEventListener('sdk-state-change', (evt) => {
|
|
403
|
-
console.log('RecallDesktopMain: SDK state change:', evt);
|
|
404
|
-
const state = evt.sdk.state.code;
|
|
405
|
-
recallSdkStore.setSdkState(state);
|
|
406
|
-
const type = 'sdk-state-change';
|
|
407
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
408
|
-
broadcast(type, evt);
|
|
409
|
-
});
|
|
410
|
-
// Recording started
|
|
411
|
-
RecallAiSdk.addEventListener('recording-started', (evt) => {
|
|
412
|
-
console.log('RecallDesktopMain: Recording started:', evt);
|
|
413
|
-
const type = 'recording-started';
|
|
414
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
415
|
-
broadcast(type, evt);
|
|
416
|
-
});
|
|
417
|
-
// Recording ended
|
|
418
|
-
RecallAiSdk.addEventListener('recording-ended', (evt) => {
|
|
419
|
-
console.log('RecallDesktopMain: Recording ended:', evt);
|
|
420
|
-
recallSdkStore.stopRecording(evt.window.id);
|
|
421
|
-
const type = 'recording-ended';
|
|
422
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
423
|
-
broadcast(type, evt);
|
|
424
|
-
});
|
|
425
|
-
// Meeting closed
|
|
426
|
-
RecallAiSdk.addEventListener('meeting-closed', (evt) => {
|
|
427
|
-
console.log('RecallDesktopMain: Meeting closed:', evt);
|
|
428
|
-
recallSdkStore.removeMeeting(evt.window.id);
|
|
429
|
-
const type = 'meeting-closed';
|
|
430
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
431
|
-
broadcast(type, evt);
|
|
432
|
-
});
|
|
433
|
-
// Upload progress
|
|
434
|
-
RecallAiSdk.addEventListener('upload-progress', (evt) => {
|
|
435
|
-
console.log(`RecallDesktopMain: Upload progress: ${evt.progress}%`);
|
|
436
|
-
const type = 'upload-progress';
|
|
437
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
438
|
-
broadcast(type, evt);
|
|
439
|
-
});
|
|
440
|
-
// Other events
|
|
441
|
-
['realtime-event', 'meeting-updated', 'media-capture-status', 'participant-capture-status']
|
|
442
|
-
.forEach(eventType => {
|
|
443
|
-
RecallAiSdk.addEventListener(eventType, (evt) => {
|
|
444
|
-
console.log(`RecallDesktopMain: ${eventType}:`, evt);
|
|
445
|
-
recallSdkStore.emitEvent({ type: eventType, data: evt });
|
|
446
|
-
broadcast(eventType, evt);
|
|
447
|
-
});
|
|
448
|
-
});
|
|
449
|
-
// Permission status
|
|
450
|
-
RecallAiSdk.addEventListener('permission-status', (evt) => {
|
|
451
|
-
console.log('RecallDesktopMain: Permission status:', evt);
|
|
452
|
-
recallSdkStore.setPermissionStatus(evt.permission, evt.status);
|
|
453
|
-
const type = 'permission-status';
|
|
454
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
455
|
-
broadcast(type, evt);
|
|
456
|
-
});
|
|
457
|
-
// Error handling
|
|
458
|
-
RecallAiSdk.addEventListener('error', (evt) => {
|
|
459
|
-
console.error('RecallDesktopMain: SDK error:', evt);
|
|
460
|
-
const type = 'error';
|
|
461
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
462
|
-
broadcast(type, evt);
|
|
463
|
-
});
|
|
464
|
-
// Shutdown
|
|
465
|
-
RecallAiSdk.addEventListener('shutdown', (evt) => {
|
|
466
|
-
console.log('RecallDesktopMain: SDK shutdown:', evt);
|
|
467
|
-
recallSdkStore.setSdkInitialized(false);
|
|
468
|
-
const type = 'shutdown';
|
|
469
|
-
recallSdkStore.emitEvent({ type, data: evt });
|
|
470
|
-
broadcast(type, evt);
|
|
227
|
+
try {
|
|
228
|
+
wc.send(channel, data);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
console.error("RecallDesktopMain: Failed to send event to webContents", wcId, err);
|
|
232
|
+
}
|
|
471
233
|
});
|
|
472
234
|
}
|
|
235
|
+
ensureSdkListener(eventType) {
|
|
236
|
+
if (this.sdkEventHandlers.has(eventType)) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const handler = (evt) => {
|
|
240
|
+
this.handleSdkEvent(eventType, evt);
|
|
241
|
+
};
|
|
242
|
+
this.sdkEventHandlers.set(eventType, handler);
|
|
243
|
+
RecallAiSdk.addEventListener(eventType, handler);
|
|
244
|
+
}
|
|
245
|
+
handleSdkEvent(eventType, evt) {
|
|
246
|
+
if (eventType === "error") {
|
|
247
|
+
console.error("RecallDesktopMain: SDK error:", evt);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(`RecallDesktopMain: ${eventType}`, evt);
|
|
251
|
+
}
|
|
252
|
+
const sideEffect = this.eventSideEffects[eventType];
|
|
253
|
+
if (sideEffect) {
|
|
254
|
+
try {
|
|
255
|
+
sideEffect(evt);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error("RecallDesktopMain: Side effect failed for", eventType, error);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
this.broadcastEvent(eventType, evt);
|
|
262
|
+
}
|
|
473
263
|
registerIpcHandlers() {
|
|
474
264
|
const addDestroyedCleanup = (wc) => {
|
|
475
265
|
const id = wc.id;
|
|
476
266
|
if (this.trackedWebContents.has(id))
|
|
477
267
|
return;
|
|
478
268
|
this.trackedWebContents.set(id, wc);
|
|
479
|
-
wc.once(
|
|
269
|
+
wc.once("destroyed", () => {
|
|
480
270
|
// Remove this wc from all subscriptions
|
|
481
271
|
this.subscriptions.forEach((map) => {
|
|
482
272
|
map.delete(id);
|
|
@@ -497,11 +287,12 @@ class RecallDesktopMain {
|
|
|
497
287
|
const id = wc.id;
|
|
498
288
|
const prev = map.get(id) || 0;
|
|
499
289
|
map.set(id, prev + 1);
|
|
290
|
+
this.ensureSdkListener(eventType);
|
|
500
291
|
return { success: true, message: `Subscribed to ${eventType}` };
|
|
501
292
|
}
|
|
502
293
|
catch (error) {
|
|
503
|
-
console.error(
|
|
504
|
-
return { success: false, message:
|
|
294
|
+
console.error("RecallDesktopMain: subscribe-events failed", error);
|
|
295
|
+
return { success: false, message: "Failed to subscribe to events" };
|
|
505
296
|
}
|
|
506
297
|
});
|
|
507
298
|
// Unsubscribe from events
|
|
@@ -520,27 +311,32 @@ class RecallDesktopMain {
|
|
|
520
311
|
return { success: true, message: `Unsubscribed from ${eventType}` };
|
|
521
312
|
}
|
|
522
313
|
catch (error) {
|
|
523
|
-
console.error(
|
|
524
|
-
return {
|
|
314
|
+
console.error("RecallDesktopMain: unsubscribe-events failed", error);
|
|
315
|
+
return {
|
|
316
|
+
success: false,
|
|
317
|
+
message: "Failed to unsubscribe from events",
|
|
318
|
+
};
|
|
525
319
|
}
|
|
526
320
|
});
|
|
527
321
|
// Initialize SDK
|
|
528
322
|
electron.ipcMain.handle(IPC_CHANNELS.INIT_SDK, async () => {
|
|
529
323
|
try {
|
|
530
324
|
if (!recallSdkStore.isEnabled()) {
|
|
531
|
-
throw new RecallSdkError(
|
|
325
|
+
throw new RecallSdkError("Plugin is disabled", "PLUGIN_DISABLED");
|
|
532
326
|
}
|
|
533
327
|
if (recallSdkStore.isSdkInitialized()) {
|
|
534
|
-
return { success: true, message:
|
|
328
|
+
return { success: true, message: "SDK already initialized" };
|
|
535
329
|
}
|
|
536
330
|
await this.initializeSdk();
|
|
537
|
-
return { success: true, message:
|
|
331
|
+
return { success: true, message: "SDK initialized successfully" };
|
|
538
332
|
}
|
|
539
333
|
catch (error) {
|
|
540
|
-
console.error(
|
|
334
|
+
console.error("RecallDesktopMain: SDK initialization failed:", error);
|
|
541
335
|
return {
|
|
542
336
|
success: false,
|
|
543
|
-
message: error instanceof RecallSdkError
|
|
337
|
+
message: error instanceof RecallSdkError
|
|
338
|
+
? error.message
|
|
339
|
+
: "SDK initialization failed",
|
|
544
340
|
};
|
|
545
341
|
}
|
|
546
342
|
});
|
|
@@ -549,11 +345,11 @@ class RecallDesktopMain {
|
|
|
549
345
|
try {
|
|
550
346
|
await RecallAiSdk.shutdown();
|
|
551
347
|
recallSdkStore.clearState();
|
|
552
|
-
return { success: true, message:
|
|
348
|
+
return { success: true, message: "SDK shutdown successfully" };
|
|
553
349
|
}
|
|
554
350
|
catch (error) {
|
|
555
|
-
console.error(
|
|
556
|
-
return { success: false, message:
|
|
351
|
+
console.error("RecallDesktopMain: SDK shutdown failed:", error);
|
|
352
|
+
return { success: false, message: "SDK shutdown failed" };
|
|
557
353
|
}
|
|
558
354
|
});
|
|
559
355
|
// Get plugin status
|
|
@@ -563,74 +359,83 @@ class RecallDesktopMain {
|
|
|
563
359
|
sdkInitialized: recallSdkStore.isSdkInitialized(),
|
|
564
360
|
version: this.version,
|
|
565
361
|
config: recallSdkStore.getConfig(),
|
|
566
|
-
sdkState: recallSdkStore.getSdkState(),
|
|
567
|
-
permissions: recallSdkStore.getPermissions()
|
|
568
362
|
};
|
|
569
363
|
});
|
|
570
364
|
// Start recording
|
|
571
365
|
electron.ipcMain.handle(IPC_CHANNELS.START_RECORDING, async (event, request) => {
|
|
572
366
|
try {
|
|
573
367
|
if (!recallSdkStore.isSdkInitialized()) {
|
|
574
|
-
throw new RecallSdkError(
|
|
368
|
+
throw new RecallSdkError("SDK not initialized", "SDK_NOT_INITIALIZED");
|
|
575
369
|
}
|
|
576
370
|
await RecallAiSdk.startRecording({
|
|
577
371
|
windowId: request.windowId,
|
|
578
|
-
uploadToken: request.uploadToken
|
|
372
|
+
uploadToken: request.uploadToken,
|
|
579
373
|
});
|
|
580
|
-
|
|
581
|
-
return { success: true, message: 'Recording started successfully' };
|
|
374
|
+
return { success: true, message: "Recording started successfully" };
|
|
582
375
|
}
|
|
583
376
|
catch (error) {
|
|
584
|
-
console.error(
|
|
377
|
+
console.error("RecallDesktopMain: Start recording failed:", error);
|
|
585
378
|
return {
|
|
586
379
|
success: false,
|
|
587
|
-
message: error instanceof RecallSdkError
|
|
380
|
+
message: error instanceof RecallSdkError
|
|
381
|
+
? error.message
|
|
382
|
+
: "Failed to start recording",
|
|
588
383
|
};
|
|
589
384
|
}
|
|
590
385
|
});
|
|
591
386
|
// Stop recording
|
|
592
387
|
electron.ipcMain.handle(IPC_CHANNELS.STOP_RECORDING, async (event, request) => {
|
|
593
388
|
try {
|
|
594
|
-
await RecallAiSdk.stopRecording({
|
|
595
|
-
|
|
596
|
-
|
|
389
|
+
await RecallAiSdk.stopRecording({
|
|
390
|
+
windowId: request.windowId,
|
|
391
|
+
});
|
|
392
|
+
return { success: true, message: "Recording stopped successfully" };
|
|
597
393
|
}
|
|
598
394
|
catch (error) {
|
|
599
|
-
console.error(
|
|
600
|
-
return { success: false, message:
|
|
395
|
+
console.error("RecallDesktopMain: Stop recording failed:", error);
|
|
396
|
+
return { success: false, message: "Failed to stop recording" };
|
|
601
397
|
}
|
|
602
398
|
});
|
|
603
399
|
// Pause recording
|
|
604
400
|
electron.ipcMain.handle(IPC_CHANNELS.PAUSE_RECORDING, async (event, request) => {
|
|
605
401
|
try {
|
|
606
|
-
await RecallAiSdk.pauseRecording({
|
|
607
|
-
|
|
402
|
+
await RecallAiSdk.pauseRecording({
|
|
403
|
+
windowId: request.windowId,
|
|
404
|
+
});
|
|
405
|
+
return { success: true, message: "Recording paused successfully" };
|
|
608
406
|
}
|
|
609
407
|
catch (error) {
|
|
610
|
-
console.error(
|
|
611
|
-
return { success: false, message:
|
|
408
|
+
console.error("RecallDesktopMain: Pause recording failed:", error);
|
|
409
|
+
return { success: false, message: "Failed to pause recording" };
|
|
612
410
|
}
|
|
613
411
|
});
|
|
614
412
|
// Resume recording
|
|
615
413
|
electron.ipcMain.handle(IPC_CHANNELS.RESUME_RECORDING, async (event, request) => {
|
|
616
414
|
try {
|
|
617
|
-
await RecallAiSdk.resumeRecording({
|
|
618
|
-
|
|
415
|
+
await RecallAiSdk.resumeRecording({
|
|
416
|
+
windowId: request.windowId,
|
|
417
|
+
});
|
|
418
|
+
return { success: true, message: "Recording resumed successfully" };
|
|
619
419
|
}
|
|
620
420
|
catch (error) {
|
|
621
|
-
console.error(
|
|
622
|
-
return { success: false, message:
|
|
421
|
+
console.error("RecallDesktopMain: Resume recording failed:", error);
|
|
422
|
+
return { success: false, message: "Failed to resume recording" };
|
|
623
423
|
}
|
|
624
424
|
});
|
|
625
425
|
// Upload recording
|
|
626
426
|
electron.ipcMain.handle(IPC_CHANNELS.UPLOAD_RECORDING, async (event, request) => {
|
|
627
427
|
try {
|
|
628
|
-
await RecallAiSdk.uploadRecording({
|
|
629
|
-
|
|
428
|
+
await RecallAiSdk.uploadRecording({
|
|
429
|
+
windowId: request.windowId,
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
success: true,
|
|
433
|
+
message: "Recording upload started successfully",
|
|
434
|
+
};
|
|
630
435
|
}
|
|
631
436
|
catch (error) {
|
|
632
|
-
console.error(
|
|
633
|
-
return { success: false, message:
|
|
437
|
+
console.error("RecallDesktopMain: Upload recording failed:", error);
|
|
438
|
+
return { success: false, message: "Failed to upload recording" };
|
|
634
439
|
}
|
|
635
440
|
});
|
|
636
441
|
// Prepare desktop audio recording
|
|
@@ -639,24 +444,30 @@ class RecallDesktopMain {
|
|
|
639
444
|
const windowId = await RecallAiSdk.prepareDesktopAudioRecording();
|
|
640
445
|
return {
|
|
641
446
|
success: true,
|
|
642
|
-
message:
|
|
643
|
-
data: { windowId }
|
|
447
|
+
message: "Desktop audio recording prepared successfully",
|
|
448
|
+
data: { windowId },
|
|
644
449
|
};
|
|
645
450
|
}
|
|
646
451
|
catch (error) {
|
|
647
|
-
console.error(
|
|
648
|
-
return {
|
|
452
|
+
console.error("RecallDesktopMain: Prepare desktop audio failed:", error);
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
message: "Failed to prepare desktop audio recording",
|
|
456
|
+
};
|
|
649
457
|
}
|
|
650
458
|
});
|
|
651
459
|
// Request permission
|
|
652
460
|
electron.ipcMain.handle(IPC_CHANNELS.REQUEST_PERMISSION, async (event, permission) => {
|
|
653
461
|
try {
|
|
654
462
|
await RecallAiSdk.requestPermission(permission);
|
|
655
|
-
return {
|
|
463
|
+
return {
|
|
464
|
+
success: true,
|
|
465
|
+
message: `Permission request sent for ${permission}`,
|
|
466
|
+
};
|
|
656
467
|
}
|
|
657
468
|
catch (error) {
|
|
658
|
-
console.error(
|
|
659
|
-
return { success: false, message:
|
|
469
|
+
console.error("RecallDesktopMain: Request permission failed:", error);
|
|
470
|
+
return { success: false, message: "Failed to request permission" };
|
|
660
471
|
}
|
|
661
472
|
});
|
|
662
473
|
// Set configuration
|
|
@@ -664,31 +475,39 @@ class RecallDesktopMain {
|
|
|
664
475
|
try {
|
|
665
476
|
recallSdkStore.setConfig(config);
|
|
666
477
|
// If SDK settings changed and SDK is initialized, reinitialize
|
|
667
|
-
if (recallSdkStore.isSdkInitialized() &&
|
|
668
|
-
|
|
478
|
+
if (recallSdkStore.isSdkInitialized() &&
|
|
479
|
+
(config.apiUrl || config.requestPermissionsOnStartup !== undefined)) {
|
|
480
|
+
console.log("RecallDesktopMain: Reinitializing SDK due to configuration change");
|
|
669
481
|
await RecallAiSdk.shutdown();
|
|
670
482
|
await this.initializeSdk();
|
|
671
483
|
}
|
|
672
|
-
return {
|
|
484
|
+
return {
|
|
485
|
+
success: true,
|
|
486
|
+
message: "Configuration updated successfully",
|
|
487
|
+
};
|
|
673
488
|
}
|
|
674
489
|
catch (error) {
|
|
675
|
-
console.error(
|
|
676
|
-
return { success: false, message:
|
|
490
|
+
console.error("RecallDesktopMain: Failed to set configuration:", error);
|
|
491
|
+
return { success: false, message: "Failed to update configuration" };
|
|
677
492
|
}
|
|
678
493
|
});
|
|
679
494
|
// Get configuration
|
|
680
495
|
electron.ipcMain.handle(IPC_CHANNELS.GET_CONFIG, async () => {
|
|
681
496
|
return {
|
|
682
497
|
success: true,
|
|
683
|
-
message:
|
|
684
|
-
data: recallSdkStore.getConfig()
|
|
498
|
+
message: "Configuration retrieved successfully",
|
|
499
|
+
data: recallSdkStore.getConfig(),
|
|
685
500
|
};
|
|
686
501
|
});
|
|
687
502
|
}
|
|
688
503
|
}
|
|
689
504
|
// Initialize plugin
|
|
690
505
|
const recallDesktopMain = new RecallDesktopMain();
|
|
691
|
-
|
|
506
|
+
var main = (context) => {
|
|
507
|
+
setPluginContext(context);
|
|
508
|
+
recallDesktopMain.initialize().catch(() => undefined);
|
|
509
|
+
};
|
|
692
510
|
|
|
693
|
-
|
|
511
|
+
exports.default = main;
|
|
512
|
+
exports.recallDesktopMain = recallDesktopMain;
|
|
694
513
|
//# sourceMappingURL=main.js.map
|