@lvce-editor/extension-host-worker 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.
Files changed (24) hide show
  1. package/dist/extension-api/index.js +103 -0
  2. package/dist/extension-api/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.js +2 -0
  3. package/dist/extension-api/parts/SourceControl/SourceControl.js +2 -0
  4. package/dist/extension-api/parts/SourceControlProviderRegistry/SourceControlProviderRegistry.js +13 -0
  5. package/dist/extension-api/parts/ViewRegistry/ViewRegistry.js +90 -0
  6. package/dist/extensionHostWorkerMain.js +10 -0
  7. package/extension-api/dist/index.d.ts +2 -2
  8. package/extension-api/dist/index.js +1 -1
  9. package/extension-api/dist/parts/CommandMap/CommandMap.d.ts +1 -0
  10. package/extension-api/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.d.ts +1 -0
  11. package/extension-api/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.js +2 -1
  12. package/extension-api/dist/parts/ExtensionApiWorkerCommandMap/ExtensionApiWorkerCommandMap.d.ts +1 -0
  13. package/extension-api/dist/parts/RegisteredSourceControlProvider/RegisteredSourceControlProvider.d.ts +1 -0
  14. package/extension-api/dist/parts/SourceControl/SourceControl.d.ts +1 -1
  15. package/extension-api/dist/parts/SourceControl/SourceControl.js +1 -1
  16. package/extension-api/dist/parts/SourceControlProvider/SourceControlProvider.d.ts +1 -0
  17. package/extension-api/dist/parts/SourceControlProviderRegistry/SourceControlProviderRegistry.d.ts +1 -0
  18. package/extension-api/dist/parts/SourceControlProviderRegistry/SourceControlProviderRegistry.js +12 -0
  19. package/extension-api/dist/parts/View/View.d.ts +4 -2
  20. package/extension-api/dist/parts/ViewRegistry/ViewRegistry.d.ts +1 -1
  21. package/extension-api/dist/parts/ViewRegistry/ViewRegistry.js +89 -0
  22. package/extension-api/package.json +1 -1
  23. package/extension-api/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +1 -1
