@lvce-editor/main-process 2.0.0 → 2.1.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.
@@ -3181,230 +3181,6 @@ const getSharedProcessArgv = isProduction => {
3181
3181
  return [];
3182
3182
  };
3183
3183
 
3184
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
3185
- const E_MODULE_NOT_FOUND = 'E_MODULE_NOT_FOUND';
3186
-
3187
- class CommandNotFoundError extends Error {
3188
- constructor(id) {
3189
- super(`command ${id} not found`);
3190
- this.name = 'CommandNotFoundError';
3191
- // @ts-ignore
3192
- this.code = E_COMMAND_NOT_FOUND;
3193
- }
3194
- }
3195
-
3196
- const App = 1;
3197
- const AppWindow = 2;
3198
- const Beep = 3;
3199
- const Developer = 4;
3200
- const Dialog = 5;
3201
- const ElectronWindowProcessExplorer = 6;
3202
- const Window = 7;
3203
- const ElectronShell = 8;
3204
- const ElectronPowerSaveBlocker = 9;
3205
- const ElectronSafeStorage = 10;
3206
- const ElectronContentTracing = 11;
3207
- const ElectronNetLog = 12;
3208
- const ElectronBrowserView = 13;
3209
- const ElectronBrowserViewQuickPick = 14;
3210
- const ElectronContextMenu = 16;
3211
- const ElectronClipBoard = 17;
3212
- const ElectronApplicationMenu = 18;
3213
- const Process = 19;
3214
- const ElectronNet = 20;
3215
- const ElectronBrowserViewSuggestions = 21;
3216
- const CreatePidMap = 22;
3217
- const OpenExternal$1 = 23;
3218
- const Platform = 25;
3219
- const GetWindowId = 26;
3220
- const DesktopCapturer = 27;
3221
- const Trash = 28;
3222
- const IpcParent = 29;
3223
- const Crash = 30;
3224
- const Exit = 31;
3225
- const ElectronScreen = 32;
3226
- const TemporaryMessagePort = 34;
3227
- const ElectronWebContents = 35;
3228
- const ElectronWebContentsView = 36;
3229
- const ElectronWebContentsViewFunctions = 37;
3230
- const CreateMessagePort = 38;
3231
- const HandleElectronMessagePort = 39;
3232
- const ElectronSession = 40;
3233
-
3234
- const getPrefix = commandId => {
3235
- return commandId.slice(0, commandId.indexOf('.'));
3236
- };
3237
- const getModuleId = commandId => {
3238
- const prefix = getPrefix(commandId);
3239
- switch (prefix) {
3240
- case 'Crash':
3241
- return Crash;
3242
- case 'ElectronApp':
3243
- case 'App':
3244
- return App;
3245
- case 'Beep':
3246
- return Beep;
3247
- case 'ElectronWindow':
3248
- return Window;
3249
- case 'ElectronDeveloper':
3250
- return Developer;
3251
- case 'AppWindow':
3252
- return AppWindow;
3253
- case 'ElectronWindowProcessExplorer':
3254
- return ElectronWindowProcessExplorer;
3255
- case 'ElectronDialog':
3256
- return Dialog;
3257
- case 'ElectronBeep':
3258
- return Beep;
3259
- case 'ElectronShell':
3260
- return ElectronShell;
3261
- case 'ElectronPowerSaveBlocker':
3262
- return ElectronPowerSaveBlocker;
3263
- case 'ElectronSafeStorage':
3264
- return ElectronSafeStorage;
3265
- case 'ElectronContentTracing':
3266
- return ElectronContentTracing;
3267
- case 'ElectronNetLog':
3268
- return ElectronNetLog;
3269
- case 'ElectronBrowserView':
3270
- return ElectronBrowserView;
3271
- case 'ElectronBrowserViewQuickPick':
3272
- return ElectronBrowserViewQuickPick;
3273
- case 'ElectronContextMenu':
3274
- return ElectronContextMenu;
3275
- case 'ElectronClipBoard':
3276
- return ElectronClipBoard;
3277
- case 'ElectronApplicationMenu':
3278
- return ElectronApplicationMenu;
3279
- case 'Process':
3280
- return Process;
3281
- case 'ElectronNet':
3282
- return ElectronNet;
3283
- case 'ElectronBrowserViewSuggestions':
3284
- return ElectronBrowserViewSuggestions;
3285
- case 'CreatePidMap':
3286
- return CreatePidMap;
3287
- case 'OpenExternal':
3288
- return OpenExternal$1;
3289
- case 'Platform':
3290
- return Platform;
3291
- case 'GetWindowId':
3292
- return GetWindowId;
3293
- case 'DesktopCapturer':
3294
- return DesktopCapturer;
3295
- case 'Trash':
3296
- return Trash;
3297
- case 'IpcParent':
3298
- return IpcParent;
3299
- case 'Exit':
3300
- return Exit;
3301
- case 'ElectronScreen':
3302
- return ElectronScreen;
3303
- case 'TemporaryMessagePort':
3304
- return TemporaryMessagePort;
3305
- case 'ElectronWebContents':
3306
- return ElectronWebContents;
3307
- case 'ElectronWebContentsView':
3308
- return ElectronWebContentsView;
3309
- case 'ElectronWebContentsViewFunctions':
3310
- return ElectronWebContentsViewFunctions;
3311
- case 'CreateMessagePort':
3312
- return CreateMessagePort;
3313
- case 'HandleElectronMessagePort':
3314
- return HandleElectronMessagePort;
3315
- case 'ElectronSession':
3316
- return ElectronSession;
3317
- default:
3318
- throw new CommandNotFoundError(commandId);
3319
- }
3320
- };
3321
-
3322
- const state$7 = {
3323
- commands: Object.create(null),
3324
- pendingModules: Object.create(null),
3325
- async load(moduleId) {}
3326
- };
3327
- const initializeModule = module => {
3328
- if (module.Commands) {
3329
- for (const [key, value] of Object.entries(module.Commands)) {
3330
- if (module.name) {
3331
- const actualKey = `${module.name}.${key}`;
3332
- register(actualKey, value);
3333
- } else {
3334
- register(key, value);
3335
- }
3336
- }
3337
- return;
3338
- }
3339
- throw new Error(`module ${module.name || '<unnamed module>'} is missing commands`);
3340
- };
3341
- const getOrLoadModule = moduleId => {
3342
- if (!state$7.pendingModules[moduleId]) {
3343
- const importPromise = state$7.load(moduleId);
3344
- state$7.pendingModules[moduleId] = importPromise.then(initializeModule);
3345
- }
3346
- return state$7.pendingModules[moduleId];
3347
- };
3348
- const loadCommand = command => getOrLoadModule(getModuleId(command));
3349
- const register = (commandId, listener) => {
3350
- state$7.commands[commandId] = listener;
3351
- };
3352
- const hasThrown = new Set();
3353
- const loadThenExecute = async (command, ...args) => {
3354
- await loadCommand(command);
3355
- // TODO can skip then block in prod (only to prevent endless loop in dev)
3356
- if (!(command in state$7.commands)) {
3357
- if (hasThrown.has(command)) {
3358
- return;
3359
- }
3360
- hasThrown.add(command);
3361
- throw new Error(`Command did not register "${command}"`);
3362
- }
3363
- return execute(command, ...args);
3364
- };
3365
- const execute = (command, ...args) => {
3366
- if (command in state$7.commands) {
3367
- return state$7.commands[command](...args);
3368
- }
3369
- return loadThenExecute(command, ...args);
3370
- };
3371
- const setLoad = load => {
3372
- state$7.load = load;
3373
- };
3374
-
3375
- const printPrettyError = (prettyError, prefix = '') => {
3376
- error(`${prefix}${prettyError.type}: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}\n`);
3377
- };
3378
-
3379
- const requiresSocket = () => {
3380
- return false;
3381
- };
3382
-
3383
- const logError = (error, prettyError) => {
3384
- printPrettyError(prettyError, '[main-process] ');
3385
- };
3386
- const handleMessage = event => {
3387
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, prepare,
3388
- // @ts-ignore
3389
- logError, requiresSocket);
3390
- };
3391
-
3392
- const handleIpc = ipc => {
3393
- if ('addEventListener' in ipc) {
3394
- ipc.addEventListener('message', handleMessage);
3395
- } else if ('on' in ipc) {
3396
- // deprecated
3397
- ipc.on('message', handleMessage);
3398
- }
3399
- };
3400
- const unhandleIpc = ipc => {
3401
- if ('removeEventListener' in ipc) {
3402
- ipc.removeEventListener('message', handleMessage);
3403
- } else if ('off' in ipc) {
3404
- ipc.off('message', handleMessage);
3405
- }
3406
- };
3407
-
3408
3184
  const EmbedsProcess = 2;
3409
3185
  const MainProcess = -5;
3410
3186
 
@@ -3478,15 +3254,8 @@ const getSharedProcessPath = () => {
3478
3254
  return join(root, 'packages', 'shared-process', 'src', 'sharedProcessMain.ts');
3479
3255
  };
3480
3256
 
3481
- const state$6 = {
3482
- /**
3483
- * @type{any|undefined}
3484
- */
3485
- sharedProcess: undefined,
3486
- /**
3487
- * @type {any}
3488
- */
3489
- promise: undefined
3257
+ const requiresSocket = () => {
3258
+ return false;
3490
3259
  };
3491
3260
 
3492
3261
  const handleChildError = error => {
@@ -3529,7 +3298,6 @@ const launchSharedProcess = async ({
3529
3298
  sharedProcess._rawIpc.on('exit', handleChildExit);
3530
3299
  // @ts-ignore
3531
3300
  sharedProcess._rawIpc.on('disconnect', handleChildDisconnect);
3532
- handleIpc(sharedProcess);
3533
3301
 
3534
3302
  // create secondary ipc to support transferring objects
3535
3303
  // from shared process to main process
@@ -3545,43 +3313,47 @@ const launchSharedProcess = async ({
3545
3313
  requiresSocket: requiresSocket,
3546
3314
  messagePort: port1
3547
3315
  });
3548
-
3549
- // @ts-ignore
3550
- state$6.sharedProcess = sharedProcess;
3551
3316
  mark(DidStartSharedProcess);
3552
- return sharedProcess;
3317
+ return sharedProcessRpc;
3318
+ };
3319
+
3320
+ const state$7 = {
3321
+ /**
3322
+ * @type {any}
3323
+ */
3324
+ promise: undefined
3553
3325
  };
3554
3326
 
3555
3327
  const getOrCreate = async ({
3556
3328
  method,
3557
3329
  env = {}
3558
3330
  }) => {
3559
- if (!state$6.promise) {
3331
+ if (!state$7.promise) {
3560
3332
  // @ts-ignore
3561
- state$6.promise = launchSharedProcess({
3333
+ state$7.promise = launchSharedProcess({
3562
3334
  method,
3563
3335
  env
3564
3336
  });
3565
3337
  }
3566
- return state$6.promise;
3338
+ return state$7.promise;
3567
3339
  };
3568
3340
  const send$1 = async (method, ...params) => {
3569
3341
  const ipc = await getOrCreate({
3570
3342
  method: ElectronUtilityProcess$1
3571
3343
  });
3572
- send$2(ipc, method, ...params);
3344
+ send$2(ipc.ipc, method, ...params);
3573
3345
  };
3574
3346
  const invoke = async (method, ...params) => {
3575
3347
  const ipc = await getOrCreate({
3576
3348
  method: ElectronUtilityProcess$1
3577
3349
  });
3578
- return invoke$1(ipc, method, ...params);
3350
+ return invoke$1(ipc.ipc, method, ...params);
3579
3351
  };
3580
3352
  const invokeAndTransfer = async (transfer, method, ...params) => {
3581
3353
  const ipc = await getOrCreate({
3582
3354
  method: ElectronUtilityProcess$1
3583
3355
  });
3584
- return invokeAndTransfer$1(ipc, transfer, method, ...params);
3356
+ return invokeAndTransfer$1(ipc.ipc, transfer, method, ...params);
3585
3357
  };
3586
3358
 
3587
3359
  const handleCliArgs = async parsedArgs => {
@@ -4686,14 +4458,14 @@ const createTitleBar = items => {
4686
4458
 
4687
4459
  const PHASE_DEFAULT = 0;
4688
4460
  const PHASE_SHUTDOWN = -1;
4689
- const state$5 = {
4461
+ const state$6 = {
4690
4462
  phase: PHASE_DEFAULT
4691
4463
  };
4692
4464
  const isShutDown = () => {
4693
- return state$5.phase === PHASE_SHUTDOWN;
4465
+ return state$6.phase === PHASE_SHUTDOWN;
4694
4466
  };
4695
4467
  const setShutDown = () => {
4696
- state$5.phase = PHASE_SHUTDOWN;
4468
+ state$6.phase = PHASE_SHUTDOWN;
4697
4469
  };
4698
4470
 
4699
4471
  // TODO move this function to shared process
@@ -4990,21 +4762,21 @@ const BeforeInputEvent = 'before-input-event';
4990
4762
  const Allow = 'allow';
4991
4763
  const Deny = 'deny';
4992
4764
 
4993
- const state$4 = {
4765
+ const state$5 = {
4994
4766
  views: Object.create(null),
4995
4767
  fallThroughKeyBindings: [],
4996
4768
  canceled: Object.create(null)
4997
4769
  };
4998
4770
  const add$1 = (id, browserWindow, view) => {
4999
4771
  // state
5000
- state$4.views[id] = {
4772
+ state$5.views[id] = {
5001
4773
  browserWindow,
5002
4774
  view
5003
4775
  };
5004
4776
  };
5005
4777
  const hasWebContents = id => {
5006
4778
  number(id);
5007
- return id in state$4.views;
4779
+ return id in state$5.views;
5008
4780
  };
5009
4781
  /**
5010
4782
  *
@@ -5012,19 +4784,19 @@ const hasWebContents = id => {
5012
4784
  * @returns {{browserWindow: Electron.BrowserWindow, view: Electron.WebContentsView}}
5013
4785
  */
5014
4786
  const get$2 = id => {
5015
- return state$4.views[id];
4787
+ return state$5.views[id];
5016
4788
  };
5017
4789
  const remove$1 = id => {
5018
- delete state$4.views[id];
4790
+ delete state$5.views[id];
5019
4791
  };
5020
4792
  const setFallthroughKeyBindings = fallthroughKeyBindings => {
5021
- state$4.fallThroughKeyBindings = fallthroughKeyBindings;
4793
+ state$5.fallThroughKeyBindings = fallthroughKeyBindings;
5022
4794
  };
5023
4795
  const getFallthroughKeyBindings = () => {
5024
- return state$4.fallThroughKeyBindings;
4796
+ return state$5.fallThroughKeyBindings;
5025
4797
  };
5026
4798
  const setCanceled = id => {
5027
- state$4.canceled[id] = true;
4799
+ state$5.canceled[id] = true;
5028
4800
  };
5029
4801
 
5030
4802
  const shouldAllowNavigation = webContentsId => {
@@ -5074,123 +4846,314 @@ const isProtocolHandleApiSupported = protocol => {
5074
4846
  if (protocol.handle) {
5075
4847
  return true;
5076
4848
  }
5077
- return false;
4849
+ return false;
4850
+ };
4851
+
4852
+ const WebView = 'lvce-oss-webview';
4853
+
4854
+ const privilegedSchems = [{
4855
+ scheme: scheme,
4856
+ privileges: {
4857
+ standard: true,
4858
+ secure: true,
4859
+ supportFetchAPI: true,
4860
+ stream: true,
4861
+ codeCache: true
4862
+ }
4863
+ }, {
4864
+ scheme: WebView,
4865
+ privileges: {
4866
+ standard: true,
4867
+ secure: true,
4868
+ supportFetchAPI: true,
4869
+ stream: true,
4870
+ codeCache: true
4871
+ }
4872
+ }];
4873
+
4874
+ /**
4875
+ *
4876
+ * @param {Electron.Protocol} protocol
4877
+ * @param {string} name
4878
+ * @param {(request: GlobalRequest) => Promise<GlobalResponse>} handleRequest
4879
+ * @returns
4880
+ */
4881
+ const handle = (protocol, name, handleRequest) => {
4882
+ if (isProtocolHandleApiSupported(protocol)) {
4883
+ protocol.handle(name, handleRequest);
4884
+ return;
4885
+ }
4886
+ throw new Error('protocol.handle api is not supported');
4887
+ };
4888
+
4889
+ /**
4890
+ *
4891
+ * @param {Electron.Protocol} protocol
4892
+ * @returns
4893
+ */
4894
+ const enable = protocol => {
4895
+ protocol.registerSchemesAsPrivileged(privilegedSchems);
4896
+ };
4897
+
4898
+ const requestSingleInstanceLock = argv => {
4899
+ return app.requestSingleInstanceLock(argv);
4900
+ };
4901
+
4902
+ // TODO maybe handle critical (first render) request via ipcMain
4903
+ // and spawn shared process when page is idle/loaded
4904
+ // currently launching shared process takes 170ms
4905
+ // which means first paint is delayed by a lot
4906
+
4907
+ const hydrate = async () => {
4908
+ setMenu(null); // performance
4909
+ unhandled({
4910
+ showDialog: true,
4911
+ logger() {} // already exists in mainProcessMain.js
4912
+ });
4913
+
4914
+ // TODO electron error ERROR:sandbox_linux.cc(364)] InitializeSandbox() called with multiple threads in process gpu-process
4915
+
4916
+ // TODO electron error [90611:0219/003126.546542:ERROR:gl_surface_presentation_helper.cc(260)] GetVSyncParametersIfAvailable() failed for 1 times!
4917
+ // need to wait for solution https://github.com/electron/electron/issues/32760
4918
+
4919
+ // TODO need to wait for playwright bugs to be resolved
4920
+ // before being able to test multi-window behavior
4921
+ // see https://github.com/microsoft/playwright/issues/12345
4922
+
4923
+ const parsedCliArgs = parseCliArgs(argv);
4924
+ const moduleId = canHandleFastCliArgs(parsedCliArgs);
4925
+ if (moduleId) {
4926
+ await handleFastCliArgs(moduleId, parsedCliArgs);
4927
+ return;
4928
+ }
4929
+ if (isLinux && chromeUserDataPath) {
4930
+ setUserDataPath(chromeUserDataPath);
4931
+ setSessionDataPath(chromeUserDataPath);
4932
+ setCrashDumpsPath(chromeUserDataPath);
4933
+ setLogsPath(chromeUserDataPath);
4934
+ }
4935
+ const hasLock = requestSingleInstanceLock(argv);
4936
+ if (!hasLock) {
4937
+ debug('[info] quitting because no lock');
4938
+ exit();
4939
+ return;
4940
+ }
4941
+
4942
+ // TODO tree shake out the .env.DEV check: reading from env variables is expensive
4943
+ if (process.stdout.isTTY && !parsedCliArgs.wait && !process.env.DEV) {
4944
+ spawn(execPath, argv.slice(1), {
4945
+ detached: true,
4946
+ stdio: 'ignore'
4947
+ });
4948
+ exit$1(Success);
4949
+ }
4950
+
4951
+ // command line switches
4952
+ enable$1(parsedCliArgs);
4953
+
4954
+ // protocol
4955
+ enable(Electron.protocol);
4956
+
4957
+ // app
4958
+ on(WindowAllClosed, handleWindowAllClosed);
4959
+ on(BeforeQuit, handleBeforeQuit);
4960
+ on(WebContentsCreated, handleWebContentsCreated);
4961
+ on(SecondInstance, handleSecondInstance);
4962
+ await whenReady();
4963
+ mark(AppReady);
4964
+ await handleReady(parsedCliArgs, cwd());
4965
+ debug('[info] app window created');
4966
+ };
4967
+
4968
+ const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
4969
+ const E_MODULE_NOT_FOUND = 'E_MODULE_NOT_FOUND';
4970
+
4971
+ class CommandNotFoundError extends Error {
4972
+ constructor(id) {
4973
+ super(`command ${id} not found`);
4974
+ this.name = 'CommandNotFoundError';
4975
+ // @ts-ignore
4976
+ this.code = E_COMMAND_NOT_FOUND;
4977
+ }
4978
+ }
4979
+
4980
+ const App = 1;
4981
+ const AppWindow = 2;
4982
+ const Beep = 3;
4983
+ const Developer = 4;
4984
+ const Dialog = 5;
4985
+ const ElectronWindowProcessExplorer = 6;
4986
+ const Window = 7;
4987
+ const ElectronShell = 8;
4988
+ const ElectronPowerSaveBlocker = 9;
4989
+ const ElectronSafeStorage = 10;
4990
+ const ElectronContentTracing = 11;
4991
+ const ElectronNetLog = 12;
4992
+ const ElectronBrowserView = 13;
4993
+ const ElectronBrowserViewQuickPick = 14;
4994
+ const ElectronContextMenu = 16;
4995
+ const ElectronClipBoard = 17;
4996
+ const ElectronApplicationMenu = 18;
4997
+ const Process = 19;
4998
+ const ElectronNet = 20;
4999
+ const ElectronBrowserViewSuggestions = 21;
5000
+ const CreatePidMap = 22;
5001
+ const OpenExternal$1 = 23;
5002
+ const Platform = 25;
5003
+ const GetWindowId = 26;
5004
+ const DesktopCapturer = 27;
5005
+ const Trash = 28;
5006
+ const IpcParent = 29;
5007
+ const Crash = 30;
5008
+ const Exit = 31;
5009
+ const ElectronScreen = 32;
5010
+ const TemporaryMessagePort = 34;
5011
+ const ElectronWebContents = 35;
5012
+ const ElectronWebContentsView = 36;
5013
+ const ElectronWebContentsViewFunctions = 37;
5014
+ const CreateMessagePort = 38;
5015
+ const HandleElectronMessagePort = 39;
5016
+ const ElectronSession = 40;
5017
+
5018
+ const getPrefix = commandId => {
5019
+ return commandId.slice(0, commandId.indexOf('.'));
5020
+ };
5021
+ const getModuleId = commandId => {
5022
+ const prefix = getPrefix(commandId);
5023
+ switch (prefix) {
5024
+ case 'Crash':
5025
+ return Crash;
5026
+ case 'ElectronApp':
5027
+ case 'App':
5028
+ return App;
5029
+ case 'Beep':
5030
+ return Beep;
5031
+ case 'ElectronWindow':
5032
+ return Window;
5033
+ case 'ElectronDeveloper':
5034
+ return Developer;
5035
+ case 'AppWindow':
5036
+ return AppWindow;
5037
+ case 'ElectronWindowProcessExplorer':
5038
+ return ElectronWindowProcessExplorer;
5039
+ case 'ElectronDialog':
5040
+ return Dialog;
5041
+ case 'ElectronBeep':
5042
+ return Beep;
5043
+ case 'ElectronShell':
5044
+ return ElectronShell;
5045
+ case 'ElectronPowerSaveBlocker':
5046
+ return ElectronPowerSaveBlocker;
5047
+ case 'ElectronSafeStorage':
5048
+ return ElectronSafeStorage;
5049
+ case 'ElectronContentTracing':
5050
+ return ElectronContentTracing;
5051
+ case 'ElectronNetLog':
5052
+ return ElectronNetLog;
5053
+ case 'ElectronBrowserView':
5054
+ return ElectronBrowserView;
5055
+ case 'ElectronBrowserViewQuickPick':
5056
+ return ElectronBrowserViewQuickPick;
5057
+ case 'ElectronContextMenu':
5058
+ return ElectronContextMenu;
5059
+ case 'ElectronClipBoard':
5060
+ return ElectronClipBoard;
5061
+ case 'ElectronApplicationMenu':
5062
+ return ElectronApplicationMenu;
5063
+ case 'Process':
5064
+ return Process;
5065
+ case 'ElectronNet':
5066
+ return ElectronNet;
5067
+ case 'ElectronBrowserViewSuggestions':
5068
+ return ElectronBrowserViewSuggestions;
5069
+ case 'CreatePidMap':
5070
+ return CreatePidMap;
5071
+ case 'OpenExternal':
5072
+ return OpenExternal$1;
5073
+ case 'Platform':
5074
+ return Platform;
5075
+ case 'GetWindowId':
5076
+ return GetWindowId;
5077
+ case 'DesktopCapturer':
5078
+ return DesktopCapturer;
5079
+ case 'Trash':
5080
+ return Trash;
5081
+ case 'IpcParent':
5082
+ return IpcParent;
5083
+ case 'Exit':
5084
+ return Exit;
5085
+ case 'ElectronScreen':
5086
+ return ElectronScreen;
5087
+ case 'TemporaryMessagePort':
5088
+ return TemporaryMessagePort;
5089
+ case 'ElectronWebContents':
5090
+ return ElectronWebContents;
5091
+ case 'ElectronWebContentsView':
5092
+ return ElectronWebContentsView;
5093
+ case 'ElectronWebContentsViewFunctions':
5094
+ return ElectronWebContentsViewFunctions;
5095
+ case 'CreateMessagePort':
5096
+ return CreateMessagePort;
5097
+ case 'HandleElectronMessagePort':
5098
+ return HandleElectronMessagePort;
5099
+ case 'ElectronSession':
5100
+ return ElectronSession;
5101
+ default:
5102
+ throw new CommandNotFoundError(commandId);
5103
+ }
5078
5104
  };
5079
5105
 
5080
- const WebView = 'lvce-oss-webview';
5081
-
5082
- const privilegedSchems = [{
5083
- scheme: scheme,
5084
- privileges: {
5085
- standard: true,
5086
- secure: true,
5087
- supportFetchAPI: true,
5088
- stream: true,
5089
- codeCache: true
5090
- }
5091
- }, {
5092
- scheme: WebView,
5093
- privileges: {
5094
- standard: true,
5095
- secure: true,
5096
- supportFetchAPI: true,
5097
- stream: true,
5098
- codeCache: true
5099
- }
5100
- }];
5101
-
5102
- /**
5103
- *
5104
- * @param {Electron.Protocol} protocol
5105
- * @param {string} name
5106
- * @param {(request: GlobalRequest) => Promise<GlobalResponse>} handleRequest
5107
- * @returns
5108
- */
5109
- const handle = (protocol, name, handleRequest) => {
5110
- if (isProtocolHandleApiSupported(protocol)) {
5111
- protocol.handle(name, handleRequest);
5106
+ const state$4 = {
5107
+ commands: Object.create(null),
5108
+ pendingModules: Object.create(null),
5109
+ async load(moduleId) {}
5110
+ };
5111
+ const initializeModule = module => {
5112
+ if (module.Commands) {
5113
+ for (const [key, value] of Object.entries(module.Commands)) {
5114
+ if (module.name) {
5115
+ const actualKey = `${module.name}.${key}`;
5116
+ register(actualKey, value);
5117
+ } else {
5118
+ register(key, value);
5119
+ }
5120
+ }
5112
5121
  return;
5113
5122
  }
5114
- throw new Error('protocol.handle api is not supported');
5123
+ throw new Error(`module ${module.name || '<unnamed module>'} is missing commands`);
5115
5124
  };
5116
-
5117
- /**
5118
- *
5119
- * @param {Electron.Protocol} protocol
5120
- * @returns
5121
- */
5122
- const enable = protocol => {
5123
- protocol.registerSchemesAsPrivileged(privilegedSchems);
5125
+ const getOrLoadModule = moduleId => {
5126
+ if (!state$4.pendingModules[moduleId]) {
5127
+ const importPromise = state$4.load(moduleId);
5128
+ state$4.pendingModules[moduleId] = importPromise.then(initializeModule);
5129
+ }
5130
+ return state$4.pendingModules[moduleId];
5124
5131
  };
5125
-
5126
- const requestSingleInstanceLock = argv => {
5127
- return app.requestSingleInstanceLock(argv);
5132
+ const loadCommand = command => getOrLoadModule(getModuleId(command));
5133
+ const register = (commandId, listener) => {
5134
+ state$4.commands[commandId] = listener;
5128
5135
  };
5129
-
5130
- // TODO maybe handle critical (first render) request via ipcMain
5131
- // and spawn shared process when page is idle/loaded
5132
- // currently launching shared process takes 170ms
5133
- // which means first paint is delayed by a lot
5134
-
5135
- const hydrate = async () => {
5136
- setMenu(null); // performance
5137
- unhandled({
5138
- showDialog: true,
5139
- logger() {} // already exists in mainProcessMain.js
5140
- });
5141
-
5142
- // TODO electron error ERROR:sandbox_linux.cc(364)] InitializeSandbox() called with multiple threads in process gpu-process
5143
-
5144
- // TODO electron error [90611:0219/003126.546542:ERROR:gl_surface_presentation_helper.cc(260)] GetVSyncParametersIfAvailable() failed for 1 times!
5145
- // need to wait for solution https://github.com/electron/electron/issues/32760
5146
-
5147
- // TODO need to wait for playwright bugs to be resolved
5148
- // before being able to test multi-window behavior
5149
- // see https://github.com/microsoft/playwright/issues/12345
5150
-
5151
- const parsedCliArgs = parseCliArgs(argv);
5152
- const moduleId = canHandleFastCliArgs(parsedCliArgs);
5153
- if (moduleId) {
5154
- await handleFastCliArgs(moduleId, parsedCliArgs);
5155
- return;
5156
- }
5157
- if (isLinux && chromeUserDataPath) {
5158
- setUserDataPath(chromeUserDataPath);
5159
- setSessionDataPath(chromeUserDataPath);
5160
- setCrashDumpsPath(chromeUserDataPath);
5161
- setLogsPath(chromeUserDataPath);
5162
- }
5163
- const hasLock = requestSingleInstanceLock(argv);
5164
- if (!hasLock) {
5165
- debug('[info] quitting because no lock');
5166
- exit();
5167
- return;
5136
+ const hasThrown = new Set();
5137
+ const loadThenExecute = async (command, ...args) => {
5138
+ await loadCommand(command);
5139
+ // TODO can skip then block in prod (only to prevent endless loop in dev)
5140
+ if (!(command in state$4.commands)) {
5141
+ if (hasThrown.has(command)) {
5142
+ return;
5143
+ }
5144
+ hasThrown.add(command);
5145
+ throw new Error(`Command did not register "${command}"`);
5168
5146
  }
5169
-
5170
- // TODO tree shake out the .env.DEV check: reading from env variables is expensive
5171
- if (process.stdout.isTTY && !parsedCliArgs.wait && !process.env.DEV) {
5172
- spawn(execPath, argv.slice(1), {
5173
- detached: true,
5174
- stdio: 'ignore'
5175
- });
5176
- exit$1(Success);
5147
+ return execute(command, ...args);
5148
+ };
5149
+ const execute = (command, ...args) => {
5150
+ if (command in state$4.commands) {
5151
+ return state$4.commands[command](...args);
5177
5152
  }
5178
-
5179
- // command line switches
5180
- enable$1(parsedCliArgs);
5181
-
5182
- // protocol
5183
- enable(Electron.protocol);
5184
-
5185
- // app
5186
- on(WindowAllClosed, handleWindowAllClosed);
5187
- on(BeforeQuit, handleBeforeQuit);
5188
- on(WebContentsCreated, handleWebContentsCreated);
5189
- on(SecondInstance, handleSecondInstance);
5190
- await whenReady();
5191
- mark(AppReady);
5192
- await handleReady(parsedCliArgs, cwd());
5193
- debug('[info] app window created');
5153
+ return loadThenExecute(command, ...args);
5154
+ };
5155
+ const setLoad = load => {
5156
+ state$4.load = load;
5194
5157
  };
5195
5158
 
5196
5159
  const ClipBoardRead = 'clipboard-read';
@@ -5298,6 +5261,35 @@ const set$1 = value => {
5298
5261
  state$3.session = value;
5299
5262
  };
5300
5263
 
5264
+ const printPrettyError = (prettyError, prefix = '') => {
5265
+ error(`${prefix}${prettyError.type}: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}\n`);
5266
+ };
5267
+
5268
+ const logError = (error, prettyError) => {
5269
+ printPrettyError(prettyError, '[main-process] ');
5270
+ };
5271
+ const handleMessage = event => {
5272
+ return handleJsonRpcMessage(event.target, event.data, execute, resolve, prepare,
5273
+ // @ts-ignore
5274
+ logError, requiresSocket);
5275
+ };
5276
+
5277
+ const handleIpc = ipc => {
5278
+ if ('addEventListener' in ipc) {
5279
+ ipc.addEventListener('message', handleMessage);
5280
+ } else if ('on' in ipc) {
5281
+ // deprecated
5282
+ ipc.on('message', handleMessage);
5283
+ }
5284
+ };
5285
+ const unhandleIpc = ipc => {
5286
+ if ('removeEventListener' in ipc) {
5287
+ ipc.removeEventListener('message', handleMessage);
5288
+ } else if ('off' in ipc) {
5289
+ ipc.off('message', handleMessage);
5290
+ }
5291
+ };
5292
+
5301
5293
  const NodeWorker = 1;
5302
5294
  const NodeForkedProcess = 2;
5303
5295
  const ElectronUtilityProcess = 3;
@@ -5496,19 +5488,57 @@ const crashMainProcess$1 = () => {
5496
5488
  setTimeout(handleTimeout, 0);
5497
5489
  };
5498
5490
 
5491
+ const transferMessagePortMain = async (ipc, port, ...params) => {
5492
+ try {
5493
+ await invokeAndTransfer$1(ipc, 'HandleElectronMessagePort.handleElectronMessagePort', port, ...params);
5494
+ } catch (error) {
5495
+ throw new VError(error, `Failed to send message port to utility process`);
5496
+ }
5497
+ };
5498
+
5499
+ const connectIpc$2 = async (ipc, browserWindowPort, ...params) => {
5500
+ await transferMessagePortMain(ipc, browserWindowPort, ...params);
5501
+ };
5502
+
5503
+ const transferMessagePort = async (ipc, port, ...params) => {
5504
+ try {
5505
+ await invokeAndTransfer$1(ipc, 'HandleNodeMessagePort.handleNodeMessagePort', port, ...params);
5506
+ } catch (error) {
5507
+ throw new VError(error, `Failed to send message port to worker thread`);
5508
+ }
5509
+ };
5510
+
5511
+ const connectIpc$1 = async (ipc, browserWindowPort, ...params) => {
5512
+ const messageChannel = new MessageChannel();
5513
+ const {
5514
+ port1,
5515
+ port2
5516
+ } = messageChannel;
5517
+ browserWindowPort.on('message', event => {
5518
+ // console.log('got message from browser window', event.data)
5519
+ port2.postMessage(event.data);
5520
+ });
5521
+ port2.on('message', message => {
5522
+ // console.log('send message to browser window', message)
5523
+ browserWindowPort.postMessage(message);
5524
+ });
5525
+ await transferMessagePort(ipc, port1, ...params);
5526
+ browserWindowPort.start();
5527
+ };
5528
+
5499
5529
  const getModule = method => {
5500
5530
  switch (method) {
5501
5531
  case NodeWorker:
5502
- return Promise.resolve().then(function () { return ConnectIpcNodeWorker; });
5532
+ return connectIpc$1;
5503
5533
  case ElectronUtilityProcess:
5504
- return Promise.resolve().then(function () { return ConnectIpcElectronUtilityProcess; });
5534
+ return connectIpc$2;
5505
5535
  default:
5506
5536
  throw new Error('unexpected ipc type');
5507
5537
  }
5508
5538
  };
5509
- const connectIpc$2 = async (method, ipc, browserWindowPort, ipcId) => {
5510
- const module = await getModule(method);
5511
- return module.connectIpc(ipc, browserWindowPort, ipcId);
5539
+ const connectIpc = async (method, ipc, browserWindowPort, ipcId) => {
5540
+ const connectIpc = getModule(method);
5541
+ return connectIpc(ipc, browserWindowPort, ipcId);
5512
5542
  };
5513
5543
 
5514
5544
  // TODO maybe handle critical (first render) request via ipcMain
@@ -5531,7 +5561,7 @@ const handlePort = async (browserWindowPort, ipcId) => {
5531
5561
  FOLDER: ''
5532
5562
  }
5533
5563
  });
5534
- await connectIpc$2(method, sharedProcess, browserWindowPort, ipcId);
5564
+ await connectIpc(method, sharedProcess.ipc, browserWindowPort, ipcId);
5535
5565
  };
5536
5566
 
5537
5567
  // TODO reverse order of parameters: make ports first
@@ -7280,54 +7310,6 @@ const index = {
7280
7310
  default: isDev
7281
7311
  };
7282
7312
 
7283
- const transferMessagePort = async (ipc, port, ...params) => {
7284
- try {
7285
- await invokeAndTransfer$1(ipc, 'HandleNodeMessagePort.handleNodeMessagePort', port, ...params);
7286
- } catch (error) {
7287
- throw new VError(error, `Failed to send message port to worker thread`);
7288
- }
7289
- };
7290
-
7291
- const connectIpc$1 = async (ipc, browserWindowPort, ...params) => {
7292
- const messageChannel = new MessageChannel();
7293
- const {
7294
- port1,
7295
- port2
7296
- } = messageChannel;
7297
- browserWindowPort.on('message', event => {
7298
- // console.log('got message from browser window', event.data)
7299
- port2.postMessage(event.data);
7300
- });
7301
- port2.on('message', message => {
7302
- // console.log('send message to browser window', message)
7303
- browserWindowPort.postMessage(message);
7304
- });
7305
- await transferMessagePort(ipc, port1, ...params);
7306
- browserWindowPort.start();
7307
- };
7308
-
7309
- const ConnectIpcNodeWorker = {
7310
- __proto__: null,
7311
- connectIpc: connectIpc$1
7312
- };
7313
-
7314
- const transferMessagePortMain = async (ipc, port, ...params) => {
7315
- try {
7316
- await invokeAndTransfer$1(ipc, 'HandleElectronMessagePort.handleElectronMessagePort', port, ...params);
7317
- } catch (error) {
7318
- throw new VError(error, `Failed to send message port to utility process`);
7319
- }
7320
- };
7321
-
7322
- const connectIpc = async (ipc, browserWindowPort, ...params) => {
7323
- await transferMessagePortMain(ipc, browserWindowPort, ...params);
7324
- };
7325
-
7326
- const ConnectIpcElectronUtilityProcess = {
7327
- __proto__: null,
7328
- connectIpc
7329
- };
7330
-
7331
7313
  const name$w = 'App';
7332
7314
  const Commands$w = {};
7333
7315
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-process",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "lvce-editor",