@workbench-kit/shell-react 0.0.2-prototype.0.2.33 → 0.0.2-prototype.0.2.35

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 (51) 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 +58 -2
  23. package/src/field-remap/convert-palette.tsx +151 -6
  24. package/src/field-remap/demo.tsx +31 -2
  25. package/src/field-remap/flow.tsx +57 -13
  26. package/src/field-remap/history.ts +99 -0
  27. package/src/field-remap/index.ts +9 -1
  28. package/src/field-remap/panel.tsx +371 -97
  29. package/src/field-remap/preview-controller.ts +122 -0
  30. package/src/field-remap/preview.tsx +171 -0
  31. package/src/field-remap/view.css +72 -0
  32. package/src/index.ts +16 -1
  33. package/src/management/keybinding-overrides-storage.ts +28 -0
  34. package/src/management/preference-settings-storage.ts +28 -0
  35. package/src/management/settings.tsx +2 -0
  36. package/src/management/use-command-management.ts +31 -26
  37. package/src/management/use-keybinding-management.ts +25 -12
  38. package/src/shell/focused-extension-services.ts +138 -0
  39. package/src/shell/host-shell.tsx +13 -10
  40. package/src/shell/persistence-diagnostic-context.ts +11 -0
  41. package/src/shell/provider.tsx +373 -69
  42. package/src/shell/settings.tsx +25 -16
  43. package/src/shell/shell.tsx +119 -78
  44. package/src/shell/view-host.tsx +23 -22
  45. package/src/storage/local-json-storage.ts +43 -29
  46. package/src/storage/persistence-diagnostics.ts +72 -0
  47. package/src/workbench/appearance-storage.ts +28 -0
  48. package/src/workbench/command-host.tsx +19 -22
  49. package/src/workbench/command-palette.ts +14 -13
  50. package/src/workbench/layout-storage.ts +52 -5
  51. package/src/workbench/use-persisted-appearance.ts +38 -12
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo, useReducer, useState } from 'react';
2
- import type { ExtensionCommandFeatureSpec, ExtensionRegistry } from '@workbench-kit/workbench-core';
2
+ import type { ExtensionCommandFeatureSpec } from '@workbench-kit/workbench-core';
3
3
  import {
4
4
  buildCommandManagementGroups,
5
5
  countCommandManagementEntries,
@@ -8,14 +8,15 @@ import {
8
8
  import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench';
9
9
 
10
10
  import { useContextKeyRevision } from '../commands/use-context-key-revision.js';
11
- import { useWorkbench } from '../shell/provider.js';
11
+ import { useWorkbench, type WorkbenchContextValue } from '../shell/provider.js';
12
12
  import {
13
13
  collectExtensionCommandFeaturesById,
14
14
  resolveShellCommandActivities,
15
15
  } from '../workbench/command-palette.js';
16
16
 
17
17
  export function useCommandManagementModel() {
18
- const { contextKeyService, executeCommand, extensionRegistry } = useWorkbench();
18
+ const workbench = useWorkbench();
19
+ const { commands, contextKeyService, executeCommand } = workbench;
19
20
  const contextKeyRevision = useContextKeyRevision(contextKeyService);
20
21
  const contextKeySnapshot = useMemo(
21
22
  () => contextKeyService.createSnapshot(),
@@ -25,18 +26,18 @@ export function useCommandManagementModel() {
25
26
  const [refreshToken, refreshRegistry] = useReducer((count: number) => count + 1, 0);
26
27
 
27
28
  useEffect(() => {
28
- const commandDisposable = extensionRegistry.commands.onDidChangeCommands(() => {
29
+ const commandDisposable = commands.onDidChangeCommands(() => {
29
30
  refreshRegistry();
30
31
  });
31
32
 
32
33
  return () => {
33
34
  commandDisposable.dispose();
34
35
  };
35
- }, [extensionRegistry]);
36
+ }, [commands]);
36
37
 
37
38
  const groups = useMemo(
38
- () => buildCommandManagementModelGroups(extensionRegistry, refreshToken, contextKeySnapshot),
39
- [contextKeySnapshot, extensionRegistry, refreshToken],
39
+ () => buildCommandManagementModelGroups(workbench, refreshToken, contextKeySnapshot),
40
+ [contextKeySnapshot, refreshToken, workbench],
40
41
  );
41
42
 
42
43
  const totalCount = countCommandManagementEntries(groups);
@@ -75,12 +76,12 @@ export function useCommandManagementModel() {
75
76
  }
76
77
 
77
78
  export function buildCommandManagementModelGroups(
78
- extensionRegistry: ExtensionRegistry,
79
+ access: CommandManagementAccess,
79
80
  _refreshToken = 0,
80
81
  contextKeys?: object | undefined,
81
82
  ) {
82
83
  const managedShellCommands = createWorkbenchShellCommands({
83
- activities: resolveShellCommandActivities(extensionRegistry),
84
+ activities: resolveShellCommandActivities(access),
84
85
  includeSettings: true,
85
86
  includeSidebarToggle: true,
86
87
  });
@@ -89,26 +90,25 @@ export function buildCommandManagementModelGroups(
89
90
  contextKeys === undefined
90
91
  ? managedShellCommands
91
92
  : createWorkbenchShellCommands({
92
- activities: resolveShellCommandActivities(extensionRegistry, contextKeys),
93
+ activities: resolveShellCommandActivities(access, contextKeys),
93
94
  includeSettings: true,
94
95
  includeSidebarToggle: true,
95
96
  });
96
- const commandFeaturesById = collectExtensionCommandFeaturesById(extensionRegistry);
97
+ const commandFeaturesById = collectExtensionCommandFeaturesById(
98
+ access.extensionCatalog.getFeatureSpecs(),
99
+ );
97
100
 
98
101
  return buildCommandManagementGroups({
99
102
  extensionCommands: collectExtensionCommandEntries(
100
- extensionRegistry,
103
+ access,
101
104
  managedShellCommandIds,
102
105
  commandFeaturesById,
103
106
  ),
104
- keybindingsByCommandId: collectKeybindingsByCommandId(extensionRegistry),
105
- menuSurfacesByCommandId: collectMenuSurfacesByCommandId(extensionRegistry),
107
+ keybindingsByCommandId: collectKeybindingsByCommandId(access),
108
+ menuSurfacesByCommandId: collectMenuSurfacesByCommandId(access),
106
109
  shellCommands: shellCommands.map((command) => ({
107
110
  category: command.category ?? 'Workbench',
108
- handler:
109
- extensionRegistry.commands.getCommand(command.id)?.handler ??
110
- command.handler ??
111
- command.run,
111
+ handler: access.commands.getCommand(command.id)?.handler ?? command.handler ?? command.run,
112
112
  id: command.id,
113
113
  label: typeof command.label === 'string' ? command.label : (command.title ?? command.id),
114
114
  })),
@@ -116,7 +116,7 @@ export function buildCommandManagementModelGroups(
116
116
  }
117
117
 
118
118
  function collectExtensionCommandEntries(
119
- extensionRegistry: ExtensionRegistry,
119
+ access: CommandManagementAccess,
120
120
  skippedCommandIds: ReadonlySet<string>,
121
121
  commandFeaturesById: ReadonlyMap<string, ExtensionCommandFeatureSpec>,
122
122
  ) {
@@ -131,11 +131,11 @@ function collectExtensionCommandEntries(
131
131
  }> = [];
132
132
  const seen = new Set<string>();
133
133
 
134
- for (const feature of extensionRegistry.getFeatureSpecs()) {
134
+ for (const feature of access.extensionCatalog.getFeatureSpecs()) {
135
135
  const extensionLabel = feature.displayName;
136
136
 
137
137
  for (const contribution of feature.commands) {
138
- const command = extensionRegistry.commands.getCommand(contribution.id);
138
+ const command = access.commands.getCommand(contribution.id);
139
139
  if (!command || seen.has(contribution.id) || skippedCommandIds.has(contribution.id)) {
140
140
  continue;
141
141
  }
@@ -153,7 +153,7 @@ function collectExtensionCommandEntries(
153
153
  }
154
154
  }
155
155
 
156
- for (const command of extensionRegistry.commands.getCommands()) {
156
+ for (const command of access.commands.getCommands()) {
157
157
  if (seen.has(command.id) || skippedCommandIds.has(command.id)) {
158
158
  continue;
159
159
  }
@@ -172,10 +172,10 @@ function collectExtensionCommandEntries(
172
172
  return entries;
173
173
  }
174
174
 
175
- function collectKeybindingsByCommandId(extensionRegistry: ExtensionRegistry) {
175
+ function collectKeybindingsByCommandId(access: CommandManagementAccess) {
176
176
  const keybindingsByCommandId: Record<string, string> = {};
177
177
 
178
- for (const keybinding of extensionRegistry.keybindings.getKeybindings()) {
178
+ for (const keybinding of access.keybindings.getKeybindings()) {
179
179
  if (!keybindingsByCommandId[keybinding.command]) {
180
180
  keybindingsByCommandId[keybinding.command] = keybinding.key;
181
181
  }
@@ -184,10 +184,10 @@ function collectKeybindingsByCommandId(extensionRegistry: ExtensionRegistry) {
184
184
  return keybindingsByCommandId;
185
185
  }
186
186
 
187
- function collectMenuSurfacesByCommandId(extensionRegistry: ExtensionRegistry) {
187
+ function collectMenuSurfacesByCommandId(access: CommandManagementAccess) {
188
188
  const menuSurfacesByCommandId = new Map<string, Set<string>>();
189
189
 
190
- for (const menuItem of extensionRegistry.menus.getMenuItems()) {
190
+ for (const menuItem of access.menus.getMenuItems()) {
191
191
  if (!menuItem.menu || !menuItem.command) {
192
192
  continue;
193
193
  }
@@ -204,3 +204,8 @@ function collectMenuSurfacesByCommandId(extensionRegistry: ExtensionRegistry) {
204
204
  ]),
205
205
  );
206
206
  }
207
+
208
+ type CommandManagementAccess = Pick<
209
+ WorkbenchContextValue,
210
+ 'activities' | 'commands' | 'extensionCatalog' | 'keybindings' | 'menus' | 'views'
211
+ >;
@@ -1,32 +1,40 @@
1
1
  import { useMemo } from 'react';
2
2
  import { buildKeybindingManagementEntries } from '@workbench-kit/platform';
3
3
  import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench';
4
- import type { ExtensionRegistry } from '@workbench-kit/workbench-core';
5
4
 
6
- import { useWorkbench } from '../shell/provider.js';
5
+ import { useWorkbench, type WorkbenchContextValue } from '../shell/provider.js';
7
6
  import { resolveShellCommandActivities } from '../workbench/command-palette.js';
8
7
 
9
8
  export function useKeybindingManagementModel() {
10
9
  const {
11
- extensionRegistry,
10
+ activities,
11
+ commands,
12
+ extensionCatalog,
13
+ keybindings,
12
14
  keybindingOverrides,
13
15
  resetCommandKeybindingOverride,
14
16
  setCommandKeybindingOverride,
17
+ views,
15
18
  } = useWorkbench();
16
19
 
17
20
  const defaults = useMemo(
18
- () => extensionRegistry.keybindings.getKeybindings(),
19
- [extensionRegistry, keybindingOverrides.length],
21
+ () => keybindings.getKeybindings(),
22
+ [keybindingOverrides.length, keybindings],
20
23
  );
21
24
 
22
25
  const entries = useMemo(
23
26
  () =>
24
27
  buildKeybindingManagementEntries({
25
- commands: collectKeybindingManagementCommands(extensionRegistry),
28
+ commands: collectKeybindingManagementCommands({
29
+ activities,
30
+ commands,
31
+ extensionCatalog,
32
+ views,
33
+ }),
26
34
  defaults,
27
35
  overrides: keybindingOverrides,
28
36
  }),
29
- [defaults, extensionRegistry, keybindingOverrides],
37
+ [activities, commands, defaults, extensionCatalog, keybindingOverrides, views],
30
38
  );
31
39
 
32
40
  const overrideCount = keybindingOverrides.length;
@@ -49,7 +57,7 @@ export function useKeybindingManagementModel() {
49
57
  };
50
58
  }
51
59
 
52
- function collectKeybindingManagementCommands(extensionRegistry: ExtensionRegistry) {
60
+ function collectKeybindingManagementCommands(access: KeybindingManagementAccess) {
53
61
  const commands: Array<{
54
62
  category?: string | undefined;
55
63
  id: string;
@@ -58,17 +66,17 @@ function collectKeybindingManagementCommands(extensionRegistry: ExtensionRegistr
58
66
  }> = [];
59
67
  const seen = new Set<string>();
60
68
  const shellCommands = createWorkbenchShellCommands({
61
- activities: resolveShellCommandActivities(extensionRegistry),
69
+ activities: resolveShellCommandActivities(access),
62
70
  includeSettings: true,
63
71
  includeSidebarToggle: true,
64
72
  });
65
73
  const shellCommandIds = new Set(shellCommands.map((command) => command.id));
66
74
 
67
- for (const extension of extensionRegistry.getExtensions()) {
75
+ for (const extension of access.extensionCatalog.getExtensions()) {
68
76
  const extensionLabel = extension.manifest.displayName ?? extension.manifest.id;
69
77
 
70
78
  for (const contribution of extension.manifest.contributes?.commands ?? []) {
71
- const command = extensionRegistry.commands.getCommand(contribution.command);
79
+ const command = access.commands.getCommand(contribution.command);
72
80
  if (!command || seen.has(contribution.command) || shellCommandIds.has(contribution.command)) {
73
81
  continue;
74
82
  }
@@ -83,7 +91,7 @@ function collectKeybindingManagementCommands(extensionRegistry: ExtensionRegistr
83
91
  }
84
92
  }
85
93
 
86
- for (const command of extensionRegistry.commands.getCommands()) {
94
+ for (const command of access.commands.getCommands()) {
87
95
  if (seen.has(command.id) || shellCommandIds.has(command.id)) {
88
96
  continue;
89
97
  }
@@ -119,3 +127,8 @@ function collectKeybindingManagementCommands(extensionRegistry: ExtensionRegistr
119
127
 
120
128
  return commands;
121
129
  }
130
+
131
+ type KeybindingManagementAccess = Pick<
132
+ WorkbenchContextValue,
133
+ 'activities' | 'commands' | 'extensionCatalog' | 'views'
134
+ >;
@@ -0,0 +1,138 @@
1
+ import {
2
+ WORKBENCH_SETTINGS_CAPABILITY_ID,
3
+ type ExtensionDependencyDiagnostic,
4
+ type ExtensionFeatureInspection,
5
+ type ExtensionFeatureSpec,
6
+ type WorkbenchExtensionDescription,
7
+ type WorkbenchSettingsCapability,
8
+ } from '@workbench-kit/workbench-core';
9
+
10
+ interface DisposableLike {
11
+ dispose(): void;
12
+ }
13
+
14
+ interface ExtensionActivationRegistry {
15
+ activateView(viewId: string): Promise<readonly { readonly extensionId: string }[]>;
16
+ getActiveExtensions(): readonly { readonly extensionId: string }[];
17
+ onDidActivateExtension(listener: () => void): DisposableLike;
18
+ onDidDeactivateExtension(listener: () => void): DisposableLike;
19
+ }
20
+
21
+ interface ExtensionCatalogRegistry {
22
+ readonly capabilityRegistry: {
23
+ listProviderIds(): readonly string[];
24
+ };
25
+ getDependencyDiagnostics(): readonly ExtensionDependencyDiagnostic[];
26
+ getExtension(extensionId: string): WorkbenchExtensionDescription | undefined;
27
+ getExtensions(): readonly WorkbenchExtensionDescription[];
28
+ getFeatureInspections(): readonly ExtensionFeatureInspection[];
29
+ getFeatureSpecs(): readonly ExtensionFeatureSpec[];
30
+ }
31
+
32
+ interface SettingsCapabilityRegistry {
33
+ has(capabilityId: string): boolean;
34
+ register(registration: {
35
+ readonly get: () => WorkbenchSettingsCapability;
36
+ readonly id: string;
37
+ }): DisposableLike;
38
+ }
39
+
40
+ export interface WorkbenchExtensionActivationAccess {
41
+ activateView(viewId: string): Promise<readonly { readonly extensionId: string }[]>;
42
+ onDidActivateExtension(listener: () => void): DisposableLike;
43
+ waitForStartup(): Promise<void>;
44
+ }
45
+
46
+ export interface WorkbenchExtensionActivationStateReader {
47
+ getActiveExtensions(): readonly { readonly extensionId: string }[];
48
+ onDidChangeActiveExtensions(listener: () => void): DisposableLike;
49
+ }
50
+
51
+ export interface WorkbenchExtensionCatalogReader {
52
+ getDependencyDiagnostics(): readonly ExtensionDependencyDiagnostic[];
53
+ getExtension(extensionId: string): WorkbenchExtensionDescription | undefined;
54
+ getExtensions(): readonly WorkbenchExtensionDescription[];
55
+ getFeatureInspections(): readonly ExtensionFeatureInspection[];
56
+ getFeatureSpecs(): readonly ExtensionFeatureSpec[];
57
+ listCapabilityProviderIds(): readonly string[];
58
+ }
59
+
60
+ export type WorkbenchSettingsCapabilityPublication =
61
+ | { readonly kind: 'already-registered' }
62
+ | { readonly disposable: DisposableLike; readonly kind: 'registered' };
63
+
64
+ export interface WorkbenchSettingsCapabilityPublisher {
65
+ publishSettingsCapability(
66
+ capability: WorkbenchSettingsCapability,
67
+ ): WorkbenchSettingsCapabilityPublication;
68
+ }
69
+
70
+ export function createWorkbenchExtensionActivationAccess(
71
+ registry: ExtensionActivationRegistry,
72
+ waitForStartup: () => Promise<void>,
73
+ ): WorkbenchExtensionActivationAccess {
74
+ return {
75
+ activateView: (viewId) => registry.activateView(viewId),
76
+ onDidActivateExtension: (listener) => registry.onDidActivateExtension(listener),
77
+ waitForStartup,
78
+ };
79
+ }
80
+
81
+ export function createWorkbenchExtensionActivationStateReader(
82
+ registry: ExtensionActivationRegistry,
83
+ ): WorkbenchExtensionActivationStateReader {
84
+ return {
85
+ getActiveExtensions: () =>
86
+ registry.getActiveExtensions().map(({ extensionId }) => ({ extensionId })),
87
+ onDidChangeActiveExtensions: (listener) => {
88
+ const activation = registry.onDidActivateExtension(listener);
89
+ const deactivation = registry.onDidDeactivateExtension(listener);
90
+ return {
91
+ dispose() {
92
+ deactivation.dispose();
93
+ activation.dispose();
94
+ },
95
+ };
96
+ },
97
+ };
98
+ }
99
+
100
+ export function createWorkbenchExtensionCatalogReader(
101
+ registry: ExtensionCatalogRegistry,
102
+ ): WorkbenchExtensionCatalogReader {
103
+ return {
104
+ getDependencyDiagnostics: () => registry.getDependencyDiagnostics(),
105
+ getExtension: (extensionId) => registry.getExtension(extensionId),
106
+ getExtensions: () => registry.getExtensions(),
107
+ getFeatureInspections: () => registry.getFeatureInspections(),
108
+ getFeatureSpecs: () => registry.getFeatureSpecs(),
109
+ listCapabilityProviderIds: () => registry.capabilityRegistry.listProviderIds(),
110
+ };
111
+ }
112
+
113
+ export function createWorkbenchSettingsCapabilityPublisher(
114
+ registry: SettingsCapabilityRegistry,
115
+ ): WorkbenchSettingsCapabilityPublisher {
116
+ return {
117
+ publishSettingsCapability: (capability) => {
118
+ if (registry.has(WORKBENCH_SETTINGS_CAPABILITY_ID)) {
119
+ return { kind: 'already-registered' };
120
+ }
121
+
122
+ try {
123
+ return {
124
+ disposable: registry.register({
125
+ id: WORKBENCH_SETTINGS_CAPABILITY_ID,
126
+ get: () => capability,
127
+ }),
128
+ kind: 'registered',
129
+ };
130
+ } catch (error) {
131
+ if (registry.has(WORKBENCH_SETTINGS_CAPABILITY_ID)) {
132
+ return { kind: 'already-registered' };
133
+ }
134
+ throw error;
135
+ }
136
+ },
137
+ };
138
+ }
@@ -59,7 +59,14 @@ export function WorkbenchHostShell({
59
59
  themePreset,
60
60
  titleBar,
61
61
  }: WorkbenchHostShellProps) {
62
- const { contextKeyService, executeCommand, extensionRegistry, layoutService } = useWorkbench();
62
+ const {
63
+ activities: activityRegistry,
64
+ contextKeyService,
65
+ executeCommand,
66
+ layoutService,
67
+ statusBar,
68
+ views,
69
+ } = useWorkbench();
63
70
  const contextKeyRevision = useContextKeyRevision(contextKeyService);
64
71
  const [, forceRender] = useReducer((count: number) => count + 1, 0);
65
72
  const rerender = useCallback(() => forceRender(), []);
@@ -69,20 +76,16 @@ export function WorkbenchHostShell({
69
76
  );
70
77
  const layout = layoutService.getState();
71
78
  const activities = useMemo(
72
- () =>
73
- filterActivitiesByWhenClause(
74
- extensionRegistry.activities.getActivities(),
75
- contextKeySnapshot,
76
- ),
77
- [contextKeySnapshot, extensionRegistry],
79
+ () => filterActivitiesByWhenClause(activityRegistry.getActivities(), contextKeySnapshot),
80
+ [activityRegistry, contextKeySnapshot],
78
81
  );
79
82
  const activityItems = filterActivityBarItems(
80
83
  sortActivityBarItems(
81
84
  createWorkbenchShellActivityItems({
82
85
  activeViewContainerId: layout.sideBar.activeViewContainer,
83
86
  activities,
84
- viewContainers: extensionRegistry.views.getViewContainers('activitybar'),
85
- views: extensionRegistry.views.getViews(),
87
+ viewContainers: views.getViewContainers('activitybar'),
88
+ views: views.getViews(),
86
89
  }),
87
90
  layout.activityBar.itemOrder,
88
91
  ),
@@ -136,7 +139,7 @@ export function WorkbenchHostShell({
136
139
  }
137
140
  compactStatus={compactStatus}
138
141
  onStatusItemActivate={(item) => {
139
- const contributed = extensionRegistry.statusBar.getStatusBarItem(item.id);
142
+ const contributed = statusBar.getStatusBarItem(item.id);
140
143
  if (contributed?.command) {
141
144
  void executeCommand(contributed.command).catch(() => undefined);
142
145
  return;
@@ -0,0 +1,11 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { WorkbenchPersistenceDiagnosticHandler } from '@workbench-kit/workbench-core';
3
+
4
+ export const WorkbenchPersistenceDiagnosticContext = createContext<
5
+ WorkbenchPersistenceDiagnosticHandler | undefined
6
+ >(undefined);
7
+
8
+ export function useWorkbenchPersistenceDiagnosticHandler():
9
+ WorkbenchPersistenceDiagnosticHandler | undefined {
10
+ return useContext(WorkbenchPersistenceDiagnosticContext);
11
+ }