@@ -2010,6 +2010,7 @@ var optionalMethods = [
2010
2010
  "add",
2011
2011
  "discard",
2012
2012
  "generateCommitMessage",
2013
+ "getBadgeCount",
2013
2014
  "getFeatures",
2014
2015
  "getFileBefore",
2015
2016
  "getFileDecorations",
@@ -2064,6 +2065,9 @@ var mapSourceControlProvider = (provider) => {
2064
2065
  if (provider.generateCommitMessage) {
2065
2066
  registeredProvider.generateCommitMessage = () => provider.generateCommitMessage();
2066
2067
  }
2068
+ if (provider.getBadgeCount) {
2069
+ registeredProvider.getBadgeCount = () => provider.getBadgeCount();
2070
+ }
2067
2071
  if (provider.getFeatures) {
2068
2072
  registeredProvider.getFeatures = () => provider.getFeatures();
2069
2073
  }
@@ -2105,6 +2109,14 @@ var executeSourceControlGenerateCommitMessage = async (id2) => {
2105
2109
  var executeSourceControlGetChangedFiles = async (id2) => {
2106
2110
  return getProvider(id2).getChangedFiles();
2107
2111
  };
2112
+ var executeSourceControlGetBadgeCount = async (id2) => {
2113
+ const provider = getProvider(id2);
2114
+ if (provider.getBadgeCount) {
2115
+ return provider.getBadgeCount();
2116
+ }
2117
+ const files = await provider.getChangedFiles();
2118
+ return files.length;
2119
+ };
2108
2120
  var executeSourceControlGetFeatures = async (id2) => {
2109
2121
  return getProvider(id2).getFeatures?.() ?? {};
2110
2122
  };
@@ -2392,9 +2404,11 @@ var diffTree = (oldNodes, newNodes) => {
2392
2404
  // packages/extension-api/src/parts/ViewRegistry/ViewRegistry.ts
2393
2405
  var views = /* @__PURE__ */ Object.create(null);
2394
2406
  var instances = /* @__PURE__ */ Object.create(null);
2407
+ var instanceUidsByView = /* @__PURE__ */ Object.create(null);
2395
2408
  var renderedDoms = /* @__PURE__ */ Object.create(null);
2396
2409
  var contexts = /* @__PURE__ */ Object.create(null);
2397
2410
  var contextViewIds = /* @__PURE__ */ Object.create(null);
2411
+ var viewCommandDisposables = /* @__PURE__ */ Object.create(null);
2398
2412
  var assertBoolean = (value, message) => {
2399
2413
  if (value !== void 0 && typeof value !== "boolean") {
2400
2414
  throw new ExtensionApiError(message);
@@ -2437,6 +2451,23 @@ var assertEventListeners = (view) => {
2437
2451
  assertEventListener(view.id, listener, index);
2438
2452
  }
2439
2453
  };
2454
+ var assertCommands = (view) => {
2455
+ if (view.commands === void 0) {
2456
+ return;
2457
+ }
2458
+ if (view.kind !== "virtualDom") {
2459
+ throw new ExtensionApiError(`view ${view.id} commands require virtualDom kind`);
2460
+ }
2461
+ if (!view.commands || typeof view.commands !== "object" || Array.isArray(view.commands)) {
2462
+ throw new ExtensionApiError(`view ${view.id} commands must be an object`);
2463
+ }
2464
+ for (const [id2, command] of Object.entries(view.commands)) {
2465
+ assertString(id2, `view ${view.id} command is missing id`);
2466
+ if (typeof command !== "function") {
2467
+ throw new ExtensionApiError(`view ${view.id} command ${id2} must be a function`);
2468
+ }
2469
+ }
2470
+ };
2440
2471
  var assertView = (view) => {
2441
2472
  if (!view) {
2442
2473
  throw new ExtensionApiError("view is not defined");
@@ -2450,6 +2481,7 @@ var assertView = (view) => {
2450
2481
  if (view.id in views) {
2451
2482
  throw new ExtensionApiError(`view ${view.id} is already registered`);
2452
2483
  }
2484
+ assertCommands(view);
2453
2485
  assertEventListeners(view);
2454
2486
  };
2455
2487
  var toRegisteredView = (view) => {
@@ -2470,12 +2502,62 @@ var toRegisteredView = (view) => {
2470
2502
  }
2471
2503
  return registeredView;
2472
2504
  };
2505
+ var getActiveViewInstance = (viewId) => {
2506
+ const instanceUids = instanceUidsByView[viewId];
2507
+ if (!instanceUids) {
2508
+ return void 0;
2509
+ }
2510
+ const uid = [...instanceUids].at(-1);
2511
+ if (uid === void 0) {
2512
+ return void 0;
2513
+ }
2514
+ return [uid, instances[uid]];
2515
+ };
2516
+ var executeViewCommand = async (view, commandId, args) => {
2517
+ const activeInstance = getActiveViewInstance(view.id);
2518
+ if (!activeInstance) {
2519
+ return;
2520
+ }
2521
+ const [uid, instance] = activeInstance;
2522
+ const command = view.commands[commandId];
2523
+ const newInstance = await command(instance, ...args);
2524
+ assertVirtualDomViewInstance(view.id, newInstance);
2525
+ instances[uid] = newInstance;
2526
+ await ExtensionManagementWorker_exports.invoke("Extensions.requestViewRerender", uid);
2527
+ };
2528
+ var registerViewCommands = (view) => {
2529
+ const disposables = [];
2530
+ try {
2531
+ for (const id2 of Object.keys(view.commands || {})) {
2532
+ disposables.push(
2533
+ registerCommand({
2534
+ execute(...args) {
2535
+ return executeViewCommand(view, id2, args);
2536
+ },
2537
+ id: id2
2538
+ })
2539
+ );
2540
+ }
2541
+ } catch (error) {
2542
+ for (const disposable of disposables) {
2543
+ disposable.dispose();
2544
+ }
2545
+ throw error;
2546
+ }
2547
+ return disposables;
2548
+ };
2473
2549
  var registerView = (view) => {
2474
2550
  assertView(view);
2551
+ const commandDisposables = registerViewCommands(view);
2475
2552
  views[view.id] = view;
2553
+ viewCommandDisposables[view.id] = commandDisposables;
2476
2554
  return {
2477
2555
  dispose() {
2556
+ for (const disposable of commandDisposables) {
2557
+ disposable.dispose();
2558
+ }
2478
2559
  delete views[view.id];
2560
+ delete viewCommandDisposables[view.id];
2479
2561
  }
2480
2562
  };
2481
2563
  };
@@ -2672,6 +2754,9 @@ var createViewInstance = async (viewId, uid, context) => {
2672
2754
  });
2673
2755
  assertVirtualDomViewInstance(viewId, instance);
2674
2756
  instances[uid] = instance;
2757
+ const instanceUids = instanceUidsByView[viewId] || /* @__PURE__ */ new Set();
2758
+ instanceUids.add(uid);
2759
+ instanceUidsByView[viewId] = instanceUids;
2675
2760
  contextViewIds[uid] = viewId;
2676
2761
  const dom = await renderDom(instance);
2677
2762
  renderedDoms[uid] = dom;
@@ -2684,6 +2769,9 @@ var createViewInstance = async (viewId, uid, context) => {
2684
2769
  };
2685
2770
  var dispatchViewEvent = async (uid, event) => {
2686
2771
  const instance = getVirtualDomInstance(uid);
2772
+ const instanceUids = instanceUidsByView[contextViewIds[uid]];
2773
+ instanceUids.delete(uid);
2774
+ instanceUids.add(uid);
2687
2775
  if (typeof instance.handleEvent === "function") {
2688
2776
  await instance.handleEvent(event);
2689
2777
  }
@@ -2703,6 +2791,12 @@ var disposeViewInstance = async (uid) => {
2703
2791
  await instance.dispose();
2704
2792
  }
2705
2793
  await maybeClearContext(uid, contextViewIds[uid]);
2794
+ const viewId = contextViewIds[uid];
2795
+ const instanceUids = instanceUidsByView[viewId];
2796
+ instanceUids?.delete(uid);
2797
+ if (instanceUids?.size === 0) {
2798
+ delete instanceUidsByView[viewId];
2799
+ }
2706
2800
  delete instances[uid];
2707
2801
  delete renderedDoms[uid];
2708
2802
  delete contextViewIds[uid];
@@ -2736,7 +2830,11 @@ var getViewRegistrySnapshot = () => {
2736
2830
  };
2737
2831
  var resetViewRegistry = () => {
2738
2832
  for (const id2 of Object.keys(views)) {
2833
+ for (const disposable of viewCommandDisposables[id2] || []) {
2834
+ disposable.dispose();
2835
+ }
2739
2836
  delete views[id2];
2837
+ delete viewCommandDisposables[id2];
2740
2838
  }
2741
2839
  for (const uid of Object.keys(instances)) {
2742
2840
  delete instances[Number(uid)];
@@ -2750,6 +2848,9 @@ var resetViewRegistry = () => {
2750
2848
  for (const uid of Object.keys(contextViewIds)) {
2751
2849
  delete contextViewIds[Number(uid)];
2752
2850
  }
2851
+ for (const viewId of Object.keys(instanceUidsByView)) {
2852
+ delete instanceUidsByView[viewId];
2853
+ }
2753
2854
  };
2754
2855
 
2755
2856
  // packages/extension-api/src/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.ts
@@ -2767,6 +2868,7 @@ var commandMap = {
2767
2868
  "ExtensionApi.executeSourceControlAdd": executeSourceControlAdd,
2768
2869
  "ExtensionApi.executeSourceControlDiscard": executeSourceControlDiscard,
2769
2870
  "ExtensionApi.executeSourceControlGenerateCommitMessage": executeSourceControlGenerateCommitMessage,
2871
+ "ExtensionApi.executeSourceControlGetBadgeCount": executeSourceControlGetBadgeCount,
2770
2872
  "ExtensionApi.executeSourceControlGetChangedFiles": executeSourceControlGetChangedFiles,
2771
2873
  "ExtensionApi.executeSourceControlGetFeatures": executeSourceControlGetFeatures,
2772
2874
  "ExtensionApi.executeSourceControlGetFileBefore": executeSourceControlGetFileBefore,
@@ -2943,6 +3045,7 @@ export {
2943
3045
  executeSourceControlAdd,
2944
3046
  executeSourceControlDiscard,
2945
3047
  executeSourceControlGenerateCommitMessage,
3048
+ executeSourceControlGetBadgeCount,
2946
3049
  executeSourceControlGetChangedFiles,
2947
3050
  executeSourceControlGetFeatures,
2948
3051
  executeSourceControlGetFileBefore,
@@ -10,6 +10,7 @@ import {
10
10
  executeSourceControlAdd,
11
11
  executeSourceControlDiscard,
12
12
  executeSourceControlGenerateCommitMessage,
13
+ executeSourceControlGetBadgeCount,
13
14
  executeSourceControlGetChangedFiles,
14
15
  executeSourceControlGetFeatures,
15
16
  executeSourceControlGetFileBefore,
@@ -43,6 +44,7 @@ const commandMap = {
43
44
  "ExtensionApi.executeSourceControlAdd": executeSourceControlAdd,
44
45
  "ExtensionApi.executeSourceControlDiscard": executeSourceControlDiscard,
45
46
  "ExtensionApi.executeSourceControlGenerateCommitMessage": executeSourceControlGenerateCommitMessage,
47
+ "ExtensionApi.executeSourceControlGetBadgeCount": executeSourceControlGetBadgeCount,
46
48
  "ExtensionApi.executeSourceControlGetChangedFiles": executeSourceControlGetChangedFiles,
47
49
  "ExtensionApi.executeSourceControlGetFeatures": executeSourceControlGetFeatures,
48
50
  "ExtensionApi.executeSourceControlGetFileBefore": executeSourceControlGetFileBefore,
@@ -3,6 +3,7 @@ import {
3
3
  executeSourceControlAdd,
4
4
  executeSourceControlDiscard,
5
5
  executeSourceControlGenerateCommitMessage,
6
+ executeSourceControlGetBadgeCount,
6
7
  executeSourceControlGetChangedFiles,
7
8
  executeSourceControlGetFeatures,
8
9
  executeSourceControlGetFileBefore,
@@ -18,6 +19,7 @@ export {
18
19
  executeSourceControlAdd,
19
20
  executeSourceControlDiscard,
20
21
  executeSourceControlGenerateCommitMessage,
22
+ executeSourceControlGetBadgeCount,
21
23
  executeSourceControlGetChangedFiles,
22
24
  executeSourceControlGetFeatures,
23
25
  executeSourceControlGetFileBefore,
@@ -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 @@ const executeSourceControlGenerateCommitMessage = async (id) => {
100
104
  const executeSourceControlGetChangedFiles = async (id) => {
101
105
  return getProvider(id).getChangedFiles();
102
106
  };
107
+ 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
  const executeSourceControlGetFeatures = async (id) => {
104
116
  return getProvider(id).getFeatures?.() ?? {};
105
117
  };
@@ -142,6 +154,7 @@ export {
142
154
  executeSourceControlAdd,
143
155
  executeSourceControlDiscard,
144
156
  executeSourceControlGenerateCommitMessage,
157
+ executeSourceControlGetBadgeCount,
145
158
  executeSourceControlGetChangedFiles,
146
159
  executeSourceControlGetFeatures,
147
160
  executeSourceControlGetFileBefore,
@@ -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 = /* @__PURE__ */ Object.create(null);
5
6
  const instances = /* @__PURE__ */ Object.create(null);
7
+ const instanceUidsByView = /* @__PURE__ */ Object.create(null);
6
8
  const renderedDoms = /* @__PURE__ */ Object.create(null);
7
9
  const contexts = /* @__PURE__ */ Object.create(null);
8
10
  const contextViewIds = /* @__PURE__ */ Object.create(null);
11
+ const viewCommandDisposables = /* @__PURE__ */ Object.create(null);
9
12
  const assertBoolean = (value, message) => {
10
13
  if (value !== void 0 && 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 === void 0) {
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,62 @@ 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 void 0;
109
+ }
110
+ const uid = [...instanceUids].at(-1);
111
+ if (uid === void 0) {
112
+ return void 0;
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(
133
+ registerCommand({
134
+ execute(...args) {
135
+ return executeViewCommand(view, id, args);
136
+ },
137
+ id
138
+ })
139
+ );
140
+ }
141
+ } catch (error) {
142
+ for (const disposable of disposables) {
143
+ disposable.dispose();
144
+ }
145
+ throw error;
146
+ }
147
+ return disposables;
148
+ };
84
149
  const registerView = (view) => {
85
150
  assertView(view);
151
+ const commandDisposables = registerViewCommands(view);
86
152
  views[view.id] = view;
153
+ viewCommandDisposables[view.id] = commandDisposables;
87
154
  return {
88
155
  dispose() {
156
+ for (const disposable of commandDisposables) {
157
+ disposable.dispose();
158
+ }
89
159
  delete views[view.id];
160
+ delete viewCommandDisposables[view.id];
90
161
  }
91
162
  };
92
163
  };
@@ -283,6 +354,9 @@ const createViewInstance = async (viewId, uid, context) => {
283
354
  });
284
355
  assertVirtualDomViewInstance(viewId, instance);
285
356
  instances[uid] = instance;
357
+ const instanceUids = instanceUidsByView[viewId] || /* @__PURE__ */ new Set();
358
+ instanceUids.add(uid);
359
+ instanceUidsByView[viewId] = instanceUids;
286
360
  contextViewIds[uid] = viewId;
287
361
  const dom = await renderDom(instance);
288
362
  renderedDoms[uid] = dom;
@@ -295,6 +369,9 @@ const createViewInstance = async (viewId, uid, context) => {
295
369
  };
296
370
  const dispatchViewEvent = async (uid, event) => {
297
371
  const instance = getVirtualDomInstance(uid);
372
+ const instanceUids = instanceUidsByView[contextViewIds[uid]];
373
+ instanceUids.delete(uid);
374
+ instanceUids.add(uid);
298
375
  if (typeof instance.handleEvent === "function") {
299
376
  await instance.handleEvent(event);
300
377
  }
@@ -314,6 +391,12 @@ const disposeViewInstance = async (uid) => {
314
391
  await instance.dispose();
315
392
  }
316
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
+ }
317
400
  delete instances[uid];
318
401
  delete renderedDoms[uid];
319
402
  delete contextViewIds[uid];
@@ -347,7 +430,11 @@ const getViewRegistrySnapshot = () => {
347
430
  };
348
431
  const resetViewRegistry = () => {
349
432
  for (const id of Object.keys(views)) {
433
+ for (const disposable of viewCommandDisposables[id] || []) {
434
+ disposable.dispose();
435
+ }
350
436
  delete views[id];
437
+ delete viewCommandDisposables[id];
351
438
  }
352
439
  for (const uid of Object.keys(instances)) {
353
440
  delete instances[Number(uid)];
@@ -361,6 +448,9 @@ const resetViewRegistry = () => {
361
448
  for (const uid of Object.keys(contextViewIds)) {
362
449
  delete contextViewIds[Number(uid)];
363
450
  }
451
+ for (const viewId of Object.keys(instanceUidsByView)) {
452
+ delete instanceUidsByView[viewId];
453
+ }
364
454
  };
365
455
  export {
366
456
  createViewInstance,
@@ -3235,6 +3235,14 @@ const getChangedFiles = async providerId => {
3235
3235
  const flattenedChangedFiles = changedFiles;
3236
3236
  return flattenedChangedFiles;
3237
3237
  };
3238
+ const getBadgeCount = async providerId => {
3239
+ const provider = getProvider$1(providerId);
3240
+ if (typeof provider.getBadgeCount === 'function') {
3241
+ return provider.getBadgeCount();
3242
+ }
3243
+ const changedFiles = await getFilesFromProvider(provider);
3244
+ return changedFiles.length;
3245
+ };
3238
3246
  const getFileBefore = async (providerId, uri) => {
3239
3247
  string(providerId);
3240
3248
  string(uri);
@@ -5754,6 +5762,7 @@ const SourceControlAdd = 'ExtensionHostSourceControl.add';
5754
5762
  const SourceControlDiscard = 'ExtensionHostSourceControl.discard';
5755
5763
  const SourceControlGenerateCommitMessage = 'ExtensionHostSourceControl.generateCommitMessage';
5756
5764
  const SourceControlGetChangedFiles = 'ExtensionHost.sourceControlGetChangedFiles';
5765
+ const SourceControlGetBadgeCount = 'ExtensionHostSourceControl.getBadgeCount';
5757
5766
  const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
5758
5767
  const SourceControlGetFeatures = 'ExtensionHostSourceControl.getFeatures';
5759
5768
  const SourceControlGetFileBefore = 'ExtensionHostSourceControl.GetFileBefore';
@@ -6977,6 +6986,7 @@ const commandMap = {
6977
6986
  [SourceControlAdd]: add,
6978
6987
  [SourceControlDiscard]: discard,
6979
6988
  [SourceControlGenerateCommitMessage]: generateCommitMessage,
6989
+ [SourceControlGetBadgeCount]: getBadgeCount,
6980
6990
  [SourceControlGetChangedFiles]: getChangedFiles,
6981
6991
  [SourceControlGetEnabledProviderIds]: getEnabledProviderIds,
6982
6992
  [SourceControlGetFeatures]: getFeatures,
@@ -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';
@@ -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 interface View {
48
- readonly create: (context?: ViewContext) => unknown;
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>;