@lvce-editor/process-explorer-worker 3.4.0 → 3.6.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.
Files changed (2) hide show
  1. package/index.js +370 -7
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -184,7 +184,7 @@ const {
184
184
  dispose: dispose$3,
185
185
  get: get$2,
186
186
  getCommandIds,
187
- getKeys,
187
+ getKeys: getKeys$1,
188
188
  registerCommands,
189
189
  set: set$9,
190
190
  wrapCommand,
@@ -192,7 +192,14 @@ const {
192
192
  wrapLoadContent
193
193
  } = create$e();
194
194
 
195
- const create$d = (id, _uri, x, y, width, height, _args, parentUid, platform = 0, assetDir = '') => {
195
+ const getIncludeFrontendMemoryUsage = args => {
196
+ if (!args || typeof args !== 'object') {
197
+ return false;
198
+ }
199
+ const createArgs = args;
200
+ return createArgs.includeFrontendMemoryUsage === true;
201
+ };
202
+ const create$d = (id, _uri, x, y, width, height, args, parentUid, platform = 0, assetDir = '') => {
196
203
  const state = {
197
204
  assetDir,
198
205
  collapsedPids: [],
@@ -203,6 +210,7 @@ const create$d = (id, _uri, x, y, width, height, _args, parentUid, platform = 0,
203
210
  focused: false,
204
211
  focusedIndex: -1,
205
212
  height,
213
+ includeFrontendMemoryUsage: getIncludeFrontendMemoryUsage(args),
206
214
  initial: true,
207
215
  parentUid,
208
216
  platform,
@@ -1471,6 +1479,7 @@ const Th = 13;
1471
1479
  const THead = 14;
1472
1480
  const Tr = 15;
1473
1481
  const Pre = 51;
1482
+ const Reference = 100;
1474
1483
 
1475
1484
  const ClientX = 'event.clientX';
1476
1485
  const ClientY = 'event.clientY';
@@ -1508,6 +1517,7 @@ const TestWorker = 9001;
1508
1517
  const FocusSelector = 'Viewlet.focusSelector';
1509
1518
  const SetDom2 = 'Viewlet.setDom2';
1510
1519
  const SetFocusContext = 'Viewlet.setFocusContext';
1520
+ const SetPatches = 'Viewlet.setPatches';
1511
1521
 
1512
1522
  const Empty = 0;
1513
1523
  const FocusExplorer = 13;
@@ -2128,15 +2138,16 @@ const isEqual$1 = (oldState, newState) => {
2128
2138
  };
2129
2139
 
2130
2140
  const isEqual = (oldState, newState) => {
2131
- return oldState.initial === newState.initial && oldState.errorCodeFrame === newState.errorCodeFrame && oldState.errorMessage === newState.errorMessage && oldState.errorStack === newState.errorStack && oldState.visibleProcesses === newState.visibleProcesses;
2141
+ return oldState.initial === newState.initial && oldState.errorCodeFrame === newState.errorCodeFrame && oldState.errorMessage === newState.errorMessage && oldState.errorStack === newState.errorStack && oldState.focusedIndex === newState.focusedIndex && oldState.visibleProcesses === newState.visibleProcesses;
2132
2142
  };
2133
2143
 
2134
2144
  const RenderItems = 1;
2135
2145
  const RenderFocus = 2;
2136
2146
  const RenderFocusContext = 3;
2147
+ const RenderIncremental = 4;
2137
2148
 
2138
2149
  const modules = [isEqual, isEqual$1, isEqual$1];
2139
- const numbers = [RenderItems, RenderFocus, RenderFocusContext];
2150
+ const numbers = [RenderIncremental, RenderFocus, RenderFocusContext];
2140
2151
 
2141
2152
  const diff = (oldState, newState) => {
2142
2153
  const diffResult = [];
@@ -2170,7 +2181,7 @@ const dispose$1 = uid => {
2170
2181
  pending.delete(uid);
2171
2182
  };
2172
2183
  const update = async uid => {
2173
- if (!getKeys().includes(uid)) {
2184
+ if (!getKeys$1().includes(uid)) {
2174
2185
  dispose$1(uid);
2175
2186
  return;
2176
2187
  }
@@ -2458,6 +2469,86 @@ const killProcess = async (state, index = state.focusedIndex) => {
2458
2469
  return state;
2459
2470
  };
2460
2471
 
2472
+ const WindowPid = -1;
2473
+ const isValidMemoryValue = value => {
2474
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
2475
+ };
2476
+ const getMeasureMemory = () => {
2477
+ const {
2478
+ measureUserAgentSpecificMemory
2479
+ } = performance;
2480
+ if (typeof measureUserAgentSpecificMemory !== 'function') {
2481
+ return undefined;
2482
+ }
2483
+ return measureUserAgentSpecificMemory.bind(performance);
2484
+ };
2485
+ const getUrlName = url => {
2486
+ if (!url || url === 'cross-origin-url') {
2487
+ return url;
2488
+ }
2489
+ try {
2490
+ const parsed = new URL(url);
2491
+ const parts = parsed.pathname.split('/').filter(Boolean);
2492
+ return parts.at(-1) || parsed.hostname || url;
2493
+ } catch {
2494
+ const withoutQuery = url.split(/[?#]/, 1)[0];
2495
+ const parts = withoutQuery.split('/').filter(Boolean);
2496
+ return parts.at(-1) || url;
2497
+ }
2498
+ };
2499
+ const getAttributionName = attribution => {
2500
+ const scope = attribution.scope || 'memory';
2501
+ const url = attribution.url ? getUrlName(attribution.url) : '';
2502
+ if (url) {
2503
+ return `${scope}: ${url}`;
2504
+ }
2505
+ return scope;
2506
+ };
2507
+ const getBreakdownName = (entry, index) => {
2508
+ if (entry.attribution && entry.attribution.length > 0) {
2509
+ return entry.attribution.map(getAttributionName).join(', ');
2510
+ }
2511
+ if (entry.types && entry.types.length > 0) {
2512
+ return entry.types.join(', ');
2513
+ }
2514
+ return `breakdown ${index + 1}`;
2515
+ };
2516
+ const toBreakdownProcess = (entry, index) => {
2517
+ const name = getBreakdownName(entry, index);
2518
+ return {
2519
+ cmd: name,
2520
+ memory: entry.bytes,
2521
+ name,
2522
+ pid: -2 - index,
2523
+ ppid: WindowPid,
2524
+ synthetic: true
2525
+ };
2526
+ };
2527
+ const getFrontendMemoryUsage = async rootPid => {
2528
+ const measureMemory = getMeasureMemory();
2529
+ if (!measureMemory) {
2530
+ return [];
2531
+ }
2532
+ try {
2533
+ const measurement = await measureMemory();
2534
+ if (!isValidMemoryValue(measurement.bytes)) {
2535
+ return [];
2536
+ }
2537
+ const breakdown = measurement.breakdown || [];
2538
+ const breakdownProcesses = breakdown.filter(entry => isValidMemoryValue(entry.bytes) && entry.bytes > 0).map(toBreakdownProcess);
2539
+ return [{
2540
+ cmd: 'window',
2541
+ memory: measurement.bytes,
2542
+ name: 'window',
2543
+ pid: WindowPid,
2544
+ ppid: rootPid,
2545
+ synthetic: true
2546
+ }, ...breakdownProcesses];
2547
+ } catch {
2548
+ return [];
2549
+ }
2550
+ };
2551
+
2461
2552
  const sendMessagePortToProcessExplorer = async port => {
2462
2553
  const rendererWorker = RendererWorker;
2463
2554
  await rendererWorker.sendMessagePortToProcessExplorer(port);
@@ -2554,7 +2645,9 @@ const refresh = async state => {
2554
2645
  includeElectronData
2555
2646
  }));
2556
2647
  const processes = await invoke('ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage', rootPid, includeElectronData);
2557
- const visibleProcesses = getVisibleProcesses(processes, state.collapsedPids, rootPid);
2648
+ const frontendMemoryProcesses = state.includeFrontendMemoryUsage ? await getFrontendMemoryUsage(rootPid) : [];
2649
+ const allProcesses = [...processes, ...frontendMemoryProcesses];
2650
+ const visibleProcesses = getVisibleProcesses(allProcesses, state.collapsedPids, rootPid);
2558
2651
  return {
2559
2652
  ...state,
2560
2653
  errorCodeFrame: '',
@@ -2562,7 +2655,7 @@ const refresh = async state => {
2562
2655
  errorStack: '',
2563
2656
  focusedIndex: getFocusedIndex(state.focusedIndex, visibleProcesses),
2564
2657
  initial: false,
2565
- processes,
2658
+ processes: allProcesses,
2566
2659
  rootPid,
2567
2660
  visibleProcesses
2568
2661
  };
@@ -2612,6 +2705,267 @@ const text = data => {
2612
2705
  };
2613
2706
  };
2614
2707
 
2708
+ const SetText = 1;
2709
+ const Replace = 2;
2710
+ const SetAttribute = 3;
2711
+ const RemoveAttribute = 4;
2712
+ const Add = 6;
2713
+ const NavigateChild = 7;
2714
+ const NavigateParent = 8;
2715
+ const RemoveChild = 9;
2716
+ const NavigateSibling = 10;
2717
+ const SetReferenceNodeUid = 11;
2718
+
2719
+ const isKey = key => {
2720
+ return key !== 'type' && key !== 'childCount';
2721
+ };
2722
+
2723
+ const getKeys = node => {
2724
+ const keys = Object.keys(node).filter(isKey);
2725
+ return keys;
2726
+ };
2727
+
2728
+ const arrayToTree = nodes => {
2729
+ const result = [];
2730
+ let i = 0;
2731
+ while (i < nodes.length) {
2732
+ const node = nodes[i];
2733
+ const {
2734
+ children,
2735
+ nodesConsumed
2736
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
2737
+ result.push({
2738
+ node,
2739
+ children
2740
+ });
2741
+ i += 1 + nodesConsumed;
2742
+ }
2743
+ return result;
2744
+ };
2745
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
2746
+ if (childCount === 0) {
2747
+ return {
2748
+ children: [],
2749
+ nodesConsumed: 0
2750
+ };
2751
+ }
2752
+ const children = [];
2753
+ let i = startIndex;
2754
+ let remaining = childCount;
2755
+ let totalConsumed = 0;
2756
+ while (remaining > 0 && i < nodes.length) {
2757
+ const node = nodes[i];
2758
+ const nodeChildCount = node.childCount || 0;
2759
+ const {
2760
+ children: nodeChildren,
2761
+ nodesConsumed
2762
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
2763
+ children.push({
2764
+ node,
2765
+ children: nodeChildren
2766
+ });
2767
+ const nodeSize = 1 + nodesConsumed;
2768
+ i += nodeSize;
2769
+ totalConsumed += nodeSize;
2770
+ remaining--;
2771
+ }
2772
+ return {
2773
+ children,
2774
+ nodesConsumed: totalConsumed
2775
+ };
2776
+ };
2777
+
2778
+ const compareNodes = (oldNode, newNode) => {
2779
+ // Check if node type changed - return null to signal incompatible nodes
2780
+ // (caller should handle this with a Replace operation)
2781
+ if (oldNode.type !== newNode.type) {
2782
+ return null;
2783
+ }
2784
+ const patches = [];
2785
+ // Handle reference nodes - special handling for uid changes
2786
+ if (oldNode.type === Reference) {
2787
+ if (oldNode.uid !== newNode.uid) {
2788
+ patches.push({
2789
+ type: SetReferenceNodeUid,
2790
+ uid: newNode.uid
2791
+ });
2792
+ }
2793
+ return patches;
2794
+ }
2795
+ // Handle text nodes
2796
+ if (oldNode.type === Text && newNode.type === Text) {
2797
+ if (oldNode.text !== newNode.text) {
2798
+ patches.push({
2799
+ type: SetText,
2800
+ value: newNode.text
2801
+ });
2802
+ }
2803
+ return patches;
2804
+ }
2805
+ // Compare attributes
2806
+ const oldKeys = getKeys(oldNode);
2807
+ const newKeys = getKeys(newNode);
2808
+ // Check for attribute changes
2809
+ for (const key of newKeys) {
2810
+ if (oldNode[key] !== newNode[key]) {
2811
+ patches.push({
2812
+ type: SetAttribute,
2813
+ key,
2814
+ value: newNode[key]
2815
+ });
2816
+ }
2817
+ }
2818
+ // Check for removed attributes
2819
+ for (const key of oldKeys) {
2820
+ if (!Object.hasOwn(newNode, key)) {
2821
+ patches.push({
2822
+ type: RemoveAttribute,
2823
+ key
2824
+ });
2825
+ }
2826
+ }
2827
+ return patches;
2828
+ };
2829
+
2830
+ const treeToArray = node => {
2831
+ const result = [node.node];
2832
+ for (const child of node.children) {
2833
+ result.push(...treeToArray(child));
2834
+ }
2835
+ return result;
2836
+ };
2837
+
2838
+ const navigateToChild = (patches, currentChildIndex, index) => {
2839
+ if (currentChildIndex === -1) {
2840
+ patches.push({
2841
+ type: NavigateChild,
2842
+ index
2843
+ });
2844
+ return index;
2845
+ }
2846
+ if (currentChildIndex !== index) {
2847
+ patches.push({
2848
+ type: NavigateSibling,
2849
+ index
2850
+ });
2851
+ }
2852
+ return index;
2853
+ };
2854
+ const navigateToParent = (patches, currentChildIndex) => {
2855
+ if (currentChildIndex >= 0) {
2856
+ patches.push({
2857
+ type: NavigateParent
2858
+ });
2859
+ }
2860
+ return -1;
2861
+ };
2862
+ const addTree = (newNode, patches) => {
2863
+ patches.push({
2864
+ type: Add,
2865
+ nodes: treeToArray(newNode)
2866
+ });
2867
+ };
2868
+ const replaceTree = (newNode, patches) => {
2869
+ patches.push({
2870
+ type: Replace,
2871
+ nodes: treeToArray(newNode)
2872
+ });
2873
+ };
2874
+ const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
2875
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2876
+ if (nodePatches === null) {
2877
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
2878
+ replaceTree(newNode, patches);
2879
+ return nextChildIndex;
2880
+ }
2881
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
2882
+ if (nodePatches.length === 0 && !hasChildrenToCompare) {
2883
+ return currentChildIndex;
2884
+ }
2885
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
2886
+ if (nodePatches.length > 0) {
2887
+ patches.push(...nodePatches);
2888
+ }
2889
+ if (hasChildrenToCompare) {
2890
+ diffChildren(oldNode.children, newNode.children, patches);
2891
+ }
2892
+ return nextChildIndex;
2893
+ };
2894
+ const diffRootNode = (oldNode, newNode, patches) => {
2895
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2896
+ if (nodePatches === null) {
2897
+ replaceTree(newNode, patches);
2898
+ return;
2899
+ }
2900
+ if (nodePatches.length > 0) {
2901
+ patches.push(...nodePatches);
2902
+ }
2903
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
2904
+ diffChildren(oldNode.children, newNode.children, patches);
2905
+ }
2906
+ };
2907
+ const diffChildren = (oldChildren, newChildren, patches) => {
2908
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
2909
+ let currentChildIndex = -1;
2910
+ const indicesToRemove = [];
2911
+ for (let i = 0; i < maxLength; i++) {
2912
+ const oldNode = oldChildren[i];
2913
+ const newNode = newChildren[i];
2914
+ if (!oldNode && !newNode) {
2915
+ continue;
2916
+ }
2917
+ if (!oldNode) {
2918
+ currentChildIndex = navigateToParent(patches, currentChildIndex);
2919
+ addTree(newNode, patches);
2920
+ continue;
2921
+ }
2922
+ if (!newNode) {
2923
+ indicesToRemove.push(i);
2924
+ continue;
2925
+ }
2926
+ currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
2927
+ }
2928
+ navigateToParent(patches, currentChildIndex);
2929
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
2930
+ patches.push({
2931
+ type: RemoveChild,
2932
+ index: indicesToRemove[j]
2933
+ });
2934
+ }
2935
+ };
2936
+ const diffTrees = (oldTree, newTree, patches, path) => {
2937
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
2938
+ diffRootNode(oldTree[0], newTree[0], patches);
2939
+ return;
2940
+ }
2941
+ diffChildren(oldTree, newTree, patches);
2942
+ };
2943
+
2944
+ const removeTrailingNavigationPatches = patches => {
2945
+ // Find the last non-navigation patch
2946
+ let lastNonNavigationIndex = -1;
2947
+ for (let i = patches.length - 1; i >= 0; i--) {
2948
+ const patch = patches[i];
2949
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
2950
+ lastNonNavigationIndex = i;
2951
+ break;
2952
+ }
2953
+ }
2954
+ // Return patches up to and including the last non-navigation patch
2955
+ return lastNonNavigationIndex === -1 ? [] : patches.slice(0, lastNonNavigationIndex + 1);
2956
+ };
2957
+
2958
+ const diffTree = (oldNodes, newNodes) => {
2959
+ // Step 1: Convert flat arrays to tree structures
2960
+ const oldTree = arrayToTree(oldNodes);
2961
+ const newTree = arrayToTree(newNodes);
2962
+ // Step 3: Compare the trees
2963
+ const patches = [];
2964
+ diffTrees(oldTree, newTree, patches, []);
2965
+ // Remove trailing navigation patches since they serve no purpose
2966
+ return removeTrailingNavigationPatches(patches);
2967
+ };
2968
+
2615
2969
  const Grid = 'grid';
2616
2970
  const GridCell = 'gridcell';
2617
2971
  const None = 'none';
@@ -2797,12 +3151,21 @@ const renderItems = (oldState, newState) => {
2797
3151
  return [SetDom2, newState.uid, getDom(newState)];
2798
3152
  };
2799
3153
 
3154
+ const renderIncremental = (oldState, newState) => {
3155
+ const oldDom = renderItems(oldState, oldState)[2];
3156
+ const newDom = renderItems(newState, newState)[2];
3157
+ const patches = diffTree(oldDom, newDom);
3158
+ return [SetPatches, newState.uid, patches];
3159
+ };
3160
+
2800
3161
  const getRenderer = diffType => {
2801
3162
  switch (diffType) {
2802
3163
  case RenderFocus:
2803
3164
  return renderFocus;
2804
3165
  case RenderFocusContext:
2805
3166
  return renderFocusContext;
3167
+ case RenderIncremental:
3168
+ return renderIncremental;
2806
3169
  case RenderItems:
2807
3170
  return renderItems;
2808
3171
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/process-explorer-worker",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",