@lvce-editor/extension-host-worker 8.34.0 → 8.35.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.
@@ -2393,6 +2393,50 @@ var diffTree = (oldNodes, newNodes) => {
2393
2393
  var views = /* @__PURE__ */ Object.create(null);
2394
2394
  var instances = /* @__PURE__ */ Object.create(null);
2395
2395
  var renderedDoms = /* @__PURE__ */ Object.create(null);
2396
+ var contexts = /* @__PURE__ */ Object.create(null);
2397
+ var contextViewIds = /* @__PURE__ */ Object.create(null);
2398
+ var assertBoolean = (value, message) => {
2399
+ if (value !== void 0 && typeof value !== "boolean") {
2400
+ throw new ExtensionApiError(message);
2401
+ }
2402
+ };
2403
+ var assertNumber = (value, message) => {
2404
+ if (typeof value !== "number") {
2405
+ throw new ExtensionApiError(message);
2406
+ }
2407
+ };
2408
+ var assertString = (value, message) => {
2409
+ if (typeof value !== "string" || value.length === 0) {
2410
+ throw new ExtensionApiError(message);
2411
+ }
2412
+ };
2413
+ var assertEventListener = (viewId, listener, index) => {
2414
+ if (!listener || typeof listener !== "object") {
2415
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} must be an object`);
2416
+ }
2417
+ const eventListener = listener;
2418
+ if (typeof eventListener.name !== "string" && typeof eventListener.name !== "number") {
2419
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} is missing name`);
2420
+ }
2421
+ if (!Array.isArray(eventListener.params) || eventListener.params.some((param) => typeof param !== "string")) {
2422
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} is missing params`);
2423
+ }
2424
+ assertBoolean(eventListener.capture, `view ${viewId} event listener ${index} has invalid capture`);
2425
+ assertBoolean(eventListener.passive, `view ${viewId} event listener ${index} has invalid passive`);
2426
+ assertBoolean(eventListener.preventDefault, `view ${viewId} event listener ${index} has invalid preventDefault`);
2427
+ assertBoolean(eventListener.stopPropagation, `view ${viewId} event listener ${index} has invalid stopPropagation`);
2428
+ };
2429
+ var assertEventListeners = (view) => {
2430
+ if (view.eventListeners === void 0) {
2431
+ return;
2432
+ }
2433
+ if (!Array.isArray(view.eventListeners)) {
2434
+ throw new ExtensionApiError(`view ${view.id} eventListeners must be an array`);
2435
+ }
2436
+ for (const [index, listener] of view.eventListeners.entries()) {
2437
+ assertEventListener(view.id, listener, index);
2438
+ }
2439
+ };
2396
2440
  var assertView = (view) => {
2397
2441
  if (!view) {
2398
2442
  throw new ExtensionApiError("view is not defined");
@@ -2406,11 +2450,13 @@ var assertView = (view) => {
2406
2450
  if (view.id in views) {
2407
2451
  throw new ExtensionApiError(`view ${view.id} is already registered`);
2408
2452
  }
2453
+ assertEventListeners(view);
2409
2454
  };
2410
2455
  var toRegisteredView = (view) => {
2411
2456
  const displayName = view.displayName || view.name || view.title;
2412
2457
  const registeredView = {
2413
2458
  displayName,
2459
+ ...view.eventListeners && { eventListeners: view.eventListeners },
2414
2460
  icon: view.icon,
2415
2461
  id: view.id,
2416
2462
  name: view.name,
@@ -2462,6 +2508,34 @@ var renderDom = async (instance) => {
2462
2508
  }
2463
2509
  return dom;
2464
2510
  };
2511
+ var normalizeMenuEntry = (entry, index) => {
2512
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
2513
+ throw new ExtensionApiError(`menu entry ${index} must be an object`);
2514
+ }
2515
+ const menuEntry = entry;
2516
+ assertString(menuEntry.id, `menu entry ${index} is missing id`);
2517
+ assertString(menuEntry.label, `menu entry ${index} is missing label`);
2518
+ assertString(menuEntry.command, `menu entry ${index} is missing command`);
2519
+ if (menuEntry.flags !== void 0 && typeof menuEntry.flags !== "number") {
2520
+ throw new ExtensionApiError(`menu entry ${index} has invalid flags`);
2521
+ }
2522
+ if (menuEntry.args !== void 0 && !Array.isArray(menuEntry.args)) {
2523
+ throw new ExtensionApiError(`menu entry ${index} has invalid args`);
2524
+ }
2525
+ return {
2526
+ command: menuEntry.command,
2527
+ flags: menuEntry.flags ?? 0,
2528
+ id: menuEntry.id,
2529
+ label: menuEntry.label,
2530
+ ...menuEntry.args && { args: menuEntry.args }
2531
+ };
2532
+ };
2533
+ var normalizeMenuEntries = (entries) => {
2534
+ if (!Array.isArray(entries)) {
2535
+ throw new ExtensionApiError("view menu entries must be an array");
2536
+ }
2537
+ return entries.map(normalizeMenuEntry);
2538
+ };
2465
2539
  var renderPatches = async (uid, instance) => {
2466
2540
  const oldDom = renderedDoms[uid] || [];
2467
2541
  const newDom = await renderDom(instance);
@@ -2472,6 +2546,54 @@ var renderPatches = async (uid, instance) => {
2472
2546
  type: "setPatches"
2473
2547
  };
2474
2548
  };
2549
+ var normalizeContext = (context) => {
2550
+ if (!context || typeof context !== "object" || Array.isArray(context)) {
2551
+ return {};
2552
+ }
2553
+ const normalized = {};
2554
+ for (const [key, value] of Object.entries(context)) {
2555
+ if (typeof value === "boolean") {
2556
+ normalized[key] = value;
2557
+ }
2558
+ }
2559
+ return normalized;
2560
+ };
2561
+ var isSameContext = (oldContext, newContext) => {
2562
+ const oldKeys = Object.keys(oldContext);
2563
+ const newKeys = Object.keys(newContext);
2564
+ if (oldKeys.length !== newKeys.length) {
2565
+ return false;
2566
+ }
2567
+ for (const key of oldKeys) {
2568
+ if (oldContext[key] !== newContext[key]) {
2569
+ return false;
2570
+ }
2571
+ }
2572
+ return true;
2573
+ };
2574
+ var maybeNotifyContextChanged = async (uid, viewId, instance) => {
2575
+ if (typeof instance.getContext !== "function") {
2576
+ return;
2577
+ }
2578
+ const oldContext = contexts[uid] || {};
2579
+ const newContext = normalizeContext(instance.getContext());
2580
+ if (isSameContext(oldContext, newContext)) {
2581
+ return;
2582
+ }
2583
+ if (Object.keys(newContext).length === 0) {
2584
+ delete contexts[uid];
2585
+ } else {
2586
+ contexts[uid] = newContext;
2587
+ }
2588
+ await ExtensionManagementWorker_exports.invoke("Extensions.handleViewContextChange", uid, viewId, newContext);
2589
+ };
2590
+ var maybeClearContext = async (uid, viewId) => {
2591
+ if (!contexts[uid]) {
2592
+ return;
2593
+ }
2594
+ delete contexts[uid];
2595
+ await ExtensionManagementWorker_exports.invoke("Extensions.handleViewContextChange", uid, viewId, {});
2596
+ };
2475
2597
  var createViewInstance = async (viewId, uid, context) => {
2476
2598
  const view = views[viewId];
2477
2599
  if (!view) {
@@ -2485,13 +2607,21 @@ var createViewInstance = async (viewId, uid, context) => {
2485
2607
  requestRerender() {
2486
2608
  return ExtensionManagementWorker_exports.invoke("Extensions.requestViewRerender", uid);
2487
2609
  },
2610
+ showContextMenu(menuId, x, y) {
2611
+ assertString(menuId, "menuId must be a string");
2612
+ assertNumber(x, "x must be a number");
2613
+ assertNumber(y, "y must be a number");
2614
+ return ExtensionManagementWorker_exports.invoke("Extensions.showViewContextMenu", uid, viewId, menuId, x, y);
2615
+ },
2488
2616
  uid,
2489
2617
  viewId
2490
2618
  });
2491
2619
  assertVirtualDomViewInstance(viewId, instance);
2492
2620
  instances[uid] = instance;
2621
+ contextViewIds[uid] = viewId;
2493
2622
  const dom = await renderDom(instance);
2494
2623
  renderedDoms[uid] = dom;
2624
+ await maybeNotifyContextChanged(uid, viewId, instance);
2495
2625
  return {
2496
2626
  dom,
2497
2627
  type: "setDom"
@@ -2502,19 +2632,25 @@ var dispatchViewEvent = async (uid, event) => {
2502
2632
  if (typeof instance.handleEvent === "function") {
2503
2633
  await instance.handleEvent(event);
2504
2634
  }
2505
- return renderPatches(uid, instance);
2635
+ const result = await renderPatches(uid, instance);
2636
+ await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
2637
+ return result;
2506
2638
  };
2507
2639
  var renderViewInstance = async (uid) => {
2508
2640
  const instance = getVirtualDomInstance(uid);
2509
- return renderPatches(uid, instance);
2641
+ const result = await renderPatches(uid, instance);
2642
+ await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
2643
+ return result;
2510
2644
  };
2511
2645
  var disposeViewInstance = async (uid) => {
2512
2646
  const instance = instances[uid];
2513
2647
  if (instance && typeof instance.dispose === "function") {
2514
2648
  await instance.dispose();
2515
2649
  }
2650
+ await maybeClearContext(uid, contextViewIds[uid]);
2516
2651
  delete instances[uid];
2517
2652
  delete renderedDoms[uid];
2653
+ delete contextViewIds[uid];
2518
2654
  };
2519
2655
  var saveViewInstanceState = async (uid) => {
2520
2656
  const instance = getVirtualDomInstance(uid);
@@ -2523,6 +2659,14 @@ var saveViewInstanceState = async (uid) => {
2523
2659
  }
2524
2660
  return instance.saveState();
2525
2661
  };
2662
+ var getViewMenuEntries = async (uid, menuId) => {
2663
+ assertString(menuId, "menuId must be a string");
2664
+ const instance = getVirtualDomInstance(uid);
2665
+ if (typeof instance.getMenuEntries !== "function") {
2666
+ return [];
2667
+ }
2668
+ return normalizeMenuEntries(await instance.getMenuEntries(menuId));
2669
+ };
2526
2670
  var getViewRegistrySnapshot = () => {
2527
2671
  return {
2528
2672
  views: Object.values(views).map(toRegisteredView)
@@ -2538,6 +2682,12 @@ var resetViewRegistry = () => {
2538
2682
  for (const uid of Object.keys(renderedDoms)) {
2539
2683
  delete renderedDoms[Number(uid)];
2540
2684
  }
2685
+ for (const uid of Object.keys(contexts)) {
2686
+ delete contexts[Number(uid)];
2687
+ }
2688
+ for (const uid of Object.keys(contextViewIds)) {
2689
+ delete contextViewIds[Number(uid)];
2690
+ }
2541
2691
  };
2542
2692
 
2543
2693
  // packages/extension-api/src/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.ts
@@ -2570,6 +2720,7 @@ var commandMap = {
2570
2720
  "ExtensionApi.getOutputChannelRegistrySnapshot": getOutputChannelRegistrySnapshot,
2571
2721
  "ExtensionApi.getSourceControlProviderRegistrySnapshot": getSourceControlProviderRegistrySnapshot,
2572
2722
  "ExtensionApi.getStatusBarItems": getStatusBarItems,
2723
+ "ExtensionApi.getViewMenuEntries": getViewMenuEntries,
2573
2724
  "ExtensionApi.getViewRegistrySnapshot": getViewRegistrySnapshot,
2574
2725
  "ExtensionApi.renderViewInstance": renderViewInstance,
2575
2726
  "ExtensionApi.saveViewInstanceState": saveViewInstanceState
@@ -23,6 +23,7 @@ import {
23
23
  dispatchViewEvent,
24
24
  disposeViewInstance,
25
25
  executeViewProvider,
26
+ getViewMenuEntries,
26
27
  getViewRegistrySnapshot,
27
28
  renderViewInstance,
28
29
  saveViewInstanceState
@@ -56,6 +57,7 @@ const commandMap = {
56
57
  "ExtensionApi.getOutputChannelRegistrySnapshot": getOutputChannelRegistrySnapshot,
57
58
  "ExtensionApi.getSourceControlProviderRegistrySnapshot": getSourceControlProviderRegistrySnapshot,
58
59
  "ExtensionApi.getStatusBarItems": getStatusBarItems,
60
+ "ExtensionApi.getViewMenuEntries": getViewMenuEntries,
59
61
  "ExtensionApi.getViewRegistrySnapshot": getViewRegistrySnapshot,
60
62
  "ExtensionApi.renderViewInstance": renderViewInstance,
61
63
  "ExtensionApi.saveViewInstanceState": saveViewInstanceState
@@ -4,6 +4,50 @@ import { ExtensionApiError } from "../ExtensionApiError/ExtensionApiError.js";
4
4
  const views = /* @__PURE__ */ Object.create(null);
5
5
  const instances = /* @__PURE__ */ Object.create(null);
6
6
  const renderedDoms = /* @__PURE__ */ Object.create(null);
7
+ const contexts = /* @__PURE__ */ Object.create(null);
8
+ const contextViewIds = /* @__PURE__ */ Object.create(null);
9
+ const assertBoolean = (value, message) => {
10
+ if (value !== void 0 && typeof value !== "boolean") {
11
+ throw new ExtensionApiError(message);
12
+ }
13
+ };
14
+ const assertNumber = (value, message) => {
15
+ if (typeof value !== "number") {
16
+ throw new ExtensionApiError(message);
17
+ }
18
+ };
19
+ const assertString = (value, message) => {
20
+ if (typeof value !== "string" || value.length === 0) {
21
+ throw new ExtensionApiError(message);
22
+ }
23
+ };
24
+ const assertEventListener = (viewId, listener, index) => {
25
+ if (!listener || typeof listener !== "object") {
26
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} must be an object`);
27
+ }
28
+ const eventListener = listener;
29
+ if (typeof eventListener.name !== "string" && typeof eventListener.name !== "number") {
30
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} is missing name`);
31
+ }
32
+ if (!Array.isArray(eventListener.params) || eventListener.params.some((param) => typeof param !== "string")) {
33
+ throw new ExtensionApiError(`view ${viewId} event listener ${index} is missing params`);
34
+ }
35
+ assertBoolean(eventListener.capture, `view ${viewId} event listener ${index} has invalid capture`);
36
+ assertBoolean(eventListener.passive, `view ${viewId} event listener ${index} has invalid passive`);
37
+ assertBoolean(eventListener.preventDefault, `view ${viewId} event listener ${index} has invalid preventDefault`);
38
+ assertBoolean(eventListener.stopPropagation, `view ${viewId} event listener ${index} has invalid stopPropagation`);
39
+ };
40
+ const assertEventListeners = (view) => {
41
+ if (view.eventListeners === void 0) {
42
+ return;
43
+ }
44
+ if (!Array.isArray(view.eventListeners)) {
45
+ throw new ExtensionApiError(`view ${view.id} eventListeners must be an array`);
46
+ }
47
+ for (const [index, listener] of view.eventListeners.entries()) {
48
+ assertEventListener(view.id, listener, index);
49
+ }
50
+ };
7
51
  const assertView = (view) => {
8
52
  if (!view) {
9
53
  throw new ExtensionApiError("view is not defined");
@@ -17,11 +61,13 @@ const assertView = (view) => {
17
61
  if (view.id in views) {
18
62
  throw new ExtensionApiError(`view ${view.id} is already registered`);
19
63
  }
64
+ assertEventListeners(view);
20
65
  };
21
66
  const toRegisteredView = (view) => {
22
67
  const displayName = view.displayName || view.name || view.title;
23
68
  const registeredView = {
24
69
  displayName,
70
+ ...view.eventListeners && { eventListeners: view.eventListeners },
25
71
  icon: view.icon,
26
72
  id: view.id,
27
73
  name: view.name,
@@ -73,6 +119,34 @@ const renderDom = async (instance) => {
73
119
  }
74
120
  return dom;
75
121
  };
122
+ const normalizeMenuEntry = (entry, index) => {
123
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
124
+ throw new ExtensionApiError(`menu entry ${index} must be an object`);
125
+ }
126
+ const menuEntry = entry;
127
+ assertString(menuEntry.id, `menu entry ${index} is missing id`);
128
+ assertString(menuEntry.label, `menu entry ${index} is missing label`);
129
+ assertString(menuEntry.command, `menu entry ${index} is missing command`);
130
+ if (menuEntry.flags !== void 0 && typeof menuEntry.flags !== "number") {
131
+ throw new ExtensionApiError(`menu entry ${index} has invalid flags`);
132
+ }
133
+ if (menuEntry.args !== void 0 && !Array.isArray(menuEntry.args)) {
134
+ throw new ExtensionApiError(`menu entry ${index} has invalid args`);
135
+ }
136
+ return {
137
+ command: menuEntry.command,
138
+ flags: menuEntry.flags ?? 0,
139
+ id: menuEntry.id,
140
+ label: menuEntry.label,
141
+ ...menuEntry.args && { args: menuEntry.args }
142
+ };
143
+ };
144
+ const normalizeMenuEntries = (entries) => {
145
+ if (!Array.isArray(entries)) {
146
+ throw new ExtensionApiError("view menu entries must be an array");
147
+ }
148
+ return entries.map(normalizeMenuEntry);
149
+ };
76
150
  const renderPatches = async (uid, instance) => {
77
151
  const oldDom = renderedDoms[uid] || [];
78
152
  const newDom = await renderDom(instance);
@@ -83,6 +157,54 @@ const renderPatches = async (uid, instance) => {
83
157
  type: "setPatches"
84
158
  };
85
159
  };
160
+ const normalizeContext = (context) => {
161
+ if (!context || typeof context !== "object" || Array.isArray(context)) {
162
+ return {};
163
+ }
164
+ const normalized = {};
165
+ for (const [key, value] of Object.entries(context)) {
166
+ if (typeof value === "boolean") {
167
+ normalized[key] = value;
168
+ }
169
+ }
170
+ return normalized;
171
+ };
172
+ const isSameContext = (oldContext, newContext) => {
173
+ const oldKeys = Object.keys(oldContext);
174
+ const newKeys = Object.keys(newContext);
175
+ if (oldKeys.length !== newKeys.length) {
176
+ return false;
177
+ }
178
+ for (const key of oldKeys) {
179
+ if (oldContext[key] !== newContext[key]) {
180
+ return false;
181
+ }
182
+ }
183
+ return true;
184
+ };
185
+ const maybeNotifyContextChanged = async (uid, viewId, instance) => {
186
+ if (typeof instance.getContext !== "function") {
187
+ return;
188
+ }
189
+ const oldContext = contexts[uid] || {};
190
+ const newContext = normalizeContext(instance.getContext());
191
+ if (isSameContext(oldContext, newContext)) {
192
+ return;
193
+ }
194
+ if (Object.keys(newContext).length === 0) {
195
+ delete contexts[uid];
196
+ } else {
197
+ contexts[uid] = newContext;
198
+ }
199
+ await ExtensionManagementWorker.invoke("Extensions.handleViewContextChange", uid, viewId, newContext);
200
+ };
201
+ const maybeClearContext = async (uid, viewId) => {
202
+ if (!contexts[uid]) {
203
+ return;
204
+ }
205
+ delete contexts[uid];
206
+ await ExtensionManagementWorker.invoke("Extensions.handleViewContextChange", uid, viewId, {});
207
+ };
86
208
  const createViewInstance = async (viewId, uid, context) => {
87
209
  const view = views[viewId];
88
210
  if (!view) {
@@ -96,13 +218,21 @@ const createViewInstance = async (viewId, uid, context) => {
96
218
  requestRerender() {
97
219
  return ExtensionManagementWorker.invoke("Extensions.requestViewRerender", uid);
98
220
  },
221
+ showContextMenu(menuId, x, y) {
222
+ assertString(menuId, "menuId must be a string");
223
+ assertNumber(x, "x must be a number");
224
+ assertNumber(y, "y must be a number");
225
+ return ExtensionManagementWorker.invoke("Extensions.showViewContextMenu", uid, viewId, menuId, x, y);
226
+ },
99
227
  uid,
100
228
  viewId
101
229
  });
102
230
  assertVirtualDomViewInstance(viewId, instance);
103
231
  instances[uid] = instance;
232
+ contextViewIds[uid] = viewId;
104
233
  const dom = await renderDom(instance);
105
234
  renderedDoms[uid] = dom;
235
+ await maybeNotifyContextChanged(uid, viewId, instance);
106
236
  return {
107
237
  dom,
108
238
  type: "setDom"
@@ -113,19 +243,25 @@ const dispatchViewEvent = async (uid, event) => {
113
243
  if (typeof instance.handleEvent === "function") {
114
244
  await instance.handleEvent(event);
115
245
  }
116
- return renderPatches(uid, instance);
246
+ const result = await renderPatches(uid, instance);
247
+ await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
248
+ return result;
117
249
  };
118
250
  const renderViewInstance = async (uid) => {
119
251
  const instance = getVirtualDomInstance(uid);
120
- return renderPatches(uid, instance);
252
+ const result = await renderPatches(uid, instance);
253
+ await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
254
+ return result;
121
255
  };
122
256
  const disposeViewInstance = async (uid) => {
123
257
  const instance = instances[uid];
124
258
  if (instance && typeof instance.dispose === "function") {
125
259
  await instance.dispose();
126
260
  }
261
+ await maybeClearContext(uid, contextViewIds[uid]);
127
262
  delete instances[uid];
128
263
  delete renderedDoms[uid];
264
+ delete contextViewIds[uid];
129
265
  };
130
266
  const saveViewInstanceState = async (uid) => {
131
267
  const instance = getVirtualDomInstance(uid);
@@ -134,6 +270,14 @@ const saveViewInstanceState = async (uid) => {
134
270
  }
135
271
  return instance.saveState();
136
272
  };
273
+ const getViewMenuEntries = async (uid, menuId) => {
274
+ assertString(menuId, "menuId must be a string");
275
+ const instance = getVirtualDomInstance(uid);
276
+ if (typeof instance.getMenuEntries !== "function") {
277
+ return [];
278
+ }
279
+ return normalizeMenuEntries(await instance.getMenuEntries(menuId));
280
+ };
137
281
  const getViewRegistrySnapshot = () => {
138
282
  return {
139
283
  views: Object.values(views).map(toRegisteredView)
@@ -149,12 +293,19 @@ const resetViewRegistry = () => {
149
293
  for (const uid of Object.keys(renderedDoms)) {
150
294
  delete renderedDoms[Number(uid)];
151
295
  }
296
+ for (const uid of Object.keys(contexts)) {
297
+ delete contexts[Number(uid)];
298
+ }
299
+ for (const uid of Object.keys(contextViewIds)) {
300
+ delete contextViewIds[Number(uid)];
301
+ }
152
302
  };
153
303
  export {
154
304
  createViewInstance,
155
305
  dispatchViewEvent,
156
306
  disposeViewInstance,
157
307
  executeViewProvider,
308
+ getViewMenuEntries,
158
309
  getViewRegistrySnapshot,
159
310
  registerView,
160
311
  renderViewInstance,
@@ -12,7 +12,7 @@ export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSource
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, ViewContext, ViewEvent, ViewKind, ViewRegistrySnapshot, ViewRenderResult, VirtualDomViewInstance, } from './parts/View/View.ts';
15
+ export type { RegisteredView, View, 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';
@@ -28,6 +28,7 @@ export declare const commandMap: {
28
28
  'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
29
29
  'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
30
30
  'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
31
+ 'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
31
32
  'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
32
33
  'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
33
34
  'ExtensionApi.saveViewInstanceState': (uid: number) => Promise<unknown>;
@@ -27,6 +27,7 @@ export declare const commandMap: {
27
27
  'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
28
28
  'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
29
29
  'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
30
+ 'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
30
31
  'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
31
32
  'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
32
33
  'ExtensionApi.saveViewInstanceState': (uid: number) => Promise<unknown>;
@@ -6,7 +6,7 @@ import { getStatusBarItems } from "../GetStatusBarItems/GetStatusBarItems.js";
6
6
  import { executeHoverProvider, getHoverProviderRegistrySnapshot } from "../Hover/Hover.js";
7
7
  import { getOutputChannelRegistrySnapshot } from "../OutputChannel/OutputChannel.js";
8
8
  import { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, } from "../SourceControl/SourceControl.js";
9
- import { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, saveViewInstanceState, } from "../ViewRegistry/ViewRegistry.js";
9
+ import { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewMenuEntries, getViewRegistrySnapshot, renderViewInstance, saveViewInstanceState, } from "../ViewRegistry/ViewRegistry.js";
10
10
  export const commandMap = {
11
11
  'ExtensionApi.createViewInstance': createViewInstance,
12
12
  'ExtensionApi.dispatchViewEvent': dispatchViewEvent,
@@ -36,6 +36,7 @@ export const commandMap = {
36
36
  'ExtensionApi.getOutputChannelRegistrySnapshot': getOutputChannelRegistrySnapshot,
37
37
  'ExtensionApi.getSourceControlProviderRegistrySnapshot': getSourceControlProviderRegistrySnapshot,
38
38
  'ExtensionApi.getStatusBarItems': getStatusBarItems,
39
+ 'ExtensionApi.getViewMenuEntries': getViewMenuEntries,
39
40
  'ExtensionApi.getViewRegistrySnapshot': getViewRegistrySnapshot,
40
41
  'ExtensionApi.renderViewInstance': renderViewInstance,
41
42
  'ExtensionApi.saveViewInstanceState': saveViewInstanceState,
@@ -29,6 +29,7 @@ export declare const commandMap: {
29
29
  'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
30
30
  'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
31
31
  'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
32
+ 'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
32
33
  'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
33
34
  'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
34
35
  'ExtensionApi.saveViewInstanceState': (uid: number) => Promise<unknown>;
@@ -2,6 +2,7 @@ import type { VirtualDomNode } from '@lvce-editor/virtual-dom-worker';
2
2
  export type ViewKind = 'virtualDom';
3
3
  export interface ViewContext {
4
4
  readonly requestRerender: () => Promise<void>;
5
+ readonly showContextMenu: (menuId: string, x: number, y: number) => Promise<void>;
5
6
  readonly state?: unknown;
6
7
  readonly uid: number;
7
8
  readonly viewId: string;
@@ -10,9 +11,28 @@ export interface ViewEvent {
10
11
  readonly name?: string;
11
12
  readonly type: string;
12
13
  readonly value?: unknown;
14
+ readonly x?: number;
15
+ readonly y?: number;
16
+ }
17
+ export interface MenuEntry {
18
+ readonly args?: readonly unknown[];
19
+ readonly command: string;
20
+ readonly flags?: number;
21
+ readonly id: string;
22
+ readonly label: string;
23
+ }
24
+ export interface DomEventListener {
25
+ readonly capture?: boolean;
26
+ readonly name: string | number;
27
+ readonly params: readonly string[];
28
+ readonly passive?: boolean;
29
+ readonly preventDefault?: boolean;
30
+ readonly stopPropagation?: boolean;
13
31
  }
14
32
  export interface VirtualDomViewInstance {
15
33
  readonly dispose?: () => unknown;
34
+ readonly getContext?: () => Readonly<Record<string, boolean>>;
35
+ readonly getMenuEntries?: (menuId: string) => readonly MenuEntry[] | Promise<readonly MenuEntry[]>;
16
36
  readonly handleEvent?: (event: ViewEvent) => unknown;
17
37
  readonly render: () => readonly VirtualDomNode[] | Promise<readonly VirtualDomNode[]>;
18
38
  readonly saveState?: () => unknown;
@@ -20,6 +40,7 @@ export interface VirtualDomViewInstance {
20
40
  export interface View {
21
41
  readonly create: (context?: ViewContext) => unknown;
22
42
  readonly displayName?: string;
43
+ readonly eventListeners?: readonly DomEventListener[];
23
44
  readonly icon?: string;
24
45
  readonly id: string;
25
46
  readonly kind?: ViewKind;
@@ -28,6 +49,7 @@ export interface View {
28
49
  }
29
50
  export interface RegisteredView {
30
51
  readonly displayName?: string;
52
+ readonly eventListeners?: readonly DomEventListener[];
31
53
  readonly icon?: string;
32
54
  readonly id: string;
33
55
  readonly kind?: ViewKind;
@@ -1,5 +1,5 @@
1
1
  import type { Disposable } from '../Disposable/Disposable.ts';
2
- import type { View, ViewContext, ViewEvent, ViewRegistrySnapshot, ViewRenderResult } from '../View/View.ts';
2
+ import type { MenuEntry, View, ViewContext, ViewEvent, ViewRegistrySnapshot, ViewRenderResult } from '../View/View.ts';
3
3
  export declare const registerView: (view: View) => Disposable;
4
4
  export declare const executeViewProvider: (id: string) => unknown;
5
5
  export declare const createViewInstance: (viewId: string, uid: number, context?: ViewContext) => Promise<ViewRenderResult>;
@@ -7,5 +7,6 @@ export declare const dispatchViewEvent: (uid: number, event: ViewEvent) => Promi
7
7
  export declare const renderViewInstance: (uid: number) => Promise<ViewRenderResult>;
8
8
  export declare const disposeViewInstance: (uid: number) => Promise<void>;
9
9
  export declare const saveViewInstanceState: (uid: number) => Promise<unknown>;
10
+ export declare const getViewMenuEntries: (uid: number, menuId: string) => Promise<readonly MenuEntry[]>;
10
11
  export declare const getViewRegistrySnapshot: () => ViewRegistrySnapshot;
11
12
  export declare const resetViewRegistry: () => void;