@workbench-kit/shell-react 0.0.2-prototype.0.2.32 → 0.0.2-prototype.0.2.34

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 (52) hide show
  1. package/README.md +32 -0
  2. package/package.json +9 -9
  3. package/src/commands/use-command-descriptors.ts +7 -3
  4. package/src/commands/use-extension-registry-command-descriptors.ts +23 -6
  5. package/src/devtools/use-workbench-devtools-snapshot.ts +39 -14
  6. package/src/devtools/workbench-devtools-snapshot.ts +32 -13
  7. package/src/editor/area.tsx +3 -2
  8. package/src/editor/state-storage.ts +31 -0
  9. package/src/editor/tab-context-menu.ts +8 -8
  10. package/src/editor/use-editor.ts +6 -6
  11. package/src/explorer/context-menu.ts +8 -4
  12. package/src/explorer/view.tsx +4 -3
  13. package/src/extensions/canonical-extension-descriptions.ts +58 -0
  14. package/src/extensions/context-menu.ts +9 -6
  15. package/src/extensions/extension-enablement-context.ts +15 -0
  16. package/src/extensions/extension-enablement-controller.ts +453 -0
  17. package/src/extensions/management-model.ts +111 -47
  18. package/src/extensions/theme-selection-protection.ts +98 -0
  19. package/src/extensions/uninstall-eligibility.ts +103 -0
  20. package/src/extensions/use-extension-management.ts +151 -67
  21. package/src/extensions/view.tsx +4 -0
  22. package/src/field-remap/chrome-labels.ts +87 -2
  23. package/src/field-remap/convert-palette.tsx +164 -18
  24. package/src/field-remap/demo.tsx +48 -3
  25. package/src/field-remap/detail-panel.tsx +6 -5
  26. package/src/field-remap/flow.tsx +341 -155
  27. package/src/field-remap/history.ts +99 -0
  28. package/src/field-remap/index.ts +9 -1
  29. package/src/field-remap/panel.tsx +388 -97
  30. package/src/field-remap/preview-controller.ts +122 -0
  31. package/src/field-remap/preview.tsx +171 -0
  32. package/src/field-remap/view.css +154 -2
  33. package/src/index.ts +16 -1
  34. package/src/management/keybinding-overrides-storage.ts +28 -0
  35. package/src/management/preference-settings-storage.ts +28 -0
  36. package/src/management/settings.tsx +2 -0
  37. package/src/management/use-command-management.ts +31 -26
  38. package/src/management/use-keybinding-management.ts +25 -12
  39. package/src/shell/focused-extension-services.ts +138 -0
  40. package/src/shell/host-shell.tsx +13 -10
  41. package/src/shell/persistence-diagnostic-context.ts +11 -0
  42. package/src/shell/provider.tsx +373 -69
  43. package/src/shell/settings.tsx +25 -16
  44. package/src/shell/shell.tsx +119 -78
  45. package/src/shell/view-host.tsx +23 -22
  46. package/src/storage/local-json-storage.ts +43 -29
  47. package/src/storage/persistence-diagnostics.ts +72 -0
  48. package/src/workbench/appearance-storage.ts +28 -0
  49. package/src/workbench/command-host.tsx +19 -22
  50. package/src/workbench/command-palette.ts +14 -13
  51. package/src/workbench/layout-storage.ts +52 -5
  52. package/src/workbench/use-persisted-appearance.ts +38 -12
@@ -13,7 +13,7 @@ import {
13
13
  createEditorService,
14
14
  ExtensionRegistry,
15
15
  LayoutService,
16
- loadInstalledExtensions,
16
+ loadInstalledExtensionsResult,
17
17
  mergeExtensionsConfigWithInstallState,
18
18
  PreferenceService,
19
19
  registerEditorSaveCommand,
@@ -25,9 +25,18 @@ import {
25
25
  verifyWorkbenchExtensionsAgainstLock,
26
26
  type EditorState,
27
27
  type EditorService,
28
+ type ActivityRegistry,
29
+ type ConfigurationRegistry,
28
30
  type ExtensionIntegrityMode,
31
+ type LocalizationRegistry,
32
+ type MenuRegistry,
29
33
  type PreferenceService as PreferenceServiceType,
34
+ type StatusBarRegistry,
35
+ type ThemeRegistry,
36
+ type ViewRegistry,
37
+ type ViewHostFactoryRegistry,
30
38
  type WorkbenchHostThemeRegistration,
39
+ type WorkbenchPersistenceDiagnosticHandler,
31
40
  type WorkbenchStorageAdapter,
32
41
  type WorkbenchEditorSavePort,
33
42
  type WorkbenchExtensionDescription,
@@ -37,7 +46,9 @@ import {
37
46
  import {
38
47
  ContextKeyService,
39
48
  createWorkbenchPermissionContextKeys,
49
+ type CommandRegistry,
40
50
  type ContextKeyValue,
51
+ type KeybindingRegistry,
41
52
  } from '@workbench-kit/platform';
42
53
  import type {
43
54
  WorkbenchExtensionsConfig,
@@ -49,20 +60,20 @@ import type {
49
60
  import {
50
61
  DEFAULT_WORKBENCH_LAYOUT_STORAGE_KEY,
51
62
  isWorkbenchLayoutPersistenceAvailable,
52
- resolvePersistedWorkbenchLayout,
53
- writePersistedWorkbenchLayout,
63
+ resolvePersistedWorkbenchLayoutResult,
64
+ writePersistedWorkbenchLayoutResult,
54
65
  } from '../workbench/layout-storage.js';
55
66
  import {
56
67
  DEFAULT_WORKBENCH_EDITOR_STATE_STORAGE_KEY,
57
68
  isWorkbenchEditorStatePersistenceAvailable,
58
- readPersistedEditorState,
59
- writePersistedEditorState,
69
+ readPersistedEditorStateResult,
70
+ writePersistedEditorStateResult,
60
71
  } from '../editor/state-storage.js';
61
72
  import {
62
73
  DEFAULT_WORKBENCH_KEYBINDING_STORAGE_KEY,
63
74
  isWorkbenchKeybindingPersistenceAvailable,
64
- readPersistedKeybindingOverrides,
65
- writePersistedKeybindingOverrides,
75
+ readPersistedKeybindingOverridesResult,
76
+ writePersistedKeybindingOverridesResult,
66
77
  } from '../management/keybinding-overrides-storage.js';
67
78
  import {
68
79
  BUILTIN_EXPLORER_VIEW_CONTAINER_ID,
@@ -73,11 +84,29 @@ import {
73
84
  BUILTIN_EXTENSIONS_FOCUS_COMMAND_ID,
74
85
  BUILTIN_EXTENSIONS_VIEW_CONTAINER_ID,
75
86
  } from '../extensions/view-data.js';
87
+ import {
88
+ createWorkbenchExtensionActivationAccess,
89
+ createWorkbenchExtensionActivationStateReader,
90
+ createWorkbenchExtensionCatalogReader,
91
+ createWorkbenchSettingsCapabilityPublisher,
92
+ type WorkbenchExtensionActivationAccess,
93
+ type WorkbenchExtensionActivationStateReader,
94
+ type WorkbenchExtensionCatalogReader,
95
+ type WorkbenchSettingsCapabilityPublisher,
96
+ } from './focused-extension-services.js';
97
+
98
+ export type {
99
+ WorkbenchExtensionActivationAccess,
100
+ WorkbenchExtensionActivationStateReader,
101
+ WorkbenchExtensionCatalogReader,
102
+ WorkbenchSettingsCapabilityPublication,
103
+ WorkbenchSettingsCapabilityPublisher,
104
+ } from './focused-extension-services.js';
76
105
  import {
77
106
  DEFAULT_WORKBENCH_LOCAL_PREFERENCE_STORAGE_KEY,
78
107
  isWorkbenchLocalPreferencePersistenceAvailable,
79
- readPersistedLocalPreferences,
80
- writePersistedLocalPreferences,
108
+ readPersistedLocalPreferencesResult,
109
+ writePersistedLocalPreferencesResult,
81
110
  } from '../management/preference-settings-storage.js';
82
111
  import { registerWorkbenchUserCommands } from '../workbench/user-commands.js';
83
112
  import { EditorWorkspaceReconciler } from '../editor/workspace-reconcile.js';
@@ -86,6 +115,15 @@ import {
86
115
  type EditorDocumentViewProvider,
87
116
  } from '../editor/view-providers.js';
88
117
  import type { EditorDocumentViewProviderRegistry } from '@workbench-kit/workbench-core';
118
+ import { ExtensionEnablementController } from '../extensions/extension-enablement-controller.js';
119
+ import { ExtensionEnablementContext } from '../extensions/extension-enablement-context.js';
120
+ import {
121
+ reportPersistenceWriteResult,
122
+ reportPersistenceDiagnostic,
123
+ usePersistenceDiagnosticHandlerRef,
124
+ useReportPersistenceReadDiagnostic,
125
+ } from '../storage/persistence-diagnostics.js';
126
+ import { WorkbenchPersistenceDiagnosticContext } from './persistence-diagnostic-context.js';
89
127
 
90
128
  export interface WorkbenchWorkspaceHostPort extends WorkbenchEditorSavePort {
91
129
  readonly capabilityId?: string | undefined;
@@ -134,6 +172,7 @@ export interface WorkbenchProviderProps {
134
172
  localPreferenceStorageKey?: string;
135
173
  onKeybindingOverridesChange?:
136
174
  ((overrides: readonly WorkbenchKeybindingDefinition[]) => void) | undefined;
175
+ onPersistenceDiagnostic?: WorkbenchPersistenceDiagnosticHandler | undefined;
137
176
  persistEditorState?: boolean;
138
177
  persistKeybindingOverrides?: boolean;
139
178
  persistLayout?: boolean;
@@ -146,20 +185,33 @@ export interface WorkbenchProviderProps {
146
185
 
147
186
  export interface WorkbenchContextValue {
148
187
  activateCommand(commandId: string): Promise<readonly { readonly extensionId: string }[]>;
188
+ activities: ActivityRegistry;
149
189
  availableExtensions: readonly WorkbenchExtensionDescription[];
190
+ commands: CommandRegistry;
191
+ configurations: ConfigurationRegistry;
150
192
  contextKeyService: ContextKeyService;
151
193
  editorDocumentViewProviders: EditorDocumentViewProviderRegistry;
152
194
  editorService: EditorService;
153
195
  executeCommand(commandId: string, ...args: unknown[]): Promise<unknown>;
154
- extensionRegistry: ExtensionRegistry;
196
+ extensionActivation: WorkbenchExtensionActivationAccess;
197
+ extensionActivationState: WorkbenchExtensionActivationStateReader;
198
+ extensionCatalog: WorkbenchExtensionCatalogReader;
155
199
  installedExtensionsStorage?: WorkbenchStorageAdapter;
156
200
  installedExtensionsStorageKey: string;
201
+ keybindings: KeybindingRegistry;
157
202
  keybindingOverrides: readonly WorkbenchKeybindingDefinition[];
158
203
  layoutService: LayoutService;
204
+ localizations: LocalizationRegistry;
205
+ menus: MenuRegistry;
159
206
  missingExtensionIds: readonly string[];
160
207
  preferenceService: PreferenceServiceType;
161
208
  resetCommandKeybindingOverride(commandId: string): void;
162
209
  setCommandKeybindingOverride(commandId: string, key: string): void;
210
+ settingsCapabilityPublisher: WorkbenchSettingsCapabilityPublisher;
211
+ statusBar: StatusBarRegistry;
212
+ themes: ThemeRegistry;
213
+ viewHostFactories: ViewHostFactoryRegistry;
214
+ views: ViewRegistry;
163
215
  waitForExtensionStartup(): Promise<void>;
164
216
  workspaceHostPort?: WorkbenchWorkspaceHostPort | undefined;
165
217
  }
@@ -170,6 +222,7 @@ interface WorkbenchProviderServices {
170
222
  dispose(): void;
171
223
  editorDocumentViewProviders: EditorDocumentViewProviderRegistry;
172
224
  editorService: EditorService;
225
+ extensionEnablement: ExtensionEnablementController;
173
226
  extensionRegistry: ExtensionRegistry;
174
227
  layoutService: LayoutService;
175
228
  missingExtensionIds: readonly string[];
@@ -183,8 +236,50 @@ interface DeferredProviderDispose {
183
236
  readonly timeout: ReturnType<typeof setTimeout>;
184
237
  }
185
238
 
239
+ interface KeybindingOverridesState {
240
+ readonly initialOverrides: readonly WorkbenchKeybindingDefinition[] | undefined;
241
+ readonly overrides: readonly WorkbenchKeybindingDefinition[];
242
+ readonly shouldPersist: boolean;
243
+ readonly storage: WorkbenchStorageAdapter | undefined;
244
+ readonly storageKey: string;
245
+ readonly writeEligible: boolean;
246
+ }
247
+
186
248
  const WorkbenchContext = createContext<WorkbenchContextValue | undefined>(undefined);
187
249
 
250
+ function isKeybindingStateCurrent(
251
+ state: KeybindingOverridesState,
252
+ initialOverrides: readonly WorkbenchKeybindingDefinition[] | undefined,
253
+ shouldPersist: boolean,
254
+ storage: WorkbenchStorageAdapter | undefined,
255
+ storageKey: string,
256
+ ): boolean {
257
+ return (
258
+ state.initialOverrides === initialOverrides &&
259
+ state.shouldPersist === shouldPersist &&
260
+ state.storage === storage &&
261
+ state.storageKey === storageKey
262
+ );
263
+ }
264
+
265
+ function createKeybindingOverridesState(
266
+ initialOverrides: readonly WorkbenchKeybindingDefinition[] | undefined,
267
+ resolvedOverrides: readonly WorkbenchKeybindingDefinition[],
268
+ readFailed: boolean,
269
+ shouldPersist: boolean,
270
+ storage: WorkbenchStorageAdapter | undefined,
271
+ storageKey: string,
272
+ ): KeybindingOverridesState {
273
+ return {
274
+ initialOverrides,
275
+ overrides: resolvedOverrides,
276
+ shouldPersist,
277
+ storage,
278
+ storageKey,
279
+ writeEligible: initialOverrides !== undefined || !readFailed,
280
+ };
281
+ }
282
+
188
283
  function createInitialContextKeyService(
189
284
  contextKeyValues: Readonly<Record<string, ContextKeyValue>> | undefined,
190
285
  ): ContextKeyService {
@@ -228,6 +323,7 @@ export function WorkbenchProvider({
228
323
  localPreferenceStorage,
229
324
  localPreferenceStorageKey = DEFAULT_WORKBENCH_LOCAL_PREFERENCE_STORAGE_KEY,
230
325
  onKeybindingOverridesChange,
326
+ onPersistenceDiagnostic,
231
327
  persistEditorState,
232
328
  persistKeybindingOverrides,
233
329
  persistLayout,
@@ -249,32 +345,37 @@ export function WorkbenchProvider({
249
345
  const shouldPersistLocalPreferences =
250
346
  persistLocalPreferences ??
251
347
  (localPreferenceStorage !== undefined || isWorkbenchLocalPreferencePersistenceAvailable());
252
- const resolvedInitialLayout = useMemo(
348
+ const diagnosticHandlerRef = usePersistenceDiagnosticHandlerRef(onPersistenceDiagnostic);
349
+ const resolvedInitialLayoutResult = useMemo(
253
350
  () =>
254
- resolvePersistedWorkbenchLayout(initialLayout, {
351
+ resolvePersistedWorkbenchLayoutResult(initialLayout, {
255
352
  persistLayout: shouldPersistLayout,
256
353
  storage: layoutStorage,
257
354
  storageKey: layoutStorageKey,
258
355
  }),
259
356
  [initialLayout, layoutStorage, layoutStorageKey, shouldPersistLayout],
260
357
  );
261
- const resolvedInitialEditorState = useMemo(
358
+ const resolvedInitialLayout = resolvedInitialLayoutResult.value;
359
+ const resolvedInitialEditorStateResult = useMemo(
262
360
  () =>
263
- initialEditorState ??
264
- (shouldPersistEditorState
265
- ? readPersistedEditorState(editorStateStorageKey, editorStateStorage)
266
- : undefined),
361
+ initialEditorState !== undefined
362
+ ? { value: initialEditorState }
363
+ : shouldPersistEditorState
364
+ ? readPersistedEditorStateResult(editorStateStorageKey, editorStateStorage)
365
+ : { value: undefined },
267
366
  [editorStateStorage, editorStateStorageKey, initialEditorState, shouldPersistEditorState],
268
367
  );
269
- const resolvedInitialKeybindingOverrides = useMemo(
368
+ const resolvedInitialEditorState = resolvedInitialEditorStateResult.value;
369
+ const resolvedInitialKeybindingOverridesResult = useMemo(
270
370
  () =>
271
- initialKeybindingOverrides ??
272
- (shouldPersistKeybindingOverrides
273
- ? readPersistedKeybindingOverrides(
274
- keybindingOverridesStorageKey,
275
- keybindingOverridesStorage,
276
- )
277
- : []),
371
+ initialKeybindingOverrides !== undefined
372
+ ? { value: initialKeybindingOverrides }
373
+ : shouldPersistKeybindingOverrides
374
+ ? readPersistedKeybindingOverridesResult(
375
+ keybindingOverridesStorageKey,
376
+ keybindingOverridesStorage,
377
+ )
378
+ : { value: [] },
278
379
  [
279
380
  initialKeybindingOverrides,
280
381
  keybindingOverridesStorage,
@@ -282,9 +383,27 @@ export function WorkbenchProvider({
282
383
  shouldPersistKeybindingOverrides,
283
384
  ],
284
385
  );
285
- const [keybindingOverrides, setKeybindingOverridesState] = useState(
286
- resolvedInitialKeybindingOverrides,
386
+ const resolvedInitialKeybindingOverrides = resolvedInitialKeybindingOverridesResult.value;
387
+ const [keybindingState, setKeybindingState] = useState<KeybindingOverridesState>(() =>
388
+ createKeybindingOverridesState(
389
+ initialKeybindingOverrides,
390
+ resolvedInitialKeybindingOverrides,
391
+ resolvedInitialKeybindingOverridesResult.diagnostic !== undefined,
392
+ shouldPersistKeybindingOverrides,
393
+ keybindingOverridesStorage,
394
+ keybindingOverridesStorageKey,
395
+ ),
396
+ );
397
+ const keybindingStateIsCurrent = isKeybindingStateCurrent(
398
+ keybindingState,
399
+ initialKeybindingOverrides,
400
+ shouldPersistKeybindingOverrides,
401
+ keybindingOverridesStorage,
402
+ keybindingOverridesStorageKey,
287
403
  );
404
+ const keybindingOverrides = keybindingStateIsCurrent
405
+ ? keybindingState.overrides
406
+ : resolvedInitialKeybindingOverrides;
288
407
  const [contextKeyService] = useState(() => createInitialContextKeyService(contextKeyValues));
289
408
 
290
409
  useEffect(() => {
@@ -304,48 +423,168 @@ export function WorkbenchProvider({
304
423
  }, [contextKeyService, contextKeyValues]);
305
424
 
306
425
  useEffect(() => {
307
- setKeybindingOverridesState(resolvedInitialKeybindingOverrides);
308
- }, [resolvedInitialKeybindingOverrides]);
426
+ setKeybindingState((current) =>
427
+ isKeybindingStateCurrent(
428
+ current,
429
+ initialKeybindingOverrides,
430
+ shouldPersistKeybindingOverrides,
431
+ keybindingOverridesStorage,
432
+ keybindingOverridesStorageKey,
433
+ )
434
+ ? current
435
+ : createKeybindingOverridesState(
436
+ initialKeybindingOverrides,
437
+ resolvedInitialKeybindingOverrides,
438
+ resolvedInitialKeybindingOverridesResult.diagnostic !== undefined,
439
+ shouldPersistKeybindingOverrides,
440
+ keybindingOverridesStorage,
441
+ keybindingOverridesStorageKey,
442
+ ),
443
+ );
444
+ }, [
445
+ initialKeybindingOverrides,
446
+ keybindingOverridesStorage,
447
+ keybindingOverridesStorageKey,
448
+ resolvedInitialKeybindingOverrides,
449
+ resolvedInitialKeybindingOverridesResult.diagnostic,
450
+ shouldPersistKeybindingOverrides,
451
+ ]);
309
452
 
310
- const setCommandKeybindingOverride = useCallback((commandId: string, key: string) => {
311
- setKeybindingOverridesState((current) => {
312
- const without = current.filter((binding) => binding.command !== commandId);
313
- return [...without, { command: commandId, key }];
314
- });
315
- }, []);
453
+ const setCommandKeybindingOverride = useCallback(
454
+ (commandId: string, key: string) => {
455
+ setKeybindingState((current) => {
456
+ const currentOverrides = isKeybindingStateCurrent(
457
+ current,
458
+ initialKeybindingOverrides,
459
+ shouldPersistKeybindingOverrides,
460
+ keybindingOverridesStorage,
461
+ keybindingOverridesStorageKey,
462
+ )
463
+ ? current.overrides
464
+ : resolvedInitialKeybindingOverrides;
465
+ const without = currentOverrides.filter((binding) => binding.command !== commandId);
466
+ return {
467
+ initialOverrides: initialKeybindingOverrides,
468
+ overrides: [...without, { command: commandId, key }],
469
+ shouldPersist: shouldPersistKeybindingOverrides,
470
+ storage: keybindingOverridesStorage,
471
+ storageKey: keybindingOverridesStorageKey,
472
+ writeEligible: true,
473
+ };
474
+ });
475
+ },
476
+ [
477
+ initialKeybindingOverrides,
478
+ keybindingOverridesStorage,
479
+ keybindingOverridesStorageKey,
480
+ resolvedInitialKeybindingOverrides,
481
+ shouldPersistKeybindingOverrides,
482
+ ],
483
+ );
316
484
 
317
- const resetCommandKeybindingOverride = useCallback((commandId: string) => {
318
- setKeybindingOverridesState((current) =>
319
- current.filter((binding) => binding.command !== commandId),
320
- );
321
- }, []);
485
+ const resetCommandKeybindingOverride = useCallback(
486
+ (commandId: string) => {
487
+ setKeybindingState((current) => {
488
+ const currentOverrides = isKeybindingStateCurrent(
489
+ current,
490
+ initialKeybindingOverrides,
491
+ shouldPersistKeybindingOverrides,
492
+ keybindingOverridesStorage,
493
+ keybindingOverridesStorageKey,
494
+ )
495
+ ? current.overrides
496
+ : resolvedInitialKeybindingOverrides;
497
+ return {
498
+ initialOverrides: initialKeybindingOverrides,
499
+ overrides: currentOverrides.filter((binding) => binding.command !== commandId),
500
+ shouldPersist: shouldPersistKeybindingOverrides,
501
+ storage: keybindingOverridesStorage,
502
+ storageKey: keybindingOverridesStorageKey,
503
+ writeEligible: true,
504
+ };
505
+ });
506
+ },
507
+ [
508
+ initialKeybindingOverrides,
509
+ keybindingOverridesStorage,
510
+ keybindingOverridesStorageKey,
511
+ resolvedInitialKeybindingOverrides,
512
+ shouldPersistKeybindingOverrides,
513
+ ],
514
+ );
322
515
 
323
516
  useEffect(() => {
324
- onKeybindingOverridesChange?.(keybindingOverrides);
325
- if (!shouldPersistKeybindingOverrides) {
517
+ if (!keybindingStateIsCurrent) {
326
518
  return;
327
519
  }
328
520
 
329
- writePersistedKeybindingOverrides(
330
- keybindingOverrides,
331
- keybindingOverridesStorageKey,
332
- keybindingOverridesStorage,
521
+ onKeybindingOverridesChange?.(keybindingState.overrides);
522
+ if (!shouldPersistKeybindingOverrides || !keybindingState.writeEligible) {
523
+ return;
524
+ }
525
+
526
+ reportPersistenceWriteResult(
527
+ writePersistedKeybindingOverridesResult(
528
+ keybindingState.overrides,
529
+ keybindingOverridesStorageKey,
530
+ keybindingOverridesStorage,
531
+ ),
532
+ diagnosticHandlerRef,
333
533
  );
334
534
  }, [
335
- keybindingOverrides,
535
+ diagnosticHandlerRef,
536
+ keybindingState,
537
+ keybindingStateIsCurrent,
336
538
  keybindingOverridesStorage,
337
539
  keybindingOverridesStorageKey,
338
540
  onKeybindingOverridesChange,
339
541
  shouldPersistKeybindingOverrides,
340
542
  ]);
341
543
 
342
- const resolvedInitialLocalPreferences = useMemo(
544
+ const resolvedInitialLocalPreferencesResult = useMemo(
343
545
  () =>
344
546
  shouldPersistLocalPreferences
345
- ? readPersistedLocalPreferences(localPreferenceStorageKey, localPreferenceStorage)
346
- : {},
547
+ ? readPersistedLocalPreferencesResult(localPreferenceStorageKey, localPreferenceStorage)
548
+ : { value: {} },
347
549
  [localPreferenceStorage, localPreferenceStorageKey, shouldPersistLocalPreferences],
348
550
  );
551
+ const resolvedInitialLocalPreferences = resolvedInitialLocalPreferencesResult.value;
552
+ const installedExtensionsReadResult = useMemo(
553
+ () => loadInstalledExtensionsResult(installedExtensionsStorageKey, installedExtensionsStorage),
554
+ [installedExtensionsStorage, installedExtensionsStorageKey],
555
+ );
556
+ const installedExtensionRecords = installedExtensionsReadResult.value;
557
+
558
+ useReportPersistenceReadDiagnostic(
559
+ resolvedInitialLayoutResult.diagnostic,
560
+ [initialLayout, layoutStorage, layoutStorageKey, shouldPersistLayout],
561
+ diagnosticHandlerRef,
562
+ );
563
+ useReportPersistenceReadDiagnostic(
564
+ resolvedInitialEditorStateResult.diagnostic,
565
+ [initialEditorState, editorStateStorage, editorStateStorageKey, shouldPersistEditorState],
566
+ diagnosticHandlerRef,
567
+ );
568
+ useReportPersistenceReadDiagnostic(
569
+ resolvedInitialKeybindingOverridesResult.diagnostic,
570
+ [
571
+ initialKeybindingOverrides,
572
+ keybindingOverridesStorage,
573
+ keybindingOverridesStorageKey,
574
+ shouldPersistKeybindingOverrides,
575
+ ],
576
+ diagnosticHandlerRef,
577
+ );
578
+ useReportPersistenceReadDiagnostic(
579
+ resolvedInitialLocalPreferencesResult.diagnostic,
580
+ [localPreferenceStorage, localPreferenceStorageKey, shouldPersistLocalPreferences],
581
+ diagnosticHandlerRef,
582
+ );
583
+ useReportPersistenceReadDiagnostic(
584
+ installedExtensionsReadResult.diagnostic,
585
+ [installedExtensionsStorage, installedExtensionsStorageKey],
586
+ diagnosticHandlerRef,
587
+ );
349
588
 
350
589
  const services = useMemo<WorkbenchProviderServices>(() => {
351
590
  const extensionRegistry = new ExtensionRegistry();
@@ -366,10 +605,7 @@ export function WorkbenchProvider({
366
605
  initialState: resolvedInitialEditorState,
367
606
  resolveEditorResource: workspaceHostPort?.resolveResource?.bind(workspaceHostPort),
368
607
  });
369
- const installedRecords = loadInstalledExtensions(
370
- installedExtensionsStorageKey,
371
- installedExtensionsStorage,
372
- );
608
+ const installedRecords = installedExtensionRecords;
373
609
  const baseExtensionsConfig =
374
610
  extensionsConfig ??
375
611
  ({
@@ -396,7 +632,26 @@ export function WorkbenchProvider({
396
632
  console.warn(`[workbench-kit] ${diagnostic.message}`);
397
633
  }
398
634
  }
399
- const extensionDisposables = extensionRegistry.registerExtensions(integrity.accepted);
635
+ const extensionRegistrations = extensionRegistry.registerExtensions(integrity.accepted);
636
+ const availableIntegrity = verifyWorkbenchExtensionsAgainstLock(
637
+ resolvedAvailableExtensions,
638
+ extensionsLock,
639
+ extensionIntegrityMode,
640
+ );
641
+ const extensionEnablement = new ExtensionEnablementController({
642
+ availableExtensions: resolvedAvailableExtensions,
643
+ initialEnabledExtensions: integrity.accepted,
644
+ initialInstalledRecords: installedRecords,
645
+ installedExtensionsStorage,
646
+ installedExtensionsStorageKey,
647
+ integrityAcceptedExtensionIds: new Set(
648
+ availableIntegrity.accepted.map((description) => description.manifest.id),
649
+ ),
650
+ onPersistenceDiagnostic: (diagnostic) =>
651
+ reportPersistenceDiagnostic(diagnostic, diagnosticHandlerRef),
652
+ registrationLifetime: extensionRegistrations,
653
+ registry: extensionRegistry,
654
+ });
400
655
  const hostThemeDisposables = registerHostWorkbenchThemes(extensionRegistry.themes, hostThemes);
401
656
  const editorServiceCapabilityDisposable = extensionRegistry.capabilityRegistry.register({
402
657
  id: WORKBENCH_EDITOR_SERVICE_CAPABILITY_ID,
@@ -443,7 +698,7 @@ export function WorkbenchProvider({
443
698
  editorServiceCapabilityDisposable.dispose();
444
699
  workspaceHostCapabilityDisposable?.dispose();
445
700
  hostThemeDisposables.dispose();
446
- extensionDisposables.dispose();
701
+ extensionEnablement.dispose();
447
702
  if (!workspaceHostCapabilityDisposable) {
448
703
  workspaceHostPort?.dispose?.();
449
704
  }
@@ -460,6 +715,7 @@ export function WorkbenchProvider({
460
715
  },
461
716
  editorDocumentViewProviders,
462
717
  editorService,
718
+ extensionEnablement,
463
719
  extensionRegistry,
464
720
  layoutService,
465
721
  missingExtensionIds: [
@@ -482,12 +738,14 @@ export function WorkbenchProvider({
482
738
  initialWorkspaceSettings,
483
739
  installedExtensionsStorage,
484
740
  installedExtensionsStorageKey,
741
+ installedExtensionRecords,
485
742
  resolvedInitialEditorState,
486
743
  resolvedInitialLayout,
487
744
  resolvedInitialLocalPreferences,
488
745
  userCommands,
489
746
  viewHostFactories,
490
747
  workspaceHostPort,
748
+ diagnosticHandlerRef,
491
749
  ]);
492
750
 
493
751
  useEffect(() => {
@@ -500,13 +758,22 @@ export function WorkbenchProvider({
500
758
  return;
501
759
  }
502
760
 
503
- writePersistedWorkbenchLayout(state, layoutStorageKey, layoutStorage);
761
+ reportPersistenceWriteResult(
762
+ writePersistedWorkbenchLayoutResult(state, layoutStorageKey, layoutStorage),
763
+ diagnosticHandlerRef,
764
+ );
504
765
  });
505
766
 
506
767
  return () => {
507
768
  disposable.dispose();
508
769
  };
509
- }, [layoutStorage, layoutStorageKey, services.layoutService, shouldPersistLayout]);
770
+ }, [
771
+ diagnosticHandlerRef,
772
+ layoutStorage,
773
+ layoutStorageKey,
774
+ services.layoutService,
775
+ shouldPersistLayout,
776
+ ]);
510
777
 
511
778
  useEffect(() => {
512
779
  if (!shouldPersistEditorState) {
@@ -514,13 +781,22 @@ export function WorkbenchProvider({
514
781
  }
515
782
 
516
783
  const disposable = services.editorService.onDidChangeEditors(({ state }) => {
517
- writePersistedEditorState(state, editorStateStorageKey, editorStateStorage);
784
+ reportPersistenceWriteResult(
785
+ writePersistedEditorStateResult(state, editorStateStorageKey, editorStateStorage),
786
+ diagnosticHandlerRef,
787
+ );
518
788
  });
519
789
 
520
790
  return () => {
521
791
  disposable.dispose();
522
792
  };
523
- }, [editorStateStorage, editorStateStorageKey, services.editorService, shouldPersistEditorState]);
793
+ }, [
794
+ diagnosticHandlerRef,
795
+ editorStateStorage,
796
+ editorStateStorageKey,
797
+ services.editorService,
798
+ shouldPersistEditorState,
799
+ ]);
524
800
 
525
801
  useEffect(() => {
526
802
  if (!shouldPersistLocalPreferences) {
@@ -532,10 +808,13 @@ export function WorkbenchProvider({
532
808
  return;
533
809
  }
534
810
 
535
- writePersistedLocalPreferences(
536
- services.preferenceService.getScopedValues('local'),
537
- localPreferenceStorageKey,
538
- localPreferenceStorage,
811
+ reportPersistenceWriteResult(
812
+ writePersistedLocalPreferencesResult(
813
+ services.preferenceService.getScopedValues('local'),
814
+ localPreferenceStorageKey,
815
+ localPreferenceStorage,
816
+ ),
817
+ diagnosticHandlerRef,
539
818
  );
540
819
  });
541
820
 
@@ -543,6 +822,7 @@ export function WorkbenchProvider({
543
822
  disposable.dispose();
544
823
  };
545
824
  }, [
825
+ diagnosticHandlerRef,
546
826
  localPreferenceStorage,
547
827
  localPreferenceStorageKey,
548
828
  services.preferenceService,
@@ -573,7 +853,10 @@ export function WorkbenchProvider({
573
853
  const value = useMemo<WorkbenchContextValue>(
574
854
  () => ({
575
855
  activateCommand: (commandId) => services.extensionRegistry.activateCommand(commandId),
856
+ activities: services.extensionRegistry.activities,
576
857
  availableExtensions: services.availableExtensions,
858
+ commands: services.extensionRegistry.commands,
859
+ configurations: services.extensionRegistry.configurations,
577
860
  contextKeyService,
578
861
  editorDocumentViewProviders: services.editorDocumentViewProviders,
579
862
  editorService: services.editorService,
@@ -592,15 +875,32 @@ export function WorkbenchProvider({
592
875
  }
593
876
  return result;
594
877
  },
595
- extensionRegistry: services.extensionRegistry,
878
+ extensionActivation: createWorkbenchExtensionActivationAccess(
879
+ services.extensionRegistry,
880
+ services.waitForExtensionStartup,
881
+ ),
882
+ extensionActivationState: createWorkbenchExtensionActivationStateReader(
883
+ services.extensionRegistry,
884
+ ),
885
+ extensionCatalog: createWorkbenchExtensionCatalogReader(services.extensionRegistry),
596
886
  installedExtensionsStorage,
597
887
  installedExtensionsStorageKey,
888
+ keybindings: services.extensionRegistry.keybindings,
598
889
  keybindingOverrides,
599
890
  layoutService: services.layoutService,
891
+ localizations: services.extensionRegistry.localizations,
892
+ menus: services.extensionRegistry.menus,
600
893
  missingExtensionIds: services.missingExtensionIds,
601
894
  preferenceService: services.preferenceService,
602
895
  resetCommandKeybindingOverride,
603
896
  setCommandKeybindingOverride,
897
+ settingsCapabilityPublisher: createWorkbenchSettingsCapabilityPublisher(
898
+ services.extensionRegistry.capabilityRegistry,
899
+ ),
900
+ statusBar: services.extensionRegistry.statusBar,
901
+ themes: services.extensionRegistry.themes,
902
+ viewHostFactories: services.extensionRegistry.viewHostFactories,
903
+ views: services.extensionRegistry.views,
604
904
  waitForExtensionStartup: services.waitForExtensionStartup,
605
905
  workspaceHostPort: services.workspaceHostPort,
606
906
  }),
@@ -616,10 +916,14 @@ export function WorkbenchProvider({
616
916
  );
617
917
 
618
918
  return (
619
- <WorkbenchContext.Provider value={value}>
620
- <EditorWorkspaceReconciler />
621
- {children}
622
- </WorkbenchContext.Provider>
919
+ <WorkbenchPersistenceDiagnosticContext.Provider value={onPersistenceDiagnostic}>
920
+ <WorkbenchContext.Provider value={value}>
921
+ <ExtensionEnablementContext.Provider value={services.extensionEnablement}>
922
+ <EditorWorkspaceReconciler />
923
+ {children}
924
+ </ExtensionEnablementContext.Provider>
925
+ </WorkbenchContext.Provider>
926
+ </WorkbenchPersistenceDiagnosticContext.Provider>
623
927
  );
624
928
  }
625
929