@workbench-kit/shell-react 0.0.2-prototype.0.2.6 → 0.0.2-prototype.0.2.8

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 (95) hide show
  1. package/README.md +41 -0
  2. package/package.json +9 -9
  3. package/src/{chat-ai-mock-proposals.ts → chat/ai-mock-proposals.ts} +39 -39
  4. package/src/{chat-command-input.ts → chat/command-input.ts} +52 -52
  5. package/src/{chat-command-policy.ts → chat/command-policy.ts} +54 -54
  6. package/src/{chat-command-surface.tsx → chat/command-surface.tsx} +155 -155
  7. package/src/{use-workbench-chat-command-proposals.ts → chat/use-chat-command-proposals.ts} +194 -194
  8. package/src/{chat-view-data.ts → chat/view-data.ts} +20 -20
  9. package/src/{chat-view.tsx → chat/view.tsx} +220 -220
  10. package/src/{command-inspector-surface.tsx → commands/inspector-surface.tsx} +46 -46
  11. package/src/{use-workbench-command-descriptors.ts → commands/use-command-descriptors.ts} +41 -41
  12. package/src/{use-context-key-revision.ts → commands/use-context-key-revision.ts} +18 -18
  13. package/src/{commands-view-data.ts → commands/view-data.ts} +17 -17
  14. package/src/{commands-view.tsx → commands/view.tsx} +43 -43
  15. package/src/devtools/WorkbenchDevtoolsPanel.tsx +124 -124
  16. package/src/devtools/WorkbenchDevtoolsShell.tsx +17 -17
  17. package/src/devtools/index.ts +11 -11
  18. package/src/devtools/use-workbench-devtools-snapshot.ts +84 -84
  19. package/src/devtools/workbench-devtools-snapshot.ts +140 -140
  20. package/src/devtools/workbench-devtools.css +82 -82
  21. package/src/{editor-area-dnd.ts → editor/area-dnd.ts} +69 -69
  22. package/src/{editor-area-model.ts → editor/area-model.ts} +71 -71
  23. package/src/{editor-area.css → editor/area.css} +454 -454
  24. package/src/{editor-area.tsx → editor/area.tsx} +676 -676
  25. package/src/{editor-host-surface.tsx → editor/host-surface.tsx} +631 -634
  26. package/src/{editor-pane-visibility.ts → editor/pane-visibility.ts} +130 -130
  27. package/src/{editor-resource.ts → editor/resource.ts} +36 -36
  28. package/src/{editor-state-storage.ts → editor/state-storage.ts} +182 -193
  29. package/src/{editor-tab-context-menu.ts → editor/tab-context-menu.ts} +118 -118
  30. package/src/{use-editor.ts → editor/use-editor.ts} +114 -107
  31. package/src/{editor-view-providers.tsx → editor/view-providers.tsx} +552 -552
  32. package/src/{editor-workspace-file-availability.ts → editor/workspace-file-availability.ts} +15 -15
  33. package/src/{editor-workspace-reconcile.tsx → editor/workspace-reconcile.tsx} +31 -28
  34. package/src/{explorer-context-menu.ts → explorer/context-menu.ts} +114 -114
  35. package/src/{createCommandWorkspaceExplorerPort.ts → explorer/create-command-workspace-explorer-port.ts} +86 -86
  36. package/src/{explorer-reveal.ts → explorer/reveal.ts} +112 -112
  37. package/src/{search-view-data.ts → explorer/search-view-data.ts} +15 -15
  38. package/src/{search-view.tsx → explorer/search-view.tsx} +65 -62
  39. package/src/{use-active-workspace-path.ts → explorer/use-active-workspace-path.ts} +15 -15
  40. package/src/{explorer-view-data.ts → explorer/view-data.ts} +58 -58
  41. package/src/{explorer-view.tsx → explorer/view.tsx} +227 -224
  42. package/src/{extension-context-menu.ts → extensions/context-menu.ts} +52 -52
  43. package/src/{extension-management-model.ts → extensions/management-model.ts} +313 -313
  44. package/src/{use-extension-management.ts → extensions/use-extension-management.ts} +241 -193
  45. package/src/{extensions-view-data.ts → extensions/view-data.ts} +19 -19
  46. package/src/{extensions-view.tsx → extensions/view.tsx} +63 -38
  47. package/src/{field-remap-demo.tsx → field-remap/demo.tsx} +18 -18
  48. package/src/{field-remap-editor-surface.tsx → field-remap/editor-surface.tsx} +36 -36
  49. package/src/{field-remap-flow-adapter.ts → field-remap/flow-adapter.ts} +240 -240
  50. package/src/{field-remap-flow.tsx → field-remap/flow.tsx} +369 -369
  51. package/src/{field-remap-graph.tsx → field-remap/graph.tsx} +559 -559
  52. package/src/field-remap/jsonata-transform.ts +166 -0
  53. package/src/{field-remap-panel.tsx → field-remap/panel.tsx} +193 -175
  54. package/src/{field-remap-samples.ts → field-remap/samples.ts} +352 -352
  55. package/src/{table-mapping-adapter.ts → field-remap/table-mapping-adapter.ts} +59 -59
  56. package/src/{field-remap-tree.tsx → field-remap/tree.tsx} +404 -404
  57. package/src/{field-remap-view-data.ts → field-remap/view-data.ts} +16 -16
  58. package/src/{field-remap-view.css → field-remap/view.css} +676 -676
  59. package/src/{field-remap-view.tsx → field-remap/view.tsx} +86 -86
  60. package/src/index.ts +212 -199
  61. package/src/{json-form-source-patch.ts → jdw/json-form-source-patch.ts} +323 -323
  62. package/src/{jdw-lab-view-data.ts → jdw/lab-view-data.ts} +25 -25
  63. package/src/{jdw-lab-view.css → jdw/lab-view.css} +21 -21
  64. package/src/{jdw-lab-view.tsx → jdw/lab-view.tsx} +79 -79
  65. package/src/{jdw-widget-form-view.tsx → jdw/widget-form-view.tsx} +68 -65
  66. package/src/{jdw-widget-preview-view.tsx → jdw/widget-preview-view.tsx} +54 -51
  67. package/src/{keybinding-overrides-storage.ts → management/keybinding-overrides-storage.ts} +49 -57
  68. package/src/{keybinding-management-settings.tsx → management/keybinding-settings.tsx} +16 -16
  69. package/src/{management-palette-commands.ts → management/palette-commands.ts} +38 -38
  70. package/src/{preference-settings-storage.ts → management/preference-settings-storage.ts} +50 -58
  71. package/src/{management-settings-ids.ts → management/settings-ids.ts} +12 -12
  72. package/src/{management-settings.tsx → management/settings.tsx} +96 -75
  73. package/src/{use-command-management.ts → management/use-command-management.ts} +191 -191
  74. package/src/{use-keybinding-management.ts → management/use-keybinding-management.ts} +130 -130
  75. package/src/{shell-model.tsx → shell/model.tsx} +149 -149
  76. package/src/{provider.tsx → shell/provider.tsx} +603 -573
  77. package/src/{shell-secondary-actions.tsx → shell/secondary-actions.tsx} +59 -59
  78. package/src/{shell-settings-constants.ts → shell/settings-constants.ts} +9 -9
  79. package/src/{shell-settings.tsx → shell/settings.tsx} +599 -599
  80. package/src/{shell.tsx → shell/shell.tsx} +680 -649
  81. package/src/{shell-titlebar-layout-controls.tsx → shell/titlebar-layout-controls.tsx} +4 -4
  82. package/src/{shell-view-host.tsx → shell/view-host.tsx} +212 -199
  83. package/src/{workbench-appearance-storage.ts → workbench/appearance-storage.ts} +107 -115
  84. package/src/{workbench-command-host.tsx → workbench/command-host.tsx} +243 -243
  85. package/src/{workbench-command-palette.ts → workbench/command-palette.ts} +208 -208
  86. package/src/{workbench-keybinding-bridge.ts → workbench/keybinding-bridge.ts} +54 -54
  87. package/src/{workbench-layout-storage.ts → workbench/layout-storage.ts} +134 -145
  88. package/src/{workbench-profile-modal.tsx → workbench/profile-modal.tsx} +118 -118
  89. package/src/{workbench-shell-command-registration.ts → workbench/shell-command-registration.ts} +58 -58
  90. package/src/{workbench-startup-gate.tsx → workbench/startup-gate.tsx} +136 -136
  91. package/src/{workbench-status-sections.ts → workbench/status-sections.ts} +43 -43
  92. package/src/{use-persisted-workbench-appearance.ts → workbench/use-persisted-appearance.ts} +33 -33
  93. package/src/{workbench-user-commands.ts → workbench/user-commands.ts} +46 -46
  94. package/src/{workspace-view-state.ts → workbench/workspace-view-state.ts} +35 -35
  95. package/src/jsonata-transform.ts +0 -36
@@ -1,15 +1,15 @@
1
- import { parseWorkspaceResourceUri } from '@workbench-kit/workspace';
2
-
3
- /** Pure helper — kept out of React component modules for Fast Refresh. */
4
- export function createWorkspaceFileAvailabilityChecker(
5
- filePaths: ReadonlySet<string>,
6
- ): (resourceUri: string) => boolean {
7
- return (resourceUri) => {
8
- const parsed = parseWorkspaceResourceUri(resourceUri);
9
- if (!parsed || parsed.kind !== 'file') {
10
- return true;
11
- }
12
-
13
- return filePaths.has(parsed.path);
14
- };
15
- }
1
+ import { parseWorkspaceResourceUri } from '@workbench-kit/workspace';
2
+
3
+ /** Pure helper — kept out of React component modules for Fast Refresh. */
4
+ export function createWorkspaceFileAvailabilityChecker(
5
+ filePaths: ReadonlySet<string>,
6
+ ): (resourceUri: string) => boolean {
7
+ return (resourceUri) => {
8
+ const parsed = parseWorkspaceResourceUri(resourceUri);
9
+ if (!parsed || parsed.kind !== 'file') {
10
+ return true;
11
+ }
12
+
13
+ return filePaths.has(parsed.path);
14
+ };
15
+ }
@@ -1,28 +1,31 @@
1
- import { useEffect } from 'react';
2
-
3
- import { createWorkspaceFileAvailabilityChecker } from './editor-workspace-file-availability.js';
4
- import { useEditorService } from './use-editor.js';
5
- import { useWorkbench } from './provider.js';
6
- import { isWorkspaceResourceService, useWorkspaceResourceState } from './workspace-view-state.js';
7
-
8
- /** Component-only module so Vite Fast Refresh can accept this boundary. */
9
- export function EditorWorkspaceReconciler(): null {
10
- const { workspaceHostPort } = useWorkbench();
11
- const editorService = useEditorService();
12
- const workspaceService = isWorkspaceResourceService(workspaceHostPort?.service)
13
- ? workspaceHostPort.service
14
- : undefined;
15
- const workspaceState = useWorkspaceResourceState(workspaceService);
16
-
17
- useEffect(() => {
18
- if (!workspaceService) {
19
- return;
20
- }
21
-
22
- const files = workspaceState?.files ?? workspaceService.getState().files;
23
- const filePaths = new Set(files.map((file) => file.path));
24
- editorService.reconcileWorkspaceFileTabs(createWorkspaceFileAvailabilityChecker(filePaths));
25
- }, [editorService, workspaceService, workspaceState]);
26
-
27
- return null;
28
- }
1
+ import { useEffect } from 'react';
2
+
3
+ import { createWorkspaceFileAvailabilityChecker } from './workspace-file-availability.js';
4
+ import { useEditorService } from './use-editor.js';
5
+ import { useWorkbench } from '../shell/provider.js';
6
+ import {
7
+ isWorkspaceResourceService,
8
+ useWorkspaceResourceState,
9
+ } from '../workbench/workspace-view-state.js';
10
+
11
+ /** Component-only module so Vite Fast Refresh can accept this boundary. */
12
+ export function EditorWorkspaceReconciler(): null {
13
+ const { workspaceHostPort } = useWorkbench();
14
+ const editorService = useEditorService();
15
+ const workspaceService = isWorkspaceResourceService(workspaceHostPort?.service)
16
+ ? workspaceHostPort.service
17
+ : undefined;
18
+ const workspaceState = useWorkspaceResourceState(workspaceService);
19
+
20
+ useEffect(() => {
21
+ if (!workspaceService) {
22
+ return;
23
+ }
24
+
25
+ const files = workspaceState?.files ?? workspaceService.getState().files;
26
+ const filePaths = new Set(files.map((file) => file.path));
27
+ editorService.reconcileWorkspaceFileTabs(createWorkspaceFileAvailabilityChecker(filePaths));
28
+ }, [editorService, workspaceService, workspaceState]);
29
+
30
+ return null;
31
+ }
@@ -1,114 +1,114 @@
1
- import type { ContextMenuItem } from '@workbench-kit/react/overlay';
2
- import {
3
- WORKBENCH_COMMAND_SURFACE_WORKSPACE,
4
- commandMenuItemsToContextMenuItems,
5
- createWorkbenchWorkspaceCommands,
6
- createWorkbenchWorkspaceFolderMenuEntries,
7
- createWorkbenchWorkspaceTargetMenuEntries,
8
- type WorkbenchWorkspaceCommandContext,
9
- } from '@workbench-kit/react/workbench/commands';
10
- import {
11
- createCommandRegistry,
12
- executeCommand as executeRegisteredCommand,
13
- resolveCommandMenuItems,
14
- } from '@workbench-kit/platform';
15
- import { parentPathOf, type WorkspaceTreeNode } from '@workbench-kit/workspace';
16
- import type { ExtensionRegistry } from '@workbench-kit/workbench-core';
17
- import {
18
- appendExtensionContextMenuItems,
19
- createExtensionContextMenuItems,
20
- } from './extension-context-menu.js';
21
-
22
- const workspaceCommandRegistry = createCommandRegistry(createWorkbenchWorkspaceCommands());
23
- const workspaceFolderMenuEntries =
24
- createWorkbenchWorkspaceFolderMenuEntries<WorkbenchWorkspaceCommandContext>();
25
- const workspaceTargetMenuEntries =
26
- createWorkbenchWorkspaceTargetMenuEntries<WorkbenchWorkspaceCommandContext>();
27
- const EXPLORER_CONTEXT_MENU = 'explorer/context';
28
- const EXPLORER_EXTENSION_MENU_SEPARATOR_ID = 'explorer-extension-separator';
29
-
30
- export function createExplorerItemContextMenuItems({
31
- actionPaths,
32
- copyPaths,
33
- createFile,
34
- createFolder,
35
- deleteTargets,
36
- executeExtensionCommand,
37
- extensionRegistry,
38
- files,
39
- node,
40
- openFiles,
41
- revealFolder,
42
- renameTarget,
43
- }: {
44
- actionPaths: readonly string[];
45
- copyPaths: (paths: string[]) => void;
46
- createFile: (parentPath: string) => void;
47
- createFolder: (parentPath: string) => void;
48
- deleteTargets: (paths: string[]) => void;
49
- executeExtensionCommand?: ((commandId: string) => unknown) | undefined;
50
- extensionRegistry?: ExtensionRegistry | undefined;
51
- files: readonly { path: string }[];
52
- node: WorkspaceTreeNode;
53
- openFiles: (paths: string[]) => void;
54
- revealFolder: (path: string) => void;
55
- renameTarget: () => void;
56
- }): ContextMenuItem[] {
57
- const fileActionPaths =
58
- node.type === 'file'
59
- ? actionPaths.length > 0
60
- ? [...actionPaths]
61
- : [node.path]
62
- : actionPaths.filter((path) => files.some((file) => file.path === path));
63
- const multiFileAction = fileActionPaths.length > 1;
64
- const targetPaths = node.type === 'folder' ? [node.path] : [...fileActionPaths];
65
- const contextKeys = {
66
- 'workspace.hasSelection': targetPaths.length > 0,
67
- 'workspace.multiSelection': node.type === 'file' && multiFileAction,
68
- };
69
-
70
- const context: WorkbenchWorkspaceCommandContext = {
71
- copyWorkspaceTarget: () => copyPaths([...targetPaths]),
72
- createWorkspaceFile: () =>
73
- createFile(node.type === 'folder' ? node.path : parentPathOf(node.path)),
74
- createWorkspaceFolder: () =>
75
- createFolder(node.type === 'folder' ? node.path : parentPathOf(node.path)),
76
- deleteWorkspaceTarget: () => deleteTargets([...targetPaths]),
77
- fileActionPaths,
78
- multiFileAction,
79
- openWorkspaceTarget: () => {
80
- if (node.type === 'folder') {
81
- revealFolder(node.path);
82
- return;
83
- }
84
-
85
- openFiles(fileActionPaths);
86
- },
87
- renameWorkspaceTarget: renameTarget,
88
- targetPaths,
89
- workspaceTargetKind: node.type,
90
- };
91
-
92
- const baseItems = commandMenuItemsToContextMenuItems(
93
- resolveCommandMenuItems({
94
- context,
95
- contextKeys,
96
- entries: node.type === 'folder' ? workspaceFolderMenuEntries : workspaceTargetMenuEntries,
97
- registry: workspaceCommandRegistry,
98
- surface: WORKBENCH_COMMAND_SURFACE_WORKSPACE,
99
- }),
100
- (commandId) =>
101
- executeRegisteredCommand(workspaceCommandRegistry, commandId, context, contextKeys),
102
- );
103
-
104
- return appendExtensionContextMenuItems(
105
- baseItems,
106
- createExtensionContextMenuItems({
107
- contextKeys,
108
- executeCommand: executeExtensionCommand,
109
- extensionRegistry,
110
- menu: EXPLORER_CONTEXT_MENU,
111
- }),
112
- EXPLORER_EXTENSION_MENU_SEPARATOR_ID,
113
- );
114
- }
1
+ import type { ContextMenuItem } from '@workbench-kit/react/overlay';
2
+ import {
3
+ WORKBENCH_COMMAND_SURFACE_WORKSPACE,
4
+ commandMenuItemsToContextMenuItems,
5
+ createWorkbenchWorkspaceCommands,
6
+ createWorkbenchWorkspaceFolderMenuEntries,
7
+ createWorkbenchWorkspaceTargetMenuEntries,
8
+ type WorkbenchWorkspaceCommandContext,
9
+ } from '@workbench-kit/react/workbench/commands';
10
+ import {
11
+ createCommandRegistry,
12
+ executeCommand as executeRegisteredCommand,
13
+ resolveCommandMenuItems,
14
+ } from '@workbench-kit/platform';
15
+ import { parentPathOf, type WorkspaceTreeNode } from '@workbench-kit/workspace';
16
+ import type { ExtensionRegistry } from '@workbench-kit/workbench-core';
17
+ import {
18
+ appendExtensionContextMenuItems,
19
+ createExtensionContextMenuItems,
20
+ } from '../extensions/context-menu.js';
21
+
22
+ const workspaceCommandRegistry = createCommandRegistry(createWorkbenchWorkspaceCommands());
23
+ const workspaceFolderMenuEntries =
24
+ createWorkbenchWorkspaceFolderMenuEntries<WorkbenchWorkspaceCommandContext>();
25
+ const workspaceTargetMenuEntries =
26
+ createWorkbenchWorkspaceTargetMenuEntries<WorkbenchWorkspaceCommandContext>();
27
+ const EXPLORER_CONTEXT_MENU = 'explorer/context';
28
+ const EXPLORER_EXTENSION_MENU_SEPARATOR_ID = 'explorer-extension-separator';
29
+
30
+ export function createExplorerItemContextMenuItems({
31
+ actionPaths,
32
+ copyPaths,
33
+ createFile,
34
+ createFolder,
35
+ deleteTargets,
36
+ executeExtensionCommand,
37
+ extensionRegistry,
38
+ files,
39
+ node,
40
+ openFiles,
41
+ revealFolder,
42
+ renameTarget,
43
+ }: {
44
+ actionPaths: readonly string[];
45
+ copyPaths: (paths: string[]) => void;
46
+ createFile: (parentPath: string) => void;
47
+ createFolder: (parentPath: string) => void;
48
+ deleteTargets: (paths: string[]) => void;
49
+ executeExtensionCommand?: ((commandId: string) => unknown) | undefined;
50
+ extensionRegistry?: ExtensionRegistry | undefined;
51
+ files: readonly { path: string }[];
52
+ node: WorkspaceTreeNode;
53
+ openFiles: (paths: string[]) => void;
54
+ revealFolder: (path: string) => void;
55
+ renameTarget: () => void;
56
+ }): ContextMenuItem[] {
57
+ const fileActionPaths =
58
+ node.type === 'file'
59
+ ? actionPaths.length > 0
60
+ ? [...actionPaths]
61
+ : [node.path]
62
+ : actionPaths.filter((path) => files.some((file) => file.path === path));
63
+ const multiFileAction = fileActionPaths.length > 1;
64
+ const targetPaths = node.type === 'folder' ? [node.path] : [...fileActionPaths];
65
+ const contextKeys = {
66
+ 'workspace.hasSelection': targetPaths.length > 0,
67
+ 'workspace.multiSelection': node.type === 'file' && multiFileAction,
68
+ };
69
+
70
+ const context: WorkbenchWorkspaceCommandContext = {
71
+ copyWorkspaceTarget: () => copyPaths([...targetPaths]),
72
+ createWorkspaceFile: () =>
73
+ createFile(node.type === 'folder' ? node.path : parentPathOf(node.path)),
74
+ createWorkspaceFolder: () =>
75
+ createFolder(node.type === 'folder' ? node.path : parentPathOf(node.path)),
76
+ deleteWorkspaceTarget: () => deleteTargets([...targetPaths]),
77
+ fileActionPaths,
78
+ multiFileAction,
79
+ openWorkspaceTarget: () => {
80
+ if (node.type === 'folder') {
81
+ revealFolder(node.path);
82
+ return;
83
+ }
84
+
85
+ openFiles(fileActionPaths);
86
+ },
87
+ renameWorkspaceTarget: renameTarget,
88
+ targetPaths,
89
+ workspaceTargetKind: node.type,
90
+ };
91
+
92
+ const baseItems = commandMenuItemsToContextMenuItems(
93
+ resolveCommandMenuItems({
94
+ context,
95
+ contextKeys,
96
+ entries: node.type === 'folder' ? workspaceFolderMenuEntries : workspaceTargetMenuEntries,
97
+ registry: workspaceCommandRegistry,
98
+ surface: WORKBENCH_COMMAND_SURFACE_WORKSPACE,
99
+ }),
100
+ (commandId) =>
101
+ executeRegisteredCommand(workspaceCommandRegistry, commandId, context, contextKeys),
102
+ );
103
+
104
+ return appendExtensionContextMenuItems(
105
+ baseItems,
106
+ createExtensionContextMenuItems({
107
+ contextKeys,
108
+ executeCommand: executeExtensionCommand,
109
+ extensionRegistry,
110
+ menu: EXPLORER_CONTEXT_MENU,
111
+ }),
112
+ EXPLORER_EXTENSION_MENU_SEPARATOR_ID,
113
+ );
114
+ }
@@ -1,86 +1,86 @@
1
- import type {
2
- WorkspaceExplorerControllerPort,
3
- WorkspaceExplorerMutationResult,
4
- WorkspaceExplorerWorkspaceSnapshot,
5
- } from '@workbench-kit/react/workbench/workspace';
6
- import type { VirtualWorkspaceState } from '@workbench-kit/workspace';
7
-
8
- import { BUILTIN_EXPLORER_MOVE_COMMAND_ID } from './explorer-view-data.js';
9
-
10
- const WORKBENCH_WORKSPACE_DELETE_COMMAND_ID = 'workspace.delete' as const;
11
- const WORKBENCH_WORKSPACE_NEW_FILE_COMMAND_ID = 'workspace.newFile' as const;
12
- const WORKBENCH_WORKSPACE_NEW_FOLDER_COMMAND_ID = 'workspace.newFolder' as const;
13
- const WORKBENCH_WORKSPACE_OPEN_COMMAND_ID = 'workspace.open' as const;
14
- const WORKBENCH_WORKSPACE_RENAME_COMMAND_ID = 'workspace.rename' as const;
15
-
16
- interface WorkspaceCommandResult {
17
- readonly path?: string | undefined;
18
- readonly paths?: readonly string[] | undefined;
19
- }
20
-
21
- export function createCommandWorkspaceExplorerPort({
22
- executeCommand,
23
- workspaceState,
24
- }: {
25
- executeCommand(commandId: string, payload?: unknown): Promise<unknown>;
26
- workspaceState: VirtualWorkspaceState | undefined;
27
- }): WorkspaceExplorerControllerPort {
28
- const snapshot: WorkspaceExplorerWorkspaceSnapshot = {
29
- files: workspaceState?.files ?? [],
30
- folders: workspaceState?.folders ?? [],
31
- };
32
-
33
- return {
34
- snapshot,
35
- createFile(input) {
36
- return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_NEW_FILE_COMMAND_ID, input);
37
- },
38
- createFolder(input) {
39
- return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_NEW_FOLDER_COMMAND_ID, input);
40
- },
41
- deleteEntries({ kind, paths }) {
42
- void executeCommand(WORKBENCH_WORKSPACE_DELETE_COMMAND_ID, {
43
- kind,
44
- paths,
45
- });
46
- },
47
- moveEntries(input) {
48
- return runWorkspaceCommand(executeCommand, BUILTIN_EXPLORER_MOVE_COMMAND_ID, {
49
- sourcePaths: input.sourcePaths,
50
- targetFolderPath: input.targetFolderPath,
51
- });
52
- },
53
- openFile(path) {
54
- void executeCommand(WORKBENCH_WORKSPACE_OPEN_COMMAND_ID, {
55
- kind: 'file',
56
- path,
57
- paths: [path],
58
- });
59
- },
60
- renameEntry(input) {
61
- return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_RENAME_COMMAND_ID, input);
62
- },
63
- };
64
- }
65
-
66
- async function runWorkspaceCommand(
67
- executeCommand: (commandId: string, payload?: unknown) => Promise<unknown>,
68
- commandId: string,
69
- payload: unknown,
70
- ): Promise<WorkspaceExplorerMutationResult | undefined> {
71
- const result = await executeCommand(commandId, payload);
72
- return isWorkspaceCommandResult(result) ? result : undefined;
73
- }
74
-
75
- function isWorkspaceCommandResult(value: unknown): value is WorkspaceCommandResult {
76
- if (typeof value !== 'object' || value === null) {
77
- return false;
78
- }
79
-
80
- const result = value as WorkspaceCommandResult;
81
- return (
82
- (result.path === undefined || typeof result.path === 'string') &&
83
- (result.paths === undefined ||
84
- (Array.isArray(result.paths) && result.paths.every((path) => typeof path === 'string')))
85
- );
86
- }
1
+ import type {
2
+ WorkspaceExplorerControllerPort,
3
+ WorkspaceExplorerMutationResult,
4
+ WorkspaceExplorerWorkspaceSnapshot,
5
+ } from '@workbench-kit/react/workbench/workspace';
6
+ import type { VirtualWorkspaceState } from '@workbench-kit/workspace';
7
+
8
+ import { BUILTIN_EXPLORER_MOVE_COMMAND_ID } from './view-data.js';
9
+
10
+ const WORKBENCH_WORKSPACE_DELETE_COMMAND_ID = 'workspace.delete' as const;
11
+ const WORKBENCH_WORKSPACE_NEW_FILE_COMMAND_ID = 'workspace.newFile' as const;
12
+ const WORKBENCH_WORKSPACE_NEW_FOLDER_COMMAND_ID = 'workspace.newFolder' as const;
13
+ const WORKBENCH_WORKSPACE_OPEN_COMMAND_ID = 'workspace.open' as const;
14
+ const WORKBENCH_WORKSPACE_RENAME_COMMAND_ID = 'workspace.rename' as const;
15
+
16
+ interface WorkspaceCommandResult {
17
+ readonly path?: string | undefined;
18
+ readonly paths?: readonly string[] | undefined;
19
+ }
20
+
21
+ export function createCommandWorkspaceExplorerPort({
22
+ executeCommand,
23
+ workspaceState,
24
+ }: {
25
+ executeCommand(commandId: string, payload?: unknown): Promise<unknown>;
26
+ workspaceState: VirtualWorkspaceState | undefined;
27
+ }): WorkspaceExplorerControllerPort {
28
+ const snapshot: WorkspaceExplorerWorkspaceSnapshot = {
29
+ files: workspaceState?.files ?? [],
30
+ folders: workspaceState?.folders ?? [],
31
+ };
32
+
33
+ return {
34
+ snapshot,
35
+ createFile(input) {
36
+ return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_NEW_FILE_COMMAND_ID, input);
37
+ },
38
+ createFolder(input) {
39
+ return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_NEW_FOLDER_COMMAND_ID, input);
40
+ },
41
+ deleteEntries({ kind, paths }) {
42
+ void executeCommand(WORKBENCH_WORKSPACE_DELETE_COMMAND_ID, {
43
+ kind,
44
+ paths,
45
+ });
46
+ },
47
+ moveEntries(input) {
48
+ return runWorkspaceCommand(executeCommand, BUILTIN_EXPLORER_MOVE_COMMAND_ID, {
49
+ sourcePaths: input.sourcePaths,
50
+ targetFolderPath: input.targetFolderPath,
51
+ });
52
+ },
53
+ openFile(path) {
54
+ void executeCommand(WORKBENCH_WORKSPACE_OPEN_COMMAND_ID, {
55
+ kind: 'file',
56
+ path,
57
+ paths: [path],
58
+ });
59
+ },
60
+ renameEntry(input) {
61
+ return runWorkspaceCommand(executeCommand, WORKBENCH_WORKSPACE_RENAME_COMMAND_ID, input);
62
+ },
63
+ };
64
+ }
65
+
66
+ async function runWorkspaceCommand(
67
+ executeCommand: (commandId: string, payload?: unknown) => Promise<unknown>,
68
+ commandId: string,
69
+ payload: unknown,
70
+ ): Promise<WorkspaceExplorerMutationResult | undefined> {
71
+ const result = await executeCommand(commandId, payload);
72
+ return isWorkspaceCommandResult(result) ? result : undefined;
73
+ }
74
+
75
+ function isWorkspaceCommandResult(value: unknown): value is WorkspaceCommandResult {
76
+ if (typeof value !== 'object' || value === null) {
77
+ return false;
78
+ }
79
+
80
+ const result = value as WorkspaceCommandResult;
81
+ return (
82
+ (result.path === undefined || typeof result.path === 'string') &&
83
+ (result.paths === undefined ||
84
+ (Array.isArray(result.paths) && result.paths.every((path) => typeof path === 'string')))
85
+ );
86
+ }