@lvce-editor/main-process 6.8.0 → 6.8.2

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.
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
5
5
  import { inspect } from 'node:util';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { Console } from 'node:console';
8
- import { createWriteStream, readFileSync, openAsBlob, existsSync } from 'node:fs';
8
+ import { createWriteStream, readFileSync, openAsBlob, existsSync, mkdirSync, openSync, writeSync, closeSync, rmSync } from 'node:fs';
9
9
  import { tmpdir, homedir } from 'node:os';
10
10
  import * as NodePath from 'node:path';
11
11
  import { dirname, join as join$1 } from 'node:path';
@@ -2794,6 +2794,78 @@ const create$4 = async ({
2794
2794
 
2795
2795
  const commandMapRef = Object.create(null);
2796
2796
 
2797
+ const Dash = '-';
2798
+ const Space$2 = ' ';
2799
+
2800
+ const firstLetterLowerCase = string => {
2801
+ return string[0].toLowerCase() + string.slice(1);
2802
+ };
2803
+ const camelCase = string => {
2804
+ const parts = string.split(Space$2);
2805
+ const lowerParts = parts.map(firstLetterLowerCase);
2806
+ return lowerParts.join(Dash);
2807
+ };
2808
+
2809
+ const formatUtilityProcessName = name => {
2810
+ return camelCase(name);
2811
+ };
2812
+
2813
+ const state$5 = {
2814
+ all: Object.create(null)
2815
+ };
2816
+ const add$1 = (pid, process, name) => {
2817
+ number(pid);
2818
+ object(process);
2819
+ string(name);
2820
+ state$5.all[pid] = {
2821
+ name,
2822
+ process
2823
+ };
2824
+ };
2825
+ const remove$1 = pid => {
2826
+ number(pid);
2827
+ delete state$5.all[pid];
2828
+ };
2829
+ const getAll = () => {
2830
+ return Object.entries(state$5.all);
2831
+ };
2832
+ const getByName = name => {
2833
+ for (const value of Object.values(state$5.all)) {
2834
+ // @ts-ignore
2835
+ if (value.name === name) {
2836
+ // @ts-ignore
2837
+ return value.process;
2838
+ }
2839
+ }
2840
+ return undefined;
2841
+ };
2842
+
2843
+ const trackUtilityProcess = (rawIpc, name) => {
2844
+ if (!rawIpc?.pid) {
2845
+ return;
2846
+ }
2847
+ const {
2848
+ pid
2849
+ } = rawIpc;
2850
+ const formattedName = formatUtilityProcessName(name);
2851
+ add$1(pid, rawIpc, formattedName);
2852
+ const cleanup = () => {
2853
+ remove$1(pid);
2854
+ rawIpc.off('exit', handleExit);
2855
+ };
2856
+ const handleExit = () => {
2857
+ cleanup();
2858
+ };
2859
+ rawIpc.on('exit', handleExit);
2860
+ };
2861
+
2862
+ const createElectronUtilityProcessRpc = async options => {
2863
+ const rpc = await create$5(options);
2864
+ const rpcWithRawIpc = rpc;
2865
+ trackUtilityProcess(rpcWithRawIpc.ipc?._rawIpc, options.name);
2866
+ return rpc;
2867
+ };
2868
+
2797
2869
  const getPortTuple = () => {
2798
2870
  const {
2799
2871
  port1,
@@ -2904,7 +2976,7 @@ const launchSharedProcess = async ({
2904
2976
  ...process.env,
2905
2977
  ...env
2906
2978
  };
2907
- const sharedProcessRpc = await create$5({
2979
+ const sharedProcessRpc = await createElectronUtilityProcessRpc({
2908
2980
  argv: [],
2909
2981
  commandMap: commandMapRef,
2910
2982
  env: fullEnv,
@@ -2942,7 +3014,7 @@ const launchSharedProcess = async ({
2942
3014
  return sharedProcessRpc;
2943
3015
  };
2944
3016
 
2945
- const state$5 = {
3017
+ const state$4 = {
2946
3018
  /**
2947
3019
  * @type {any}
2948
3020
  */
@@ -2953,14 +3025,14 @@ const getOrCreate = async ({
2953
3025
  env = {},
2954
3026
  method
2955
3027
  }) => {
2956
- if (!state$5.promise) {
3028
+ if (!state$4.promise) {
2957
3029
  // @ts-ignore
2958
- state$5.promise = launchSharedProcess({
3030
+ state$4.promise = launchSharedProcess({
2959
3031
  env,
2960
3032
  method
2961
3033
  });
2962
3034
  }
2963
- return state$5.promise;
3035
+ return state$4.promise;
2964
3036
  };
2965
3037
  const send$1 = async (method, ...params) => {
2966
3038
  const rpc = await getOrCreate({
@@ -3123,14 +3195,14 @@ const createTitleBar = items => {
3123
3195
 
3124
3196
  const PHASE_DEFAULT = 0;
3125
3197
  const PHASE_SHUTDOWN = -1;
3126
- const state$4 = {
3198
+ const state$3 = {
3127
3199
  phase: PHASE_DEFAULT
3128
3200
  };
3129
3201
  const isShutDown = () => {
3130
- return state$4.phase === PHASE_SHUTDOWN;
3202
+ return state$3.phase === PHASE_SHUTDOWN;
3131
3203
  };
3132
3204
  const setShutDown = () => {
3133
- state$4.phase = PHASE_SHUTDOWN;
3205
+ state$3.phase = PHASE_SHUTDOWN;
3134
3206
  };
3135
3207
 
3136
3208
  // TODO move this function to shared process
@@ -3427,21 +3499,21 @@ const openExternal = async url => {
3427
3499
  await shell.openExternal(url);
3428
3500
  };
3429
3501
 
3430
- const state$3 = {
3502
+ const state$2 = {
3431
3503
  canceled: Object.create(null),
3432
3504
  fallThroughKeyBindings: [],
3433
3505
  views: Object.create(null)
3434
3506
  };
3435
- const add$1 = (id, browserWindow, view) => {
3507
+ const add = (id, browserWindow, view) => {
3436
3508
  // state
3437
- state$3.views[id] = {
3509
+ state$2.views[id] = {
3438
3510
  browserWindow,
3439
3511
  view
3440
3512
  };
3441
3513
  };
3442
3514
  const hasWebContents = id => {
3443
3515
  number(id);
3444
- return id in state$3.views;
3516
+ return id in state$2.views;
3445
3517
  };
3446
3518
  /**
3447
3519
  *
@@ -3449,19 +3521,19 @@ const hasWebContents = id => {
3449
3521
  * @returns {{browserWindow: Electron.BrowserWindow, view: Electron.WebContentsView}}
3450
3522
  */
3451
3523
  const get$3 = id => {
3452
- return state$3.views[id];
3524
+ return state$2.views[id];
3453
3525
  };
3454
- const remove$1 = id => {
3455
- delete state$3.views[id];
3526
+ const remove = id => {
3527
+ delete state$2.views[id];
3456
3528
  };
3457
3529
  const setFallthroughKeyBindings = fallthroughKeyBindings => {
3458
- state$3.fallThroughKeyBindings = fallthroughKeyBindings;
3530
+ state$2.fallThroughKeyBindings = fallthroughKeyBindings;
3459
3531
  };
3460
3532
  const getFallthroughKeyBindings = () => {
3461
- return state$3.fallThroughKeyBindings;
3533
+ return state$2.fallThroughKeyBindings;
3462
3534
  };
3463
3535
  const setCanceled = id => {
3464
- state$3.canceled[id] = true;
3536
+ state$2.canceled[id] = true;
3465
3537
  };
3466
3538
 
3467
3539
  const shouldAllowNavigation = webContentsId => {
@@ -3775,20 +3847,20 @@ const createElectronSession = () => {
3775
3847
  return session;
3776
3848
  };
3777
3849
 
3778
- const state$2 = {
3850
+ const state$1 = {
3779
3851
  session: undefined
3780
3852
  };
3781
3853
  const has = () => {
3782
- return Boolean(state$2.session);
3854
+ return Boolean(state$1.session);
3783
3855
  };
3784
3856
  const get$2 = () => {
3785
- if (!state$2.session) {
3857
+ if (!state$1.session) {
3786
3858
  throw new Error('session is not defined');
3787
3859
  }
3788
- return state$2.session;
3860
+ return state$1.session;
3789
3861
  };
3790
3862
  const set$1 = value => {
3791
- state$2.session = value;
3863
+ state$1.session = value;
3792
3864
  };
3793
3865
 
3794
3866
  const create$3 = rpc => {
@@ -4009,36 +4081,6 @@ const createMessagePort = async (ipcId, port, webContentsId) => {
4009
4081
  return webContentsId;
4010
4082
  };
4011
4083
 
4012
- const state$1 = {
4013
- all: Object.create(null)
4014
- };
4015
- const add = (pid, process, name) => {
4016
- number(pid);
4017
- object(process);
4018
- string(name);
4019
- state$1.all[pid] = {
4020
- name,
4021
- process
4022
- };
4023
- };
4024
- const remove = pid => {
4025
- number(pid);
4026
- delete state$1.all[pid];
4027
- };
4028
- const getAll = () => {
4029
- return Object.entries(state$1.all);
4030
- };
4031
- const getByName = name => {
4032
- for (const value of Object.values(state$1.all)) {
4033
- // @ts-ignore
4034
- if (value.name === name) {
4035
- // @ts-ignore
4036
- return value.process;
4037
- }
4038
- }
4039
- return undefined;
4040
- };
4041
-
4042
4084
  const createPidMap = () => {
4043
4085
  const browserWindows = BrowserWindow.getAllWindows();
4044
4086
  const utilityProcesses = getAll();
@@ -4080,7 +4122,7 @@ const get = id => {
4080
4122
  };
4081
4123
 
4082
4124
  const createUtilityProcessRpc = async options => {
4083
- const rpc = await create$5({
4125
+ const rpc = await createElectronUtilityProcessRpc({
4084
4126
  commandMap: commandMapRef,
4085
4127
  ...options
4086
4128
  });
@@ -4226,6 +4268,100 @@ const openContextMenu = async (menuItems, x, y) => {
4226
4268
  }
4227
4269
  };
4228
4270
 
4271
+ const getFileName = workerName => {
4272
+ const safeWorkerName = workerName.replaceAll(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-/, '').replace(/-$/, '') || 'worker';
4273
+ return `${safeWorkerName}-${Date.now()}.heapsnapshot`;
4274
+ };
4275
+ const takeWorkerHeapSnapshot = async (windowId, workerName) => {
4276
+ number(windowId);
4277
+ string(workerName);
4278
+ const browserWindow = Electron.BrowserWindow.fromId(windowId);
4279
+ if (!browserWindow) {
4280
+ throw new Error(`Browser window not found: ${windowId}`);
4281
+ }
4282
+ const electronDebugger = browserWindow.webContents.debugger;
4283
+ const wasAttached = electronDebugger.isAttached();
4284
+ let fileDescriptor;
4285
+ let filePath = '';
4286
+ let sessionId = '';
4287
+ let success = false;
4288
+ if (!wasAttached) {
4289
+ electronDebugger.attach();
4290
+ }
4291
+ try {
4292
+ const {
4293
+ frameTree
4294
+ } = await electronDebugger.sendCommand('Page.getFrameTree');
4295
+ const {
4296
+ targetInfos
4297
+ } = await electronDebugger.sendCommand('Target.getTargets');
4298
+ const target = targetInfos.find(targetInfo => targetInfo.type === 'worker' && targetInfo.title === workerName && targetInfo.parentFrameId === frameTree.frame.id);
4299
+ if (!target) {
4300
+ throw new Error(`Worker not found: ${workerName}`);
4301
+ }
4302
+ const attachResult = await electronDebugger.sendCommand('Target.attachToTarget', {
4303
+ flatten: true,
4304
+ targetId: target.targetId
4305
+ });
4306
+ sessionId = attachResult.sessionId;
4307
+ const downloadsPath = Electron.app.getPath('downloads');
4308
+ mkdirSync(downloadsPath, {
4309
+ recursive: true
4310
+ });
4311
+ filePath = join$1(downloadsPath, getFileName(workerName));
4312
+ fileDescriptor = openSync(filePath, 'wx');
4313
+ const currentFileDescriptor = fileDescriptor;
4314
+ let writeError;
4315
+ const handleMessage = (_event, method, parameters, messageSessionId) => {
4316
+ if (method !== 'HeapProfiler.addHeapSnapshotChunk' || messageSessionId !== sessionId || writeError) {
4317
+ return;
4318
+ }
4319
+ try {
4320
+ writeSync(currentFileDescriptor, parameters.chunk);
4321
+ } catch (error) {
4322
+ writeError = error;
4323
+ }
4324
+ };
4325
+ electronDebugger.on('message', handleMessage);
4326
+ try {
4327
+ await electronDebugger.sendCommand('HeapProfiler.enable', undefined, sessionId);
4328
+ await electronDebugger.sendCommand('HeapProfiler.takeHeapSnapshot', {
4329
+ reportProgress: false
4330
+ }, sessionId);
4331
+ if (writeError) {
4332
+ throw writeError;
4333
+ }
4334
+ } finally {
4335
+ electronDebugger.off('message', handleMessage);
4336
+ }
4337
+ success = true;
4338
+ return filePath;
4339
+ } finally {
4340
+ try {
4341
+ if (fileDescriptor !== undefined) {
4342
+ closeSync(fileDescriptor);
4343
+ }
4344
+ if (!success && filePath) {
4345
+ rmSync(filePath, {
4346
+ force: true
4347
+ });
4348
+ }
4349
+ } finally {
4350
+ try {
4351
+ if (sessionId && electronDebugger.isAttached()) {
4352
+ await electronDebugger.sendCommand('Target.detachFromTarget', {
4353
+ sessionId
4354
+ });
4355
+ }
4356
+ } finally {
4357
+ if (!wasAttached && electronDebugger.isAttached()) {
4358
+ electronDebugger.detach();
4359
+ }
4360
+ }
4361
+ }
4362
+ }
4363
+ };
4364
+
4229
4365
  const getPerformanceEntries = () => {
4230
4366
  const entries = getEntries();
4231
4367
  const {
@@ -4590,7 +4726,7 @@ const KeyDown = 'keyDown';
4590
4726
 
4591
4727
  const Backspace$1 = 'Backspace';
4592
4728
  const Tab$1 = 'Tab';
4593
- const Space$2 = ' ';
4729
+ const Space$1 = ' ';
4594
4730
  const Enter$1 = 'Enter';
4595
4731
  const Escape$1 = 'Escape';
4596
4732
  const PageUp$1 = 'PageUp';
@@ -4682,7 +4818,7 @@ const Backspace = 1;
4682
4818
  const Tab = 2;
4683
4819
  const Enter = 3;
4684
4820
  const Escape = 8;
4685
- const Space$1 = 9;
4821
+ const Space = 9;
4686
4822
  const PageUp = 10;
4687
4823
  const PageDown = 11;
4688
4824
  const End = 255;
@@ -4852,7 +4988,7 @@ const keyCodeMap = {
4852
4988
  [RightArrow$1]: RightArrow,
4853
4989
  [SemiColon$1]: SemiColon,
4854
4990
  [Slash$1]: Slash,
4855
- [Space$2]: Space$1,
4991
+ [Space$1]: Space,
4856
4992
  [Star$1]: Star,
4857
4993
  [Tab$1]: Tab,
4858
4994
  [UpArrow$1]: UpArrow
@@ -5260,7 +5396,7 @@ const createWebContentsView = async () => {
5260
5396
  const {
5261
5397
  id
5262
5398
  } = webContents;
5263
- add$1(id, browserWindow, view);
5399
+ add(id, browserWindow, view);
5264
5400
  return id;
5265
5401
  };
5266
5402
  const attachEventListeners = webContentsId => {
@@ -5298,7 +5434,7 @@ const disposeWebContentsView = browserViewId => {
5298
5434
  browserWindow,
5299
5435
  view
5300
5436
  } = instance;
5301
- remove$1(browserViewId);
5437
+ remove(browserViewId);
5302
5438
  browserWindow.contentView.removeChildView(view);
5303
5439
  };
5304
5440
 
@@ -5386,6 +5522,10 @@ const getDomTree = async view => {
5386
5522
  const result = await getBodyOuterHtml(view);
5387
5523
  return getSlimCode(result);
5388
5524
  };
5525
+ const capturePage = async view => {
5526
+ const image = await view.webContents.capturePage();
5527
+ return image.toDataURL();
5528
+ };
5389
5529
  const insertCss = async (view, code) => {
5390
5530
  const {
5391
5531
  webContents
@@ -6718,22 +6858,6 @@ const create$1 = async ({
6718
6858
  return ipc;
6719
6859
  };
6720
6860
 
6721
- const Dash = '-';
6722
- const Space = ' ';
6723
-
6724
- const firstLetterLowerCase = string => {
6725
- return string[0].toLowerCase() + string.slice(1);
6726
- };
6727
- const camelCase = string => {
6728
- const parts = string.split(Space);
6729
- const lowerParts = parts.map(firstLetterLowerCase);
6730
- return lowerParts.join(Dash);
6731
- };
6732
-
6733
- const formatUtilityProcessName = name => {
6734
- return camelCase(name);
6735
- };
6736
-
6737
6861
  const {
6738
6862
  create
6739
6863
  } = IpcParentWithElectronUtilityProcess$1$1;
@@ -6744,22 +6868,7 @@ const effects = ({
6744
6868
  name,
6745
6869
  rawIpc
6746
6870
  }) => {
6747
- if (!rawIpc.pid) {
6748
- return;
6749
- }
6750
- const {
6751
- pid
6752
- } = rawIpc;
6753
- const formattedName = formatUtilityProcessName(name);
6754
- add(pid, rawIpc, formattedName);
6755
- const cleanup = () => {
6756
- remove(pid);
6757
- rawIpc.off('exit', handleExit);
6758
- };
6759
- const handleExit = () => {
6760
- cleanup();
6761
- };
6762
- rawIpc.on('exit', handleExit);
6871
+ trackUtilityProcess(rawIpc, name);
6763
6872
  };
6764
6873
 
6765
6874
  const IpcParentWithElectronUtilityProcess = {
@@ -6846,6 +6955,7 @@ const commandMap = {
6846
6955
  'ElectronContextMenu.openContextMenu': openContextMenu,
6847
6956
  'ElectronDeveloper.crashMainProcess': crashMainProcess,
6848
6957
  'ElectronDeveloper.getPerformanceEntries': getPerformanceEntries,
6958
+ 'ElectronDeveloper.takeWorkerHeapSnapshot': takeWorkerHeapSnapshot,
6849
6959
  'ElectronDialog.showMessageBox': showMessageBox,
6850
6960
  'ElectronDialog.showOpenDialog': showOpenDialog,
6851
6961
  'ElectronDialog.showSaveDialog': showSaveDialog,
@@ -6874,6 +6984,7 @@ const commandMap = {
6874
6984
  'ElectronWebContentsViewFunctions.addToWindow': addToWindow,
6875
6985
  'ElectronWebContentsViewFunctions.backward': wrapBrowserViewCommand(backward),
6876
6986
  'ElectronWebContentsViewFunctions.cancelNavigation': wrapBrowserViewCommand(cancelNavigation),
6987
+ 'ElectronWebContentsViewFunctions.capturePage': wrapBrowserViewCommand(capturePage),
6877
6988
  'ElectronWebContentsViewFunctions.copyImageAt': wrapBrowserViewCommand(copyImageAt),
6878
6989
  'ElectronWebContentsViewFunctions.executeJavaScript': wrapBrowserViewCommand(executeJavaScript),
6879
6990
  'ElectronWebContentsViewFunctions.focus': wrapBrowserViewCommand(focus),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-process",
3
- "version": "6.8.0",
3
+ "version": "6.8.2",
4
4
  "keywords": [
5
5
  "lvce-editor",
6
6
  "electron"