@lvce-editor/status-bar-worker 3.32.1 → 3.32.3

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.
@@ -263,15 +263,18 @@ const terminate = () => {
263
263
  const {
264
264
  get: get$5,
265
265
  getCommandIds,
266
- getKeys,
266
+ getKeys: getKeys$1,
267
267
  registerCommands,
268
268
  set: set$9,
269
269
  wrapCommand,
270
270
  wrapGetter,
271
271
  wrapSerialAsyncCommand} = create$a();
272
272
 
273
- const create$9 = (uid, uri, x, y, width, height, platform, assetDir) => {
273
+ const create$9 = (uid, uri, x, y, width, height, platform, assetDir, applicationId) => {
274
274
  const state = {
275
+ ...(applicationId !== undefined && {
276
+ applicationId
277
+ }),
275
278
  assetDir,
276
279
  errorCount: 0,
277
280
  initial: true,
@@ -509,6 +512,7 @@ const TextMeasurementWorker = 7011;
509
512
 
510
513
  const SetDom2 = 'Viewlet.setDom2';
511
514
  const SetFocusContext = 'Viewlet.setFocusContext';
515
+ const SetPatches = 'Viewlet.setPatches';
512
516
 
513
517
  const mergeClassNames = (...classNames) => {
514
518
  return classNames.filter(Boolean).join(' ');
@@ -524,6 +528,266 @@ const text = data => {
524
528
 
525
529
  new Set(Object.values(VirtualDomElements));
526
530
 
531
+ const SetText = 1;
532
+ const Replace = 2;
533
+ const SetAttribute = 3;
534
+ const RemoveAttribute = 4;
535
+ const Add = 6;
536
+ const NavigateChild = 7;
537
+ const NavigateParent = 8;
538
+ const RemoveChild = 9;
539
+ const NavigateSibling = 10;
540
+ const SetReferenceNodeUid = 11;
541
+
542
+ const isKey = key => {
543
+ return key !== 'type' && key !== 'childCount';
544
+ };
545
+
546
+ const getKeys = node => {
547
+ const keys = Object.keys(node).filter(isKey);
548
+ return keys;
549
+ };
550
+
551
+ const arrayToTree = nodes => {
552
+ const result = [];
553
+ let i = 0;
554
+ while (i < nodes.length) {
555
+ const node = nodes[i];
556
+ const {
557
+ children,
558
+ nodesConsumed
559
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
560
+ result.push({
561
+ node,
562
+ children
563
+ });
564
+ i += 1 + nodesConsumed;
565
+ }
566
+ return result;
567
+ };
568
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
569
+ if (childCount === 0) {
570
+ return {
571
+ children: [],
572
+ nodesConsumed: 0
573
+ };
574
+ }
575
+ const children = [];
576
+ let i = startIndex;
577
+ let remaining = childCount;
578
+ let totalConsumed = 0;
579
+ while (remaining > 0 && i < nodes.length) {
580
+ const node = nodes[i];
581
+ const nodeChildCount = node.childCount || 0;
582
+ const {
583
+ children: nodeChildren,
584
+ nodesConsumed
585
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
586
+ children.push({
587
+ node,
588
+ children: nodeChildren
589
+ });
590
+ const nodeSize = 1 + nodesConsumed;
591
+ i += nodeSize;
592
+ totalConsumed += nodeSize;
593
+ remaining--;
594
+ }
595
+ return {
596
+ children,
597
+ nodesConsumed: totalConsumed
598
+ };
599
+ };
600
+
601
+ const compareNodes = (oldNode, newNode) => {
602
+ // Check if node type changed - return null to signal incompatible nodes
603
+ // (caller should handle this with a Replace operation)
604
+ if (oldNode.type !== newNode.type) {
605
+ return null;
606
+ }
607
+ const patches = [];
608
+ // Handle reference nodes - special handling for uid changes
609
+ if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
610
+ patches.push({
611
+ type: SetReferenceNodeUid,
612
+ uid: newNode.uid
613
+ });
614
+ }
615
+ // Handle text nodes
616
+ if (oldNode.type === Text && newNode.type === Text) {
617
+ if (oldNode.text !== newNode.text) {
618
+ patches.push({
619
+ type: SetText,
620
+ value: newNode.text
621
+ });
622
+ }
623
+ return patches;
624
+ }
625
+ // Compare attributes
626
+ const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
627
+ const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
628
+ // Check for attribute changes
629
+ for (const key of newKeys) {
630
+ if (oldNode[key] !== newNode[key]) {
631
+ patches.push({
632
+ type: SetAttribute,
633
+ key,
634
+ value: newNode[key]
635
+ });
636
+ }
637
+ }
638
+ // Check for removed attributes
639
+ for (const key of oldKeys) {
640
+ if (!Object.hasOwn(newNode, key)) {
641
+ patches.push({
642
+ type: RemoveAttribute,
643
+ key
644
+ });
645
+ }
646
+ }
647
+ return patches;
648
+ };
649
+
650
+ const treeToArray = node => {
651
+ const result = [];
652
+ const stack = [node];
653
+ while (stack.length > 0) {
654
+ const current = stack.pop();
655
+ result.push(current.node);
656
+ for (let i = current.children.length - 1; i >= 0; i--) {
657
+ stack.push(current.children[i]);
658
+ }
659
+ }
660
+ return result;
661
+ };
662
+
663
+ const navigateToChild = (patches, currentChildIndex, index) => {
664
+ if (currentChildIndex === -1) {
665
+ patches.push({
666
+ type: NavigateChild,
667
+ index
668
+ });
669
+ return index;
670
+ }
671
+ if (currentChildIndex !== index) {
672
+ patches.push({
673
+ type: NavigateSibling,
674
+ index
675
+ });
676
+ }
677
+ return index;
678
+ };
679
+ const navigateToParent = (patches, currentChildIndex) => {
680
+ if (currentChildIndex >= 0) {
681
+ patches.push({
682
+ type: NavigateParent
683
+ });
684
+ }
685
+ return -1;
686
+ };
687
+ const addTree = (newNode, patches) => {
688
+ patches.push({
689
+ type: Add,
690
+ nodes: treeToArray(newNode)
691
+ });
692
+ };
693
+ const replaceTree = (newNode, patches) => {
694
+ patches.push({
695
+ type: Replace,
696
+ nodes: treeToArray(newNode)
697
+ });
698
+ };
699
+ const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
700
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
701
+ if (nodePatches === null) {
702
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
703
+ replaceTree(newNode, patches);
704
+ return nextChildIndex;
705
+ }
706
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
707
+ if (nodePatches.length === 0 && !hasChildrenToCompare) {
708
+ return currentChildIndex;
709
+ }
710
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
711
+ if (nodePatches.length > 0) {
712
+ patches.push(...nodePatches);
713
+ }
714
+ if (hasChildrenToCompare) {
715
+ diffChildren(oldNode.children, newNode.children, patches);
716
+ }
717
+ return nextChildIndex;
718
+ };
719
+ const diffRootNode = (oldNode, newNode, patches) => {
720
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
721
+ if (nodePatches === null) {
722
+ replaceTree(newNode, patches);
723
+ return;
724
+ }
725
+ if (nodePatches.length > 0) {
726
+ patches.push(...nodePatches);
727
+ }
728
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
729
+ diffChildren(oldNode.children, newNode.children, patches);
730
+ }
731
+ };
732
+ const diffChildren = (oldChildren, newChildren, patches) => {
733
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
734
+ let currentChildIndex = -1;
735
+ const indicesToRemove = [];
736
+ for (let i = 0; i < maxLength; i++) {
737
+ const oldNode = oldChildren[i];
738
+ const newNode = newChildren[i];
739
+ if (!oldNode && !newNode) {
740
+ continue;
741
+ }
742
+ if (!oldNode) {
743
+ currentChildIndex = navigateToParent(patches, currentChildIndex);
744
+ addTree(newNode, patches);
745
+ continue;
746
+ }
747
+ if (!newNode) {
748
+ indicesToRemove.push(i);
749
+ continue;
750
+ }
751
+ currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
752
+ }
753
+ navigateToParent(patches, currentChildIndex);
754
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
755
+ patches.push({
756
+ type: RemoveChild,
757
+ index: indicesToRemove[j]
758
+ });
759
+ }
760
+ };
761
+ const diffTrees = (oldTree, newTree, patches, path) => {
762
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
763
+ diffRootNode(oldTree[0], newTree[0], patches);
764
+ return;
765
+ }
766
+ diffChildren(oldTree, newTree, patches);
767
+ };
768
+
769
+ const removeTrailingNavigationPatches = patches => {
770
+ while (patches.length > 0) {
771
+ const patch = patches.at(-1);
772
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
773
+ break;
774
+ }
775
+ patches.pop();
776
+ }
777
+ return patches;
778
+ };
779
+
780
+ const diffTree = (oldNodes, newNodes) => {
781
+ // Step 1: Convert flat arrays to tree structures
782
+ const oldTree = arrayToTree(oldNodes);
783
+ const newTree = arrayToTree(newNodes);
784
+ // Step 3: Compare the trees
785
+ const patches = [];
786
+ diffTrees(oldTree, newTree, patches, []);
787
+ // Remove trailing navigation patches since they serve no purpose
788
+ return removeTrailingNavigationPatches(patches);
789
+ };
790
+
527
791
  const HandleContextMenu = 2;
528
792
  const HandleClick = 11;
529
793
 
@@ -1885,9 +2149,16 @@ const getPreference = async key => {
1885
2149
  return await invoke$2('Preferences.get', key);
1886
2150
  };
1887
2151
 
1888
- const handleClickExtensionStatusBarItem = async name => {
2152
+ const invokeExtensionCommand = (applicationId, command, ...args) => {
2153
+ if (applicationId !== undefined) {
2154
+ return invoke$5('Extensions.invokeForApplication', applicationId, command, ...args);
2155
+ }
2156
+ return invoke$5(command, ...args);
2157
+ };
2158
+
2159
+ const handleClickExtensionStatusBarItem = async (name, applicationId) => {
1889
2160
  try {
1890
- await invoke$5('Extensions.executeCommand', name);
2161
+ await invokeExtensionCommand(applicationId, 'Extensions.executeCommand', name);
1891
2162
  } catch (error) {
1892
2163
  console.error(new VError(error, `Failed to execute status bar command: ${name}`));
1893
2164
  }
@@ -1907,6 +2178,7 @@ const handleClick = async (state, name) => {
1907
2178
  return state;
1908
2179
  }
1909
2180
  const {
2181
+ applicationId,
1910
2182
  editorStatus,
1911
2183
  statusBarItemsLeft,
1912
2184
  statusBarItemsRight
@@ -1922,7 +2194,7 @@ const handleClick = async (state, name) => {
1922
2194
  } else if (isEditorStatus(item.name)) {
1923
2195
  await handleClickEditorStatus(item.name, editorStatus);
1924
2196
  } else if (item.command && !isEditorStatus(item.name)) {
1925
- await handleClickExtensionStatusBarItem(item.command);
2197
+ await handleClickExtensionStatusBarItem(item.command, applicationId);
1926
2198
  }
1927
2199
  // TODO
1928
2200
  // sendExtensionWorker([/* statusBarItemHandleClick */ 7657, /* name */ name])
@@ -1946,9 +2218,9 @@ const show2 = async (uid, menuId, x, y, args) => {
1946
2218
  await invoke$1('Menu.show2', uid, menuId, x, y, args);
1947
2219
  };
1948
2220
 
1949
- const getStatusBarItemContextMenuItems = async (extensionId, providerId) => {
2221
+ const getStatusBarItemContextMenuItems = async (extensionId, providerId, applicationId) => {
1950
2222
  try {
1951
- return await invoke$5('Extensions.getStatusBarItemContextMenuItems', extensionId, providerId);
2223
+ return await invokeExtensionCommand(applicationId, 'Extensions.getStatusBarItemContextMenuItems', extensionId, providerId);
1952
2224
  } catch {
1953
2225
  return [];
1954
2226
  }
@@ -1958,7 +2230,7 @@ const StatusBar = 31;
1958
2230
 
1959
2231
  const handleContextMenu = async (state, button, x, y, targetName = '') => {
1960
2232
  const item = [...state.statusBarItemsLeft, ...state.statusBarItemsRight].find(statusBarItem => statusBarItem.name === targetName);
1961
- const contextMenuItems = item?.extensionId && item.providerId ? await getStatusBarItemContextMenuItems(item.extensionId, item.providerId) : [];
2233
+ const contextMenuItems = item?.extensionId && item.providerId ? await getStatusBarItemContextMenuItems(item.extensionId, item.providerId, state.applicationId) : [];
1962
2234
  await show2(state.uid, StatusBar, x, y, {
1963
2235
  contextMenuItems,
1964
2236
  menuId: StatusBar
@@ -2190,7 +2462,25 @@ const handleEditorStatusChanged = (state, editorStatus, previous = state) => {
2190
2462
  };
2191
2463
 
2192
2464
  const renderIncremental = (oldState, newState) => {
2193
- return renderItems(oldState, newState);
2465
+ if (oldState.initial) {
2466
+ return renderItems(oldState, newState);
2467
+ }
2468
+ const oldDom = getStatusBarVirtualDom(oldState.visibleStatusBarItemsLeft, oldState.visibleStatusBarItemsRight);
2469
+ const newDom = getStatusBarVirtualDom(newState.visibleStatusBarItemsLeft, newState.visibleStatusBarItemsRight);
2470
+ // Structural and visibility changes can replace or reorder item groups.
2471
+ // Keep their full-render fallback, including the renderer's ambiguous
2472
+ // solitary Add encoding. Only patch a stable tree of the same items.
2473
+ if (oldDom.length !== newDom.length || oldDom.some((node, index) => {
2474
+ const other = newDom[index];
2475
+ return node.type !== other.type || node.childCount !== other.childCount || node.className !== other.className || node.name !== other.name;
2476
+ })) {
2477
+ return renderItems(oldState, newState);
2478
+ }
2479
+ const patches = diffTree(oldDom, newDom);
2480
+ if (patches.length === 0) {
2481
+ return [];
2482
+ }
2483
+ return [SetPatches, newState.uid, patches];
2194
2484
  };
2195
2485
 
2196
2486
  const getRenderer = diffType => {
@@ -2333,11 +2623,17 @@ const render2 = async (uid, _diffResult) => {
2333
2623
  }
2334
2624
  newState = latestState;
2335
2625
  }
2336
- const diffResult = [...new Set([..._diffResult, ...diff(current.oldState, newState)])];
2626
+ const changed = [...new Set([..._diffResult, ...diff(current.oldState, newState)])];
2627
+ // A full replacement already includes every change; do not patch its new tree
2628
+ // using paths calculated against the old tree.
2629
+ const diffResult = changed.includes(RenderItems) ? changed.filter(type => type !== RenderIncremental) : changed;
2337
2630
  const {
2338
2631
  oldState
2339
2632
  } = current;
2340
2633
  const commands = applyRender(oldState, newState, diffResult);
2634
+ // Advance synchronously: subsequent out-of-band updates must diff against
2635
+ // the DOM commands just generated, including updates that revert a value.
2636
+ set$9(uid, newState, newState);
2341
2637
  if (!isConnected()) {
2342
2638
  return commands;
2343
2639
  }
@@ -2371,7 +2667,7 @@ const handleEditorStatusChangedAll = async update => {
2371
2667
  };
2372
2668
  const editorStatus = applyUpdate(update);
2373
2669
  const changedUids = [];
2374
- for (const uid of getKeys()) {
2670
+ for (const uid of getKeys$1()) {
2375
2671
  const {
2376
2672
  newState,
2377
2673
  oldState
@@ -2415,7 +2711,7 @@ const handleEditorStatusVisibilityChangedAll = async visible => {
2415
2711
  }
2416
2712
  setVisible(visible);
2417
2713
  const changedUids = [];
2418
- for (const uid of getKeys()) {
2714
+ for (const uid of getKeys$1()) {
2419
2715
  const {
2420
2716
  newState,
2421
2717
  oldState
@@ -2510,9 +2806,9 @@ const getBuiltinStatusBarItems = async (errorCount, warningCount, {
2510
2806
  return [...getEditorStatusBarItems(editorStatus), ...getNotificationsStatusBarItem(notificationsEnabled, notificationCount), ...getProblemsStatusBarItem(errorCount, warningCount, problemsEnabled)];
2511
2807
  };
2512
2808
 
2513
- const getExtensionStatusBarItems = async (assetDir, platform) => {
2514
- await invoke$5('Extensions.activateByEvent', 'onStatusBarItem', assetDir, platform);
2515
- return invoke$5('Extensions.getStatusBarItems');
2809
+ const getExtensionStatusBarItems = async (assetDir, platform, applicationId) => {
2810
+ await invokeExtensionCommand(applicationId, 'Extensions.activateByEvent', 'onStatusBarItem', assetDir, platform);
2811
+ return invokeExtensionCommand(applicationId, 'Extensions.getStatusBarItems');
2516
2812
  };
2517
2813
 
2518
2814
  const toStatusBarItem = uiStatusBarItem => {
@@ -2596,6 +2892,7 @@ const getNotificationCount = async () => {
2596
2892
  }
2597
2893
  };
2598
2894
  const getStatusBarItems = async ({
2895
+ applicationId,
2599
2896
  assetDir,
2600
2897
  builtinNotificationsEnabled = true,
2601
2898
  builtinProblemsEnabled = true,
@@ -2608,7 +2905,7 @@ const getStatusBarItems = async ({
2608
2905
  if (!showItems) {
2609
2906
  return [];
2610
2907
  }
2611
- const extensionStatusBarItems = await getExtensionStatusBarItems(assetDir, platform);
2908
+ const extensionStatusBarItems = await getExtensionStatusBarItems(assetDir, platform, applicationId);
2612
2909
  const notificationCount = await getNotificationCount();
2613
2910
  const uiStatusBarItems = toUiStatusBarItems(extensionStatusBarItems);
2614
2911
  const extraItems = await getBuiltinStatusBarItems(errorCount, warningCount, {
@@ -2623,6 +2920,7 @@ const getStatusBarItems = async ({
2623
2920
  const refreshVersions = Object.create(null);
2624
2921
  const handleExtensionsChanged = async state => {
2625
2922
  const {
2923
+ applicationId,
2626
2924
  assetDir,
2627
2925
  errorCount,
2628
2926
  platform,
@@ -2634,6 +2932,7 @@ const handleExtensionsChanged = async state => {
2634
2932
  refreshVersions[uid] = refreshVersion;
2635
2933
  // TODO requery status bar items
2636
2934
  const statusBarItems = await getStatusBarItems({
2935
+ applicationId,
2637
2936
  assetDir,
2638
2937
  builtinNotificationsEnabled: false,
2639
2938
  builtinProblemsEnabled: false,
@@ -2657,7 +2956,7 @@ const handleItemsChanged = async state => {
2657
2956
  };
2658
2957
 
2659
2958
  const handleExtensionManagementChange = async () => {
2660
- for (const uid of getKeys()) {
2959
+ for (const uid of getKeys$1()) {
2661
2960
  const {
2662
2961
  newState,
2663
2962
  oldState
@@ -2705,7 +3004,7 @@ const set = count => {
2705
3004
 
2706
3005
  const handleNotificationCountChangedAll = async count => {
2707
3006
  set(count);
2708
- for (const uid of getKeys()) {
3007
+ for (const uid of getKeys$1()) {
2709
3008
  const {
2710
3009
  newState,
2711
3010
  oldState
@@ -2855,6 +3154,7 @@ const loadStatusBarPreferences = async () => {
2855
3154
 
2856
3155
  const loadContent = async state => {
2857
3156
  const {
3157
+ applicationId,
2858
3158
  assetDir,
2859
3159
  errorCount,
2860
3160
  platform,
@@ -2867,6 +3167,7 @@ const loadContent = async state => {
2867
3167
  itemsVisible
2868
3168
  } = await loadStatusBarPreferences();
2869
3169
  const statusBarItems = await getStatusBarItems({
3170
+ applicationId,
2870
3171
  assetDir,
2871
3172
  builtinNotificationsEnabled: builtinNotificationsEnabled,
2872
3173
  builtinProblemsEnabled: builtinProblemsEnabled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/status-bar-worker",
3
- "version": "3.32.1",
3
+ "version": "3.32.3",
4
4
  "description": "Status Bar Worker",
5
5
  "repository": {
6
6
  "type": "git",