@lvce-editor/api 8.39.0 → 8.41.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.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/parts/CommandMap/CommandMap.d.ts +1 -0
- package/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.d.ts +1 -0
- package/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.js +2 -1
- package/dist/parts/ExtensionApiWorkerCommandMap/ExtensionApiWorkerCommandMap.d.ts +1 -0
- package/dist/parts/RegisteredSourceControlProvider/RegisteredSourceControlProvider.d.ts +1 -0
- package/dist/parts/SourceControl/SourceControl.d.ts +1 -1
- package/dist/parts/SourceControl/SourceControl.js +1 -1
- package/dist/parts/SourceControlProvider/SourceControlProvider.d.ts +1 -0
- package/dist/parts/SourceControlProviderRegistry/SourceControlProviderRegistry.d.ts +1 -0
- package/dist/parts/SourceControlProviderRegistry/SourceControlProviderRegistry.js +12 -0
- package/dist/parts/View/View.d.ts +4 -2
- package/dist/parts/ViewRegistry/ViewRegistry.d.ts +1 -1
- package/dist/parts/ViewRegistry/ViewRegistry.js +89 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,11 +8,11 @@ export { executeDiagnosticProvider, getDiagnosticProviderRegistrySnapshot, regis
|
|
|
8
8
|
export { executeFormattingProvider, getFormattingProviderRegistrySnapshot, registerFormattingProvider, resetFormattingProviderRegistry, } from './parts/Formatting/Formatting.ts';
|
|
9
9
|
export { exists, mkdir, readDirWithFileTypes, readFile, remove, writeFile } from './parts/FileSystem/FileSystem.ts';
|
|
10
10
|
export { executeHoverProvider, getHoverProviderRegistrySnapshot, registerHoverProvider, resetHoverProviderRegistry } from './parts/Hover/Hover.ts';
|
|
11
|
-
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from './parts/SourceControl/SourceControl.ts';
|
|
11
|
+
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from './parts/SourceControl/SourceControl.ts';
|
|
12
12
|
export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from './parts/ViewRegistry/ViewRegistry.ts';
|
|
13
13
|
export { createOutputChannel, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry } from './parts/OutputChannel/OutputChannel.ts';
|
|
14
14
|
export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from './parts/StatusBar/StatusBar.ts';
|
|
15
|
-
export type { RegisteredView, View, ViewAction, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, VirtualDomViewInstance, } from './parts/View/View.ts';
|
|
15
|
+
export type { RegisteredView, View, ViewAction, ViewCommand, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, VirtualDomViewInstance, } from './parts/View/View.ts';
|
|
16
16
|
export { handleExtensionManagementMessagePort } from './parts/HandleExtensionManagementMessagePort/HandleExtensionManagementMessagePort.ts';
|
|
17
17
|
export type { Command } from './parts/Command/Command.ts';
|
|
18
18
|
export type { CommandCallback } from './parts/CommandCallback/CommandCallback.ts';
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export { executeDiagnosticProvider, getDiagnosticProviderRegistrySnapshot, regis
|
|
|
8
8
|
export { executeFormattingProvider, getFormattingProviderRegistrySnapshot, registerFormattingProvider, resetFormattingProviderRegistry, } from "./parts/Formatting/Formatting.js";
|
|
9
9
|
export { exists, mkdir, readDirWithFileTypes, readFile, remove, writeFile } from "./parts/FileSystem/FileSystem.js";
|
|
10
10
|
export { executeHoverProvider, getHoverProviderRegistrySnapshot, registerHoverProvider, resetHoverProviderRegistry } from "./parts/Hover/Hover.js";
|
|
11
|
-
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from "./parts/SourceControl/SourceControl.js";
|
|
11
|
+
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, registerSourceControlProvider, resetSourceControlProviderRegistry, } from "./parts/SourceControl/SourceControl.js";
|
|
12
12
|
export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from "./parts/ViewRegistry/ViewRegistry.js";
|
|
13
13
|
export { createOutputChannel, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry } from "./parts/OutputChannel/OutputChannel.js";
|
|
14
14
|
export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from "./parts/StatusBar/StatusBar.js";
|
|
@@ -13,6 +13,7 @@ export declare const commandMap: {
|
|
|
13
13
|
'ExtensionApi.executeSourceControlAdd': (id: string, path: string) => Promise<unknown>;
|
|
14
14
|
'ExtensionApi.executeSourceControlDiscard': (id: string, path: string) => Promise<unknown>;
|
|
15
15
|
'ExtensionApi.executeSourceControlGenerateCommitMessage': (id: string) => Promise<unknown>;
|
|
16
|
+
'ExtensionApi.executeSourceControlGetBadgeCount': (id: string) => Promise<number>;
|
|
16
17
|
'ExtensionApi.executeSourceControlGetChangedFiles': (id: string) => Promise<readonly unknown[]>;
|
|
17
18
|
'ExtensionApi.executeSourceControlGetFeatures': (id: string) => Promise<unknown>;
|
|
18
19
|
'ExtensionApi.executeSourceControlGetFileBefore': (id: string, uri: string) => Promise<unknown>;
|
|
@@ -12,6 +12,7 @@ export declare const commandMap: {
|
|
|
12
12
|
'ExtensionApi.executeSourceControlAdd': (id: string, path: string) => Promise<unknown>;
|
|
13
13
|
'ExtensionApi.executeSourceControlDiscard': (id: string, path: string) => Promise<unknown>;
|
|
14
14
|
'ExtensionApi.executeSourceControlGenerateCommitMessage': (id: string) => Promise<unknown>;
|
|
15
|
+
'ExtensionApi.executeSourceControlGetBadgeCount': (id: string) => Promise<number>;
|
|
15
16
|
'ExtensionApi.executeSourceControlGetChangedFiles': (id: string) => Promise<readonly unknown[]>;
|
|
16
17
|
'ExtensionApi.executeSourceControlGetFeatures': (id: string) => Promise<unknown>;
|
|
17
18
|
'ExtensionApi.executeSourceControlGetFileBefore': (id: string, uri: string) => Promise<unknown>;
|
|
@@ -5,7 +5,7 @@ import { executeFormattingProvider, getFormattingProviderRegistrySnapshot } from
|
|
|
5
5
|
import { getStatusBarItems } from "../GetStatusBarItems/GetStatusBarItems.js";
|
|
6
6
|
import { executeHoverProvider, getHoverProviderRegistrySnapshot } from "../Hover/Hover.js";
|
|
7
7
|
import { getOutputChannelRegistrySnapshot } from "../OutputChannel/OutputChannel.js";
|
|
8
|
-
import { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, } from "../SourceControl/SourceControl.js";
|
|
8
|
+
import { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, } from "../SourceControl/SourceControl.js";
|
|
9
9
|
import { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewActions, getViewMenuEntries, getViewRegistrySnapshot, renderViewInstance, saveViewInstanceState, } from "../ViewRegistry/ViewRegistry.js";
|
|
10
10
|
export const commandMap = {
|
|
11
11
|
'ExtensionApi.createViewInstance': createViewInstance,
|
|
@@ -21,6 +21,7 @@ export const commandMap = {
|
|
|
21
21
|
'ExtensionApi.executeSourceControlAdd': executeSourceControlAdd,
|
|
22
22
|
'ExtensionApi.executeSourceControlDiscard': executeSourceControlDiscard,
|
|
23
23
|
'ExtensionApi.executeSourceControlGenerateCommitMessage': executeSourceControlGenerateCommitMessage,
|
|
24
|
+
'ExtensionApi.executeSourceControlGetBadgeCount': executeSourceControlGetBadgeCount,
|
|
24
25
|
'ExtensionApi.executeSourceControlGetChangedFiles': executeSourceControlGetChangedFiles,
|
|
25
26
|
'ExtensionApi.executeSourceControlGetFeatures': executeSourceControlGetFeatures,
|
|
26
27
|
'ExtensionApi.executeSourceControlGetFileBefore': executeSourceControlGetFileBefore,
|
|
@@ -14,6 +14,7 @@ export declare const commandMap: {
|
|
|
14
14
|
'ExtensionApi.executeSourceControlAdd': (id: string, path: string) => Promise<unknown>;
|
|
15
15
|
'ExtensionApi.executeSourceControlDiscard': (id: string, path: string) => Promise<unknown>;
|
|
16
16
|
'ExtensionApi.executeSourceControlGenerateCommitMessage': (id: string) => Promise<unknown>;
|
|
17
|
+
'ExtensionApi.executeSourceControlGetBadgeCount': (id: string) => Promise<number>;
|
|
17
18
|
'ExtensionApi.executeSourceControlGetChangedFiles': (id: string) => Promise<readonly unknown[]>;
|
|
18
19
|
'ExtensionApi.executeSourceControlGetFeatures': (id: string) => Promise<unknown>;
|
|
19
20
|
'ExtensionApi.executeSourceControlGetFileBefore': (id: string, uri: string) => Promise<unknown>;
|
|
@@ -3,6 +3,7 @@ export interface RegisteredSourceControlProvider {
|
|
|
3
3
|
readonly add?: (path: string) => unknown | Promise<unknown>;
|
|
4
4
|
readonly discard?: (path: string) => unknown | Promise<unknown>;
|
|
5
5
|
readonly generateCommitMessage?: () => unknown | Promise<unknown>;
|
|
6
|
+
readonly getBadgeCount?: () => number | Promise<number>;
|
|
6
7
|
readonly getChangedFiles: () => readonly unknown[] | Promise<readonly unknown[]>;
|
|
7
8
|
readonly getFeatures?: () => unknown | Promise<unknown>;
|
|
8
9
|
readonly getFileBefore?: (uri: string) => unknown | Promise<unknown>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, registerSourceControlProvider, resetSourceControlProviderRegistry, } from '../SourceControlProviderRegistry/SourceControlProviderRegistry.ts';
|
|
1
|
+
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, registerSourceControlProvider, resetSourceControlProviderRegistry, } from '../SourceControlProviderRegistry/SourceControlProviderRegistry.ts';
|
|
2
2
|
export type { RegisteredSourceControlProvider } from '../RegisteredSourceControlProvider/RegisteredSourceControlProvider.ts';
|
|
3
3
|
export type { SourceControlProvider } from '../SourceControlProvider/SourceControlProvider.ts';
|
|
4
4
|
export type { SourceControlProviderRegistrySnapshot } from '../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, registerSourceControlProvider, resetSourceControlProviderRegistry, } from "../SourceControlProviderRegistry/SourceControlProviderRegistry.js";
|
|
1
|
+
export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetBadgeCount, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, registerSourceControlProvider, resetSourceControlProviderRegistry, } from "../SourceControlProviderRegistry/SourceControlProviderRegistry.js";
|
|
@@ -3,6 +3,7 @@ export interface SourceControlProvider {
|
|
|
3
3
|
readonly add?: (path: string) => unknown | Promise<unknown>;
|
|
4
4
|
readonly discard?: (path: string) => unknown | Promise<unknown>;
|
|
5
5
|
readonly generateCommitMessage?: () => unknown | Promise<unknown>;
|
|
6
|
+
readonly getBadgeCount?: () => number | Promise<number>;
|
|
6
7
|
readonly getChangedFiles: () => readonly unknown[] | Promise<readonly unknown[]>;
|
|
7
8
|
readonly getFeatures?: () => unknown | Promise<unknown>;
|
|
8
9
|
readonly getFileBefore?: (uri: string) => unknown | Promise<unknown>;
|
|
@@ -7,6 +7,7 @@ export declare const executeSourceControlAdd: (id: string, path: string) => Prom
|
|
|
7
7
|
export declare const executeSourceControlDiscard: (id: string, path: string) => Promise<unknown>;
|
|
8
8
|
export declare const executeSourceControlGenerateCommitMessage: (id: string) => Promise<unknown>;
|
|
9
9
|
export declare const executeSourceControlGetChangedFiles: (id: string) => Promise<readonly unknown[]>;
|
|
10
|
+
export declare const executeSourceControlGetBadgeCount: (id: string) => Promise<number>;
|
|
10
11
|
export declare const executeSourceControlGetFeatures: (id: string) => Promise<unknown>;
|
|
11
12
|
export declare const executeSourceControlGetFileBefore: (id: string, uri: string) => Promise<unknown>;
|
|
12
13
|
export declare const executeSourceControlGetFileDecorations: (id: string, uris: readonly string[]) => Promise<unknown>;
|
|
@@ -5,6 +5,7 @@ const optionalMethods = [
|
|
|
5
5
|
'add',
|
|
6
6
|
'discard',
|
|
7
7
|
'generateCommitMessage',
|
|
8
|
+
'getBadgeCount',
|
|
8
9
|
'getFeatures',
|
|
9
10
|
'getFileBefore',
|
|
10
11
|
'getFileDecorations',
|
|
@@ -59,6 +60,9 @@ const mapSourceControlProvider = (provider) => {
|
|
|
59
60
|
if (provider.generateCommitMessage) {
|
|
60
61
|
registeredProvider.generateCommitMessage = () => provider.generateCommitMessage();
|
|
61
62
|
}
|
|
63
|
+
if (provider.getBadgeCount) {
|
|
64
|
+
registeredProvider.getBadgeCount = () => provider.getBadgeCount();
|
|
65
|
+
}
|
|
62
66
|
if (provider.getFeatures) {
|
|
63
67
|
registeredProvider.getFeatures = () => provider.getFeatures();
|
|
64
68
|
}
|
|
@@ -100,6 +104,14 @@ export const executeSourceControlGenerateCommitMessage = async (id) => {
|
|
|
100
104
|
export const executeSourceControlGetChangedFiles = async (id) => {
|
|
101
105
|
return getProvider(id).getChangedFiles();
|
|
102
106
|
};
|
|
107
|
+
export const executeSourceControlGetBadgeCount = async (id) => {
|
|
108
|
+
const provider = getProvider(id);
|
|
109
|
+
if (provider.getBadgeCount) {
|
|
110
|
+
return provider.getBadgeCount();
|
|
111
|
+
}
|
|
112
|
+
const files = await provider.getChangedFiles();
|
|
113
|
+
return files.length;
|
|
114
|
+
};
|
|
103
115
|
export const executeSourceControlGetFeatures = async (id) => {
|
|
104
116
|
return getProvider(id).getFeatures?.() ?? {};
|
|
105
117
|
};
|
|
@@ -44,8 +44,10 @@ export interface VirtualDomViewInstance {
|
|
|
44
44
|
readonly renderFocus?: (oldContext: Readonly<Record<string, boolean>>, newContext: Readonly<Record<string, boolean>>) => string | Promise<string>;
|
|
45
45
|
readonly saveState?: () => unknown;
|
|
46
46
|
}
|
|
47
|
-
export
|
|
48
|
-
|
|
47
|
+
export type ViewCommand<State = VirtualDomViewInstance, Args extends readonly any[] = readonly any[]> = (state: State, ...args: Args) => State | Promise<State>;
|
|
48
|
+
export interface View<State = unknown> {
|
|
49
|
+
readonly commands?: Readonly<Record<string, ViewCommand<State>>>;
|
|
50
|
+
readonly create: (context?: ViewContext) => State | Promise<State>;
|
|
49
51
|
readonly displayName?: string;
|
|
50
52
|
readonly eventListeners?: readonly DomEventListener[];
|
|
51
53
|
readonly icon?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Disposable } from '../Disposable/Disposable.ts';
|
|
2
2
|
import type { MenuEntry, View, ViewAction, ViewContext, ViewEvent, ViewRegistrySnapshot, ViewRenderResult } from '../View/View.ts';
|
|
3
|
-
export declare const registerView: (view: View) => Disposable;
|
|
3
|
+
export declare const registerView: <State>(view: View<State>) => Disposable;
|
|
4
4
|
export declare const executeViewProvider: (id: string) => unknown;
|
|
5
5
|
export declare const createViewInstance: (viewId: string, uid: number, context?: ViewContext) => Promise<ViewRenderResult>;
|
|
6
6
|
export declare const dispatchViewEvent: (uid: number, event: ViewEvent) => Promise<ViewRenderResult>;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { ExtensionManagementWorker } from '@lvce-editor/rpc-registry';
|
|
2
2
|
import { diffTree } from '@lvce-editor/virtual-dom-worker';
|
|
3
|
+
import { registerCommand } from "../CommandRegistry/CommandRegistry.js";
|
|
3
4
|
import { ExtensionApiError } from "../ExtensionApiError/ExtensionApiError.js";
|
|
4
5
|
const views = Object.create(null);
|
|
5
6
|
const instances = Object.create(null);
|
|
7
|
+
const instanceUidsByView = Object.create(null);
|
|
6
8
|
const renderedDoms = Object.create(null);
|
|
7
9
|
const contexts = Object.create(null);
|
|
8
10
|
const contextViewIds = Object.create(null);
|
|
11
|
+
const viewCommandDisposables = Object.create(null);
|
|
9
12
|
const assertBoolean = (value, message) => {
|
|
10
13
|
if (value !== undefined && typeof value !== 'boolean') {
|
|
11
14
|
throw new ExtensionApiError(message);
|
|
@@ -48,6 +51,23 @@ const assertEventListeners = (view) => {
|
|
|
48
51
|
assertEventListener(view.id, listener, index);
|
|
49
52
|
}
|
|
50
53
|
};
|
|
54
|
+
const assertCommands = (view) => {
|
|
55
|
+
if (view.commands === undefined) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (view.kind !== 'virtualDom') {
|
|
59
|
+
throw new ExtensionApiError(`view ${view.id} commands require virtualDom kind`);
|
|
60
|
+
}
|
|
61
|
+
if (!view.commands || typeof view.commands !== 'object' || Array.isArray(view.commands)) {
|
|
62
|
+
throw new ExtensionApiError(`view ${view.id} commands must be an object`);
|
|
63
|
+
}
|
|
64
|
+
for (const [id, command] of Object.entries(view.commands)) {
|
|
65
|
+
assertString(id, `view ${view.id} command is missing id`);
|
|
66
|
+
if (typeof command !== 'function') {
|
|
67
|
+
throw new ExtensionApiError(`view ${view.id} command ${id} must be a function`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
51
71
|
const assertView = (view) => {
|
|
52
72
|
if (!view) {
|
|
53
73
|
throw new ExtensionApiError('view is not defined');
|
|
@@ -61,6 +81,7 @@ const assertView = (view) => {
|
|
|
61
81
|
if (view.id in views) {
|
|
62
82
|
throw new ExtensionApiError(`view ${view.id} is already registered`);
|
|
63
83
|
}
|
|
84
|
+
assertCommands(view);
|
|
64
85
|
assertEventListeners(view);
|
|
65
86
|
};
|
|
66
87
|
const toRegisteredView = (view) => {
|
|
@@ -81,12 +102,61 @@ const toRegisteredView = (view) => {
|
|
|
81
102
|
}
|
|
82
103
|
return registeredView;
|
|
83
104
|
};
|
|
105
|
+
const getActiveViewInstance = (viewId) => {
|
|
106
|
+
const instanceUids = instanceUidsByView[viewId];
|
|
107
|
+
if (!instanceUids) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const uid = [...instanceUids].at(-1);
|
|
111
|
+
if (uid === undefined) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return [uid, instances[uid]];
|
|
115
|
+
};
|
|
116
|
+
const executeViewCommand = async (view, commandId, args) => {
|
|
117
|
+
const activeInstance = getActiveViewInstance(view.id);
|
|
118
|
+
if (!activeInstance) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const [uid, instance] = activeInstance;
|
|
122
|
+
const command = view.commands[commandId];
|
|
123
|
+
const newInstance = await command(instance, ...args);
|
|
124
|
+
assertVirtualDomViewInstance(view.id, newInstance);
|
|
125
|
+
instances[uid] = newInstance;
|
|
126
|
+
await ExtensionManagementWorker.invoke('Extensions.requestViewRerender', uid);
|
|
127
|
+
};
|
|
128
|
+
const registerViewCommands = (view) => {
|
|
129
|
+
const disposables = [];
|
|
130
|
+
try {
|
|
131
|
+
for (const id of Object.keys(view.commands || {})) {
|
|
132
|
+
disposables.push(registerCommand({
|
|
133
|
+
execute(...args) {
|
|
134
|
+
return executeViewCommand(view, id, args);
|
|
135
|
+
},
|
|
136
|
+
id,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
for (const disposable of disposables) {
|
|
142
|
+
disposable.dispose();
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
return disposables;
|
|
147
|
+
};
|
|
84
148
|
export const registerView = (view) => {
|
|
85
149
|
assertView(view);
|
|
150
|
+
const commandDisposables = registerViewCommands(view);
|
|
86
151
|
views[view.id] = view;
|
|
152
|
+
viewCommandDisposables[view.id] = commandDisposables;
|
|
87
153
|
return {
|
|
88
154
|
dispose() {
|
|
155
|
+
for (const disposable of commandDisposables) {
|
|
156
|
+
disposable.dispose();
|
|
157
|
+
}
|
|
89
158
|
delete views[view.id];
|
|
159
|
+
delete viewCommandDisposables[view.id];
|
|
90
160
|
},
|
|
91
161
|
};
|
|
92
162
|
};
|
|
@@ -284,6 +354,9 @@ export const createViewInstance = async (viewId, uid, context) => {
|
|
|
284
354
|
});
|
|
285
355
|
assertVirtualDomViewInstance(viewId, instance);
|
|
286
356
|
instances[uid] = instance;
|
|
357
|
+
const instanceUids = instanceUidsByView[viewId] || new Set();
|
|
358
|
+
instanceUids.add(uid);
|
|
359
|
+
instanceUidsByView[viewId] = instanceUids;
|
|
287
360
|
contextViewIds[uid] = viewId;
|
|
288
361
|
const dom = await renderDom(instance);
|
|
289
362
|
renderedDoms[uid] = dom;
|
|
@@ -296,6 +369,9 @@ export const createViewInstance = async (viewId, uid, context) => {
|
|
|
296
369
|
};
|
|
297
370
|
export const dispatchViewEvent = async (uid, event) => {
|
|
298
371
|
const instance = getVirtualDomInstance(uid);
|
|
372
|
+
const instanceUids = instanceUidsByView[contextViewIds[uid]];
|
|
373
|
+
instanceUids.delete(uid);
|
|
374
|
+
instanceUids.add(uid);
|
|
299
375
|
if (typeof instance.handleEvent === 'function') {
|
|
300
376
|
await instance.handleEvent(event);
|
|
301
377
|
}
|
|
@@ -315,6 +391,12 @@ export const disposeViewInstance = async (uid) => {
|
|
|
315
391
|
await instance.dispose();
|
|
316
392
|
}
|
|
317
393
|
await maybeClearContext(uid, contextViewIds[uid]);
|
|
394
|
+
const viewId = contextViewIds[uid];
|
|
395
|
+
const instanceUids = instanceUidsByView[viewId];
|
|
396
|
+
instanceUids?.delete(uid);
|
|
397
|
+
if (instanceUids?.size === 0) {
|
|
398
|
+
delete instanceUidsByView[viewId];
|
|
399
|
+
}
|
|
318
400
|
delete instances[uid];
|
|
319
401
|
delete renderedDoms[uid];
|
|
320
402
|
delete contextViewIds[uid];
|
|
@@ -348,7 +430,11 @@ export const getViewRegistrySnapshot = () => {
|
|
|
348
430
|
};
|
|
349
431
|
export const resetViewRegistry = () => {
|
|
350
432
|
for (const id of Object.keys(views)) {
|
|
433
|
+
for (const disposable of viewCommandDisposables[id] || []) {
|
|
434
|
+
disposable.dispose();
|
|
435
|
+
}
|
|
351
436
|
delete views[id];
|
|
437
|
+
delete viewCommandDisposables[id];
|
|
352
438
|
}
|
|
353
439
|
for (const uid of Object.keys(instances)) {
|
|
354
440
|
delete instances[Number(uid)];
|
|
@@ -362,4 +448,7 @@ export const resetViewRegistry = () => {
|
|
|
362
448
|
for (const uid of Object.keys(contextViewIds)) {
|
|
363
449
|
delete contextViewIds[Number(uid)];
|
|
364
450
|
}
|
|
451
|
+
for (const viewId of Object.keys(instanceUidsByView)) {
|
|
452
|
+
delete instanceUidsByView[viewId];
|
|
453
|
+
}
|
|
365
454
|
};
|