@lvce-editor/api 9.16.0 → 9.16.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.
package/dist/index.d.ts CHANGED
@@ -25,7 +25,7 @@ export { getLanguageServerRegistrySnapshot, registerLanguageServer, resetLanguag
25
25
  export { registerBraceCompletionProvider, registerClosingTagProvider, registerCodeActionsProvider, registerCommentProvider, registerDefinitionProvider, registerImplementationProvider, registerReferenceProvider, registerRenameProvider, registerSelectionProvider, registerTabCompletionProvider, registerTypeDefinitionProvider, resetLanguageProviderRegistry, } from './parts/LanguageProvider/LanguageProvider.ts';
26
26
  export type { LanguageProvider } from './parts/LanguageProvider/LanguageProvider.ts';
27
27
  export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileBeforeUri, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from './parts/SourceControl/SourceControl.ts';
28
- export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from './parts/ViewRegistry/ViewRegistry.ts';
28
+ export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, setViewInstanceActive, } from './parts/ViewRegistry/ViewRegistry.ts';
29
29
  export { createOutputChannel, getOutputChannelLogs, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry, } from './parts/OutputChannel/OutputChannel.ts';
30
30
  export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from './parts/StatusBar/StatusBar.ts';
31
31
  export type { RegisteredView, View, ViewAction, ViewCommand, ViewContext, ViewEvent, ViewKind, ViewPreferredLocation, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, ViewScrollPosition, ViewSelection, VirtualDomViewInstance, } from './parts/View/View.ts';
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ export { openDebugConsole, openOutputView, openProblemsView, } from "./parts/Pan
24
24
  export { getLanguageServerRegistrySnapshot, registerLanguageServer, resetLanguageServerRegistry } from "./parts/LanguageServer/LanguageServer.js";
25
25
  export { registerBraceCompletionProvider, registerClosingTagProvider, registerCodeActionsProvider, registerCommentProvider, registerDefinitionProvider, registerImplementationProvider, registerReferenceProvider, registerRenameProvider, registerSelectionProvider, registerTabCompletionProvider, registerTypeDefinitionProvider, resetLanguageProviderRegistry, } from "./parts/LanguageProvider/LanguageProvider.js";
26
26
  export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileBeforeUri, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from "./parts/SourceControl/SourceControl.js";
27
- export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from "./parts/ViewRegistry/ViewRegistry.js";
27
+ export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, setViewInstanceActive, } from "./parts/ViewRegistry/ViewRegistry.js";
28
28
  export { createOutputChannel, getOutputChannelLogs, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry, } from "./parts/OutputChannel/OutputChannel.js";
29
29
  export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from "./parts/StatusBar/StatusBar.js";
30
30
  export { handleExtensionManagementMessagePort } from "./parts/HandleExtensionManagementMessagePort/HandleExtensionManagementMessagePort.js";
@@ -6,6 +6,7 @@ export declare const executeViewProvider: (id: string) => unknown;
6
6
  export declare const createViewInstance: (viewId: string, uid: number, context?: ViewContext) => Promise<ViewRenderResult>;
7
7
  export declare const dispatchViewEvent: (uid: number, event: ViewEvent) => Promise<ViewRenderResult>;
8
8
  export declare const renderViewInstance: (uid: number) => Promise<ViewRenderResult>;
9
+ export declare const setViewInstanceActive: (uid: number, active: boolean) => Promise<void>;
9
10
  export declare const disposeViewInstance: (uid: number) => Promise<void>;
10
11
  export declare const saveViewInstanceState: (uid: number) => Promise<unknown>;
11
12
  export declare const getViewMenuEntries: (uid: number, menuId: string) => Promise<readonly MenuEntry[]>;
@@ -499,6 +499,13 @@ export const renderViewInstance = async (uid) => {
499
499
  const contextChange = await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
500
500
  return withRenderMetadata(uid, contextViewIds[uid], result, instance, contextChange);
501
501
  };
502
+ export const setViewInstanceActive = async (uid, active) => {
503
+ getVirtualDomInstance(uid);
504
+ if (typeof active !== 'boolean') {
505
+ throw new ExtensionApiError('view instance active state must be a boolean');
506
+ }
507
+ await ViewStatusBarItems.setViewInstanceActive(uid, active);
508
+ };
502
509
  export const disposeViewInstance = async (uid) => {
503
510
  const instance = instances[uid];
504
511
  const viewId = contextViewIds[uid];
@@ -573,6 +580,7 @@ const commandMap = {
573
580
  'ExtensionApi.getViewRegistrySnapshot': getViewRegistrySnapshot,
574
581
  'ExtensionApi.renderViewInstance': renderViewInstance,
575
582
  'ExtensionApi.saveViewInstanceState': saveViewInstanceState,
583
+ 'ExtensionApi.setViewInstanceActive': setViewInstanceActive,
576
584
  };
577
585
  export const resetViewRegistry = () => {
578
586
  ViewStatusBarItems.resetViewStatusBarItems();
@@ -1,4 +1,5 @@
1
1
  import type { VirtualDomViewInstance } from '../View/View.ts';
2
2
  export declare const renderViewStatusBarItems: (uid: number, viewId: string, instance: VirtualDomViewInstance) => Promise<void>;
3
+ export declare const setViewInstanceActive: (uid: number, active: boolean) => Promise<void>;
3
4
  export declare const disposeViewStatusBarItems: (uid: number) => void;
4
5
  export declare const resetViewStatusBarItems: () => void;
@@ -1,7 +1,11 @@
1
1
  import { ExtensionApiError } from "../ExtensionApiError/ExtensionApiError.js";
2
2
  import { registerStatusBarItemProvider } from "../StatusBarItemProviderRegistry/StatusBarItemProviderRegistry.js";
3
- const handlesByUid = Object.create(null);
3
+ const activeUidByViewId = Object.create(null);
4
+ const explicitActiveStateByUid = Object.create(null);
5
+ const handlesByViewId = Object.create(null);
4
6
  const itemsByUid = Object.create(null);
7
+ const renderedUidsByViewId = Object.create(null);
8
+ const viewIdByUid = Object.create(null);
5
9
  const stringProperties = ['ariaLabel', 'icon', 'name', 'onClick', 'text', 'title'];
6
10
  const normalizeStatusBarItem = (item, index) => {
7
11
  if (!item || typeof item !== 'object' || Array.isArray(item)) {
@@ -47,44 +51,122 @@ const areItemsEqual = (oldItems, newItems) => {
47
51
  oldItem.title === newItem.title);
48
52
  });
49
53
  };
50
- const disposeHandles = (uid) => {
51
- for (const handle of handlesByUid[uid] || []) {
54
+ const disposeHandles = (viewId) => {
55
+ for (const handle of handlesByViewId[viewId] || []) {
52
56
  handle.dispose();
53
57
  }
54
- delete handlesByUid[uid];
58
+ delete handlesByViewId[viewId];
55
59
  };
56
- const replaceItems = (uid, viewId, items) => {
57
- disposeHandles(uid);
58
- itemsByUid[uid] = items;
59
- handlesByUid[uid] = items.map((_item, index) => registerStatusBarItemProvider({
60
+ const replaceItems = (viewId, itemCount) => {
61
+ disposeHandles(viewId);
62
+ handlesByViewId[viewId] = Array.from({ length: itemCount }, (_item, index) => registerStatusBarItemProvider({
60
63
  getStatusBarItem() {
61
- return itemsByUid[uid]?.[index];
64
+ return itemsByUid[activeUidByViewId[viewId]]?.[index];
62
65
  },
63
- id: `view:${viewId}:${uid}:${index}`,
66
+ id: `view:${viewId}:${index}`,
64
67
  }));
65
68
  };
69
+ const refreshItems = async (viewId) => {
70
+ await Promise.all((handlesByViewId[viewId] || []).map((handle) => handle.refresh()));
71
+ };
72
+ const setActiveUid = (viewId, uid) => {
73
+ const renderedUids = renderedUidsByViewId[viewId] || [];
74
+ const index = renderedUids.indexOf(uid);
75
+ if (index !== -1) {
76
+ renderedUids.splice(index, 1);
77
+ }
78
+ renderedUids.push(uid);
79
+ renderedUidsByViewId[viewId] = renderedUids;
80
+ activeUidByViewId[viewId] = uid;
81
+ };
66
82
  export const renderViewStatusBarItems = async (uid, viewId, instance) => {
67
83
  if (typeof instance.renderStatusBarItems !== 'function') {
68
84
  return;
69
85
  }
70
86
  const items = normalizeStatusBarItems(await instance.renderStatusBarItems());
71
87
  const oldItems = itemsByUid[uid] || [];
72
- if (areItemsEqual(oldItems, items)) {
88
+ const wasActive = activeUidByViewId[viewId] === uid;
89
+ itemsByUid[uid] = items;
90
+ viewIdByUid[uid] = viewId;
91
+ if (explicitActiveStateByUid[uid] !== undefined && !explicitActiveStateByUid[uid]) {
73
92
  return;
74
93
  }
75
- if ((handlesByUid[uid]?.length || 0) !== items.length) {
76
- replaceItems(uid, viewId, items);
94
+ setActiveUid(viewId, uid);
95
+ if (wasActive && areItemsEqual(oldItems, items)) {
77
96
  return;
78
97
  }
79
- itemsByUid[uid] = items;
80
- await Promise.all((handlesByUid[uid] || []).map((handle) => handle.refresh()));
98
+ if ((handlesByViewId[viewId]?.length || 0) !== items.length) {
99
+ replaceItems(viewId, items.length);
100
+ return;
101
+ }
102
+ await refreshItems(viewId);
103
+ };
104
+ export const setViewInstanceActive = async (uid, active) => {
105
+ const viewId = viewIdByUid[uid];
106
+ if (!viewId) {
107
+ return;
108
+ }
109
+ explicitActiveStateByUid[uid] = active;
110
+ if (!active) {
111
+ if (activeUidByViewId[viewId] !== uid) {
112
+ return;
113
+ }
114
+ disposeHandles(viewId);
115
+ delete activeUidByViewId[viewId];
116
+ return;
117
+ }
118
+ const wasActive = activeUidByViewId[viewId] === uid;
119
+ const items = itemsByUid[uid] || [];
120
+ setActiveUid(viewId, uid);
121
+ if (wasActive && (handlesByViewId[viewId]?.length || 0) === items.length) {
122
+ return;
123
+ }
124
+ if ((handlesByViewId[viewId]?.length || 0) !== items.length) {
125
+ replaceItems(viewId, items.length);
126
+ return;
127
+ }
128
+ await refreshItems(viewId);
81
129
  };
82
130
  export const disposeViewStatusBarItems = (uid) => {
83
- disposeHandles(uid);
131
+ const viewId = viewIdByUid[uid];
132
+ if (!viewId) {
133
+ return;
134
+ }
84
135
  delete itemsByUid[uid];
136
+ delete explicitActiveStateByUid[uid];
137
+ delete viewIdByUid[uid];
138
+ const renderedUids = renderedUidsByViewId[viewId] || [];
139
+ const remainingUids = renderedUids.filter((renderedUid) => renderedUid !== uid);
140
+ if (remainingUids.length === 0) {
141
+ disposeHandles(viewId);
142
+ delete activeUidByViewId[viewId];
143
+ delete renderedUidsByViewId[viewId];
144
+ return;
145
+ }
146
+ renderedUidsByViewId[viewId] = remainingUids;
147
+ if (activeUidByViewId[viewId] !== uid) {
148
+ return;
149
+ }
150
+ const activeUid = remainingUids.at(-1);
151
+ const items = itemsByUid[activeUid] || [];
152
+ activeUidByViewId[viewId] = activeUid;
153
+ if ((handlesByViewId[viewId]?.length || 0) !== items.length) {
154
+ replaceItems(viewId, items.length);
155
+ return;
156
+ }
157
+ void refreshItems(viewId);
85
158
  };
86
159
  export const resetViewStatusBarItems = () => {
160
+ for (const viewId of Object.keys(handlesByViewId)) {
161
+ disposeHandles(viewId);
162
+ }
87
163
  for (const uid of Object.keys(itemsByUid)) {
88
- disposeViewStatusBarItems(Number(uid));
164
+ delete itemsByUid[Number(uid)];
165
+ delete explicitActiveStateByUid[Number(uid)];
166
+ delete viewIdByUid[Number(uid)];
167
+ }
168
+ for (const viewId of Object.keys(activeUidByViewId)) {
169
+ delete activeUidByViewId[viewId];
170
+ delete renderedUidsByViewId[viewId];
89
171
  }
90
172
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/api",
3
- "version": "9.16.0",
3
+ "version": "9.16.2",
4
4
  "description": "Tree-shakeable extension API for Lvce Editor extensions.",
5
5
  "keywords": [
6
6
  "lvce-editor",