@vuu-ui/vuu-shell 4.0.0-alpha.3 → 4.0.0-alpha.30

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 (43) hide show
  1. package/package.json +20 -19
  2. package/src/app-header/AppHeader.css.js +1 -1
  3. package/src/persistence-manager/PersistenceProvider.js +5 -7
  4. package/src/persistence-manager/index.js +1 -3
  5. package/src/shell.css.js +1 -1
  6. package/src/shell.js +2 -2
  7. package/src/workspace-management/LayoutList.js +1 -1
  8. package/src/workspace-management/index.js +1 -8
  9. package/src/workspace-management/useWorkspaceContextMenuItems.js +1 -2
  10. package/types/app-header/AppHeader.d.ts +1 -1
  11. package/types/feature/Feature.d.ts +1 -1
  12. package/types/feature/Loader.d.ts +1 -1
  13. package/types/feature-list/FeatureList.d.ts +1 -1
  14. package/types/left-nav/LeftNav.d.ts +1 -1
  15. package/types/login/LoginPanel.d.ts +1 -1
  16. package/types/login/VuuLogo.d.ts +1 -1
  17. package/types/persistence-manager/PersistenceProvider.d.ts +2 -3
  18. package/types/persistence-manager/index.d.ts +1 -3
  19. package/types/shell-layout-templates/context-panel/ApplicationSettingsContextPanel.d.ts +1 -1
  20. package/types/shell-layout-templates/context-panel/ContextPanel.d.ts +1 -1
  21. package/types/shell-layout-templates/side-panel/SidePanel.d.ts +1 -1
  22. package/types/shell.d.ts +2 -2
  23. package/types/theme-switch/ThemeSwitch.d.ts +1 -1
  24. package/types/workspace-management/LayoutList.d.ts +1 -1
  25. package/types/workspace-management/LayoutTile.d.ts +1 -1
  26. package/types/workspace-management/SaveLayoutPanel.d.ts +1 -1
  27. package/types/workspace-management/WorkspaceHost.d.ts +1 -1
  28. package/types/workspace-management/WorkspaceProvider.d.ts +50 -61
  29. package/types/workspace-management/WorkspaceStartPanel.d.ts +1 -1
  30. package/types/workspace-management/index.d.ts +5 -8
  31. package/types/workspace-management/shell-workspace-components.d.ts +1 -1
  32. package/src/persistence-manager/LocalWorkspacePersistenceService.js +0 -129
  33. package/src/persistence-manager/RemoteWorkspacePersistenceService.js +0 -112
  34. package/src/persistence-manager/WorkspacePersistenceService.js +0 -9
  35. package/src/workspace-management/WorkspaceController.js +0 -73
  36. package/src/workspace-management/WorkspaceHost.js +0 -194
  37. package/src/workspace-management/WorkspacePersistentState.js +0 -67
  38. package/src/workspace-management/WorkspaceProvider.js +0 -730
  39. package/src/workspace-management/WorkspaceRepository.js +0 -127
  40. package/src/workspace-management/WorkspaceStartPanel.css.js +0 -44
  41. package/src/workspace-management/WorkspaceStartPanel.js +0 -34
  42. package/src/workspace-management/workspace-component-registry.js +0 -30
  43. package/src/workspace-management/workspace-schemas.js +0 -257
@@ -1,112 +0,0 @@
1
- import { cloneWorkspaceValue, validateApplicationSessionV1, validateNamedWorkspaceDefinitionV1, validateNamedWorkspaceMetadataV1, validateWorkspaceSnapshotRecordV1 } from "../workspace-management/workspace-schemas.js";
2
- import { WorkspacePersistenceError } from "./WorkspacePersistenceService.js";
3
- const trimSlash = (value)=>value.replace(/\/+$/, "");
4
- const requireId = (id, operation)=>{
5
- if (!id) throw new WorkspacePersistenceError("Entity id must not be empty", operation);
6
- return encodeURIComponent(id);
7
- };
8
- class RemoteWorkspacePersistenceService {
9
- scope;
10
- #baseUrl;
11
- #requestInit;
12
- #requestInitProvider;
13
- #fetch;
14
- constructor(scope, { baseUrl, requestInit, requestInitProvider, fetch: fetchImplementation = globalThis.fetch }){
15
- if (!scope.applicationNamespace || !scope.applicationId || !scope.userId || !baseUrl) throw new WorkspacePersistenceError("Remote persistence scope and base URL must not be empty", "construct");
16
- this.scope = Object.freeze({
17
- ...scope
18
- });
19
- this.#baseUrl = trimSlash(baseUrl);
20
- this.#requestInit = requestInit;
21
- this.#requestInitProvider = requestInitProvider;
22
- this.#fetch = fetchImplementation;
23
- }
24
- async loadApplicationSession() {
25
- return this.#optional("loadApplicationSession", "application-session", validateApplicationSessionV1);
26
- }
27
- async saveApplicationSession(session) {
28
- await this.#void("saveApplicationSession", "application-session", "PUT", validateApplicationSessionV1(session));
29
- }
30
- async deleteApplicationSession() {
31
- await this.#void("deleteApplicationSession", "application-session", "DELETE");
32
- }
33
- async listWorkspaceSnapshots() {
34
- const value = await this.#json("listWorkspaceSnapshots", "snapshots");
35
- if (!Array.isArray(value)) throw new WorkspacePersistenceError("Remote snapshot list response must be an array", "listWorkspaceSnapshots");
36
- return value.map(validateWorkspaceSnapshotRecordV1);
37
- }
38
- async loadWorkspaceSnapshot(workspaceInstanceId) {
39
- return this.#optional("loadWorkspaceSnapshot", `snapshots/${requireId(workspaceInstanceId, "loadWorkspaceSnapshot")}`, validateWorkspaceSnapshotRecordV1);
40
- }
41
- async saveWorkspaceSnapshot(snapshot) {
42
- const validated = validateWorkspaceSnapshotRecordV1(snapshot);
43
- await this.#void("saveWorkspaceSnapshot", `snapshots/${encodeURIComponent(validated.workspaceInstanceId)}`, "PUT", validated);
44
- }
45
- async deleteWorkspaceSnapshot(workspaceInstanceId) {
46
- await this.#void("deleteWorkspaceSnapshot", `snapshots/${requireId(workspaceInstanceId, "deleteWorkspaceSnapshot")}`, "DELETE");
47
- }
48
- async listNamedWorkspaceMetadata() {
49
- const value = await this.#json("listNamedWorkspaceMetadata", "named-workspaces");
50
- if (!Array.isArray(value)) throw new WorkspacePersistenceError("Remote workspace metadata response must be an array", "listNamedWorkspaceMetadata");
51
- return value.map(validateNamedWorkspaceMetadataV1);
52
- }
53
- async loadNamedWorkspaceDefinition(id) {
54
- return this.#optional("loadNamedWorkspaceDefinition", `named-workspaces/${requireId(id, "loadNamedWorkspaceDefinition")}`, validateNamedWorkspaceDefinitionV1);
55
- }
56
- async saveNamedWorkspaceDefinition(definition) {
57
- const validated = validateNamedWorkspaceDefinitionV1(definition);
58
- await this.#void("saveNamedWorkspaceDefinition", `named-workspaces/${encodeURIComponent(validated.id)}`, "PUT", validated);
59
- }
60
- async deleteNamedWorkspaceDefinition(id) {
61
- await this.#void("deleteNamedWorkspaceDefinition", `named-workspaces/${requireId(id, "deleteNamedWorkspaceDefinition")}`, "DELETE");
62
- }
63
- async #optional(operation, path, validator) {
64
- const response = await this.#request(operation, path, "GET");
65
- if (404 === response.status) return;
66
- await this.#assertOk(response, operation);
67
- return cloneWorkspaceValue(validator(await response.json()));
68
- }
69
- async #json(operation, path) {
70
- const response = await this.#request(operation, path, "GET");
71
- await this.#assertOk(response, operation);
72
- return response.json();
73
- }
74
- async #void(operation, path, method, body) {
75
- const response = await this.#request(operation, path, method, body);
76
- await this.#assertOk(response, operation);
77
- }
78
- async #request(operation, path, method, body) {
79
- const provided = this.#requestInitProvider ? await this.#requestInitProvider() : {};
80
- const configured = this.#requestInit ?? {};
81
- const headers = new Headers(configured.headers);
82
- new Headers(provided.headers).forEach((value, key)=>{
83
- headers.set(key, value);
84
- });
85
- headers.set("Accept", "application/json");
86
- headers.set("X-Vuu-Application-Namespace", this.scope.applicationNamespace);
87
- headers.set("X-Vuu-Application-Id", this.scope.applicationId);
88
- headers.set("X-Vuu-User-Id", this.scope.userId);
89
- if (void 0 !== body) headers.set("Content-Type", "application/json");
90
- const scopePath = [
91
- this.scope.applicationNamespace,
92
- this.scope.applicationId,
93
- this.scope.userId
94
- ].map(encodeURIComponent).join("/");
95
- try {
96
- return await this.#fetch(`${this.#baseUrl}/${scopePath}/${path}`, {
97
- ...configured,
98
- ...provided,
99
- headers,
100
- method,
101
- body: void 0 === body ? void 0 : JSON.stringify(cloneWorkspaceValue(body))
102
- });
103
- } catch (error) {
104
- if (!(error instanceof Error)) throw error;
105
- throw new WorkspacePersistenceError(error.message, operation);
106
- }
107
- }
108
- async #assertOk(response, operation) {
109
- if (!response.ok) throw new WorkspacePersistenceError(response.statusText || `Remote persistence request failed (${response.status})`, operation, response.status);
110
- }
111
- }
112
- export { RemoteWorkspacePersistenceService };
@@ -1,9 +0,0 @@
1
- class WorkspacePersistenceError extends Error {
2
- operation;
3
- status;
4
- constructor(message, operation, status){
5
- super(message), this.operation = operation, this.status = status;
6
- this.name = "WorkspacePersistenceError";
7
- }
8
- }
9
- export { WorkspacePersistenceError };
@@ -1,73 +0,0 @@
1
- import { GridLayoutDocumentController } from "@vuu-ui/grid-layout";
2
- import { WorkspacePersistentStateStore } from "./WorkspacePersistentState.js";
3
- import { WorkspaceRepository } from "./WorkspaceRepository.js";
4
- import { WORKSPACE_SNAPSHOT_VERSION } from "./workspace-schemas.js";
5
- class WorkspaceController {
6
- definitionId;
7
- documentController;
8
- instanceId;
9
- name;
10
- persistentState;
11
- renderers;
12
- repository;
13
- settingsCodecs;
14
- #disposed = false;
15
- #savingStructure = false;
16
- #onError;
17
- #unsubscribe;
18
- constructor(options){
19
- this.definitionId = options.definitionId;
20
- this.instanceId = options.instanceId;
21
- this.name = options.name;
22
- this.renderers = options.renderers;
23
- this.settingsCodecs = options.settingsCodecs;
24
- this.#onError = options.onError;
25
- this.repository = new WorkspaceRepository(options.service, options.instanceId, void 0 === options.revision ? void 0 : {
26
- revision: options.revision,
27
- snapshot: options.snapshot,
28
- version: 1,
29
- workspaceInstanceId: options.instanceId
30
- });
31
- this.persistentState = new WorkspacePersistentStateStore(options.snapshot.componentState);
32
- this.documentController = new GridLayoutDocumentController(options.snapshot.layout);
33
- this.#unsubscribe = this.persistentState.subscribe(()=>{
34
- if (!this.#savingStructure) this.#save();
35
- });
36
- }
37
- get snapshot() {
38
- const layout = this.documentController.getSnapshot();
39
- if (!layout) throw new Error(`Workspace "${this.instanceId}" has no layout document`);
40
- return {
41
- version: WORKSPACE_SNAPSHOT_VERSION,
42
- layout,
43
- componentState: this.persistentState.getSnapshot()
44
- };
45
- }
46
- handleDocumentChange = (document, change)=>{
47
- if (this.#disposed) return;
48
- this.documentController.replace(document);
49
- this.#savingStructure = true;
50
- try {
51
- for (const componentId of change.removedComponentInstanceIds)this.persistentState.purge(componentId);
52
- } finally{
53
- this.#savingStructure = false;
54
- }
55
- this.#save();
56
- };
57
- rename(name) {
58
- this.name = name;
59
- }
60
- dispose() {
61
- if (!this.#disposed) {
62
- this.#disposed = true;
63
- this.#unsubscribe();
64
- }
65
- return this.repository.dispose();
66
- }
67
- #save() {
68
- if (!this.#disposed) this.repository.save(this.snapshot).catch((cause)=>{
69
- if (!this.#disposed) this.#onError(cause instanceof Error ? cause : new Error("Workspace snapshot persistence failed"));
70
- });
71
- }
72
- }
73
- export { WorkspaceController };
@@ -1,194 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { GridLayout, GridLayoutProvider } from "@vuu-ui/grid-layout";
3
- import { Tab, Tabstrip } from "@vuu-ui/vuu-ui-controls";
4
- import { useCallback, useRef, useState } from "react";
5
- import { WorkspacePersistentStateProvider, WorkspacePersistentStateStore } from "./WorkspacePersistentState.js";
6
- import { emptyWorkspaceSnapshot, useWorkspace } from "./WorkspaceProvider.js";
7
- import { WorkspaceStartPanel } from "./WorkspaceStartPanel.js";
8
- import { WORKSPACE_SNAPSHOT_VERSION } from "./workspace-schemas.js";
9
- const WorkspaceGrid = ({ active, controller })=>{
10
- const [isEmpty, setIsEmpty] = useState(0 === controller.snapshot.layout.components.length);
11
- const handleDocumentError = useCallback((error)=>{
12
- throw new Error(`Invalid workspace document at ${error.path}: ${error.message}`);
13
- }, []);
14
- const handleDocumentChange = useCallback((document, change)=>{
15
- setIsEmpty(0 === document.components.length);
16
- controller.handleDocumentChange(document, change);
17
- }, [
18
- controller
19
- ]);
20
- return /*#__PURE__*/ jsx("section", {
21
- "aria-hidden": !active,
22
- "aria-labelledby": `${controller.instanceId}-tab`,
23
- className: "vuuWorkspaceHost-workspace",
24
- "data-workspace-instance-id": controller.instanceId,
25
- hidden: !active,
26
- id: controller.instanceId,
27
- role: "tabpanel",
28
- children: /*#__PURE__*/ jsx(WorkspacePersistentStateProvider, {
29
- store: controller.persistentState,
30
- children: /*#__PURE__*/ jsx(GridLayoutProvider, {
31
- componentRenderers: controller.renderers,
32
- document: controller.snapshot.layout,
33
- documentController: controller.documentController,
34
- onDocumentChange: handleDocumentChange,
35
- onDocumentError: handleDocumentError,
36
- settingsCodecs: controller.settingsCodecs,
37
- children: /*#__PURE__*/ jsx(GridLayout, {
38
- id: controller.snapshot.layout.layout.id,
39
- placeholderContent: isEmpty ? /*#__PURE__*/ jsx(WorkspaceStartPanel, {}) : void 0
40
- })
41
- })
42
- })
43
- });
44
- };
45
- const EmptyWorkspaceDropTarget = ()=>{
46
- const { componentRenderers, createWorkspaceFromSnapshot, settingsCodecs } = useWorkspace();
47
- const creating = useRef(false);
48
- const [creationPending, setCreationPending] = useState(false);
49
- const [generation, setGeneration] = useState(0);
50
- const [persistentState, setPersistentState] = useState(()=>new WorkspacePersistentStateStore());
51
- const handleDocumentError = useCallback((error)=>{
52
- throw new Error(`Invalid empty workspace document at ${error.path}: ${error.message}`);
53
- }, []);
54
- const handleDocumentChange = useCallback((document)=>{
55
- if (creating.current || 0 === document.components.length) return;
56
- creating.current = true;
57
- setCreationPending(true);
58
- createWorkspaceFromSnapshot({
59
- componentState: persistentState.getSnapshot(),
60
- layout: document,
61
- version: WORKSPACE_SNAPSHOT_VERSION
62
- }, "Untitled").catch(()=>{
63
- creating.current = false;
64
- setCreationPending(false);
65
- setPersistentState(new WorkspacePersistentStateStore());
66
- setGeneration((current)=>current + 1);
67
- });
68
- }, [
69
- createWorkspaceFromSnapshot,
70
- persistentState
71
- ]);
72
- if (!componentRenderers || !settingsCodecs) return /*#__PURE__*/ jsx("div", {
73
- className: "vuuWorkspaceHost-state",
74
- role: "alert",
75
- children: "Workspace component registries are not configured."
76
- });
77
- if (creationPending) return /*#__PURE__*/ jsx("div", {
78
- className: "vuuWorkspaceHost-empty",
79
- children: /*#__PURE__*/ jsx("div", {
80
- className: "vuuWorkspaceHost-state",
81
- role: "status",
82
- children: "Creating workspace…"
83
- })
84
- });
85
- return /*#__PURE__*/ jsx("div", {
86
- className: "vuuWorkspaceHost-empty",
87
- children: /*#__PURE__*/ jsx(WorkspacePersistentStateProvider, {
88
- store: persistentState,
89
- children: /*#__PURE__*/ jsx(GridLayoutProvider, {
90
- componentRenderers: componentRenderers,
91
- onDocumentChange: handleDocumentChange,
92
- onDocumentError: handleDocumentError,
93
- settingsCodecs: settingsCodecs,
94
- children: /*#__PURE__*/ jsx(GridLayout, {
95
- className: "vuuWorkspaceHost-emptyGrid",
96
- colsAndRows: {
97
- cols: [
98
- "1fr"
99
- ],
100
- rows: [
101
- "1fr"
102
- ]
103
- },
104
- id: emptyWorkspaceSnapshot.layout.layout.id,
105
- placeholderContent: /*#__PURE__*/ jsx(WorkspaceStartPanel, {})
106
- })
107
- }, generation)
108
- })
109
- });
110
- };
111
- const WorkspaceHost = ()=>{
112
- const { activeWorkspaceInstanceId, closeWorkspace, controllers, createWorkspaceFromSnapshot, error, renameWorkspace, selectWorkspace, status } = useWorkspace();
113
- const [tabRevision, setTabRevision] = useState(0);
114
- const activeWorkspaceIndex = controllers.findIndex(({ instanceId })=>instanceId === activeWorkspaceInstanceId);
115
- const handleActiveChange = useCallback((tabIndex)=>{
116
- const controller = controllers[tabIndex];
117
- if (controller) selectWorkspace(controller.instanceId);
118
- }, [
119
- controllers,
120
- selectWorkspace
121
- ]);
122
- const handleCloseTab = useCallback((tabIndex)=>{
123
- const controller = controllers[tabIndex];
124
- if (controller) closeWorkspace(controller.instanceId);
125
- }, [
126
- closeWorkspace,
127
- controllers
128
- ]);
129
- const handleAddTab = useCallback(()=>{
130
- const titles = new Set(controllers.map(({ name })=>name));
131
- let suffix = 1;
132
- let title = "Untitled";
133
- while(titles.has(title)){
134
- suffix += 1;
135
- title = `Untitled ${suffix}`;
136
- }
137
- createWorkspaceFromSnapshot(emptyWorkspaceSnapshot, title).catch(()=>void 0);
138
- }, [
139
- controllers,
140
- createWorkspaceFromSnapshot
141
- ]);
142
- const handleExitEditMode = useCallback((originalTitle, title, _allowDeactivation, tabIndex)=>{
143
- const controller = controllers[tabIndex];
144
- if (controller && title !== originalTitle) renameWorkspace(controller.instanceId, title).catch(()=>{
145
- setTabRevision((revision)=>revision + 1);
146
- });
147
- }, [
148
- controllers,
149
- renameWorkspace
150
- ]);
151
- if ("loading" === status) return /*#__PURE__*/ jsx("div", {
152
- className: "vuuWorkspaceHost-state",
153
- role: "status",
154
- children: "Loading workspaces…"
155
- });
156
- if ("error" === status) return /*#__PURE__*/ jsx("div", {
157
- className: "vuuWorkspaceHost-state",
158
- role: "alert",
159
- children: error?.message ?? "Unable to load workspaces"
160
- });
161
- return /*#__PURE__*/ jsxs("div", {
162
- className: "vuuWorkspaceHost vuu-workspace-tabs",
163
- children: [
164
- /*#__PURE__*/ jsx(Tabstrip, {
165
- activeTabIndex: activeWorkspaceIndex,
166
- allowAddTab: true,
167
- allowCloseTab: true,
168
- allowRenameTab: true,
169
- animateSelectionThumb: false,
170
- "aria-label": "Workspace Tabs",
171
- className: "vuuTabHeader",
172
- onActiveChange: handleActiveChange,
173
- onAddTab: handleAddTab,
174
- onCloseTab: handleCloseTab,
175
- onExitEditMode: handleExitEditMode,
176
- variant: "primary",
177
- children: controllers.map((controller)=>/*#__PURE__*/ jsx(Tab, {
178
- ariaControls: controller.instanceId,
179
- id: `${controller.instanceId}-tab`,
180
- label: controller.name,
181
- onClose: ()=>void closeWorkspace(controller.instanceId)
182
- }, `${controller.instanceId}-${tabRevision}`))
183
- }),
184
- /*#__PURE__*/ jsx("div", {
185
- className: "vuuWorkspaceHost-content",
186
- children: "empty" === status ? /*#__PURE__*/ jsx(EmptyWorkspaceDropTarget, {}) : controllers.map((controller)=>/*#__PURE__*/ jsx(WorkspaceGrid, {
187
- active: controller.instanceId === activeWorkspaceInstanceId,
188
- controller: controller
189
- }, controller.instanceId))
190
- })
191
- ]
192
- });
193
- };
194
- export { WorkspaceHost };
@@ -1,67 +0,0 @@
1
- import { createContext, createElement, useContext, useSyncExternalStore } from "react";
2
- import { cloneWorkspaceValue } from "./workspace-schemas.js";
3
- class WorkspacePersistentStateStore {
4
- #state;
5
- #listeners = new Set();
6
- constructor(initialState = {}){
7
- this.#state = Object.freeze(cloneWorkspaceValue(initialState));
8
- }
9
- getSnapshot = ()=>this.#state;
10
- subscribe = (listener)=>{
11
- this.#listeners.add(listener);
12
- return ()=>this.#listeners.delete(listener);
13
- };
14
- get(componentInstanceId) {
15
- const value = this.#state[componentInstanceId];
16
- return void 0 === value ? void 0 : cloneWorkspaceValue(value);
17
- }
18
- update(componentInstanceId, update) {
19
- if (!componentInstanceId) throw new Error("componentInstanceId must not be empty");
20
- const next = "function" == typeof update ? update(this.get(componentInstanceId)) : update;
21
- const captured = cloneWorkspaceValue(next);
22
- if (!captured.componentType || !Number.isInteger(captured.schemaVersion) || captured.schemaVersion < 1) throw new Error("Component persistent state metadata is invalid");
23
- this.#state = Object.freeze({
24
- ...this.#state,
25
- [componentInstanceId]: captured
26
- });
27
- this.#emit();
28
- }
29
- purge(componentInstanceId) {
30
- if (void 0 === componentInstanceId) {
31
- if (Object.keys(this.#state).length > 0) {
32
- this.#state = Object.freeze({});
33
- this.#emit();
34
- }
35
- return;
36
- }
37
- if (void 0 !== this.#state[componentInstanceId]) {
38
- const { [componentInstanceId]: removed, ...remaining } = this.#state;
39
- this.#state = Object.freeze(remaining);
40
- this.#emit();
41
- }
42
- }
43
- #emit() {
44
- this.#listeners.forEach((listener)=>{
45
- listener();
46
- });
47
- }
48
- }
49
- const WorkspacePersistentStateContext = /*#__PURE__*/ createContext(null);
50
- const WorkspacePersistentStateProvider = ({ children, store })=>/*#__PURE__*/ createElement(WorkspacePersistentStateContext.Provider, {
51
- value: store
52
- }, children);
53
- const useWorkspacePersistentStateStore = ()=>{
54
- const store = useContext(WorkspacePersistentStateContext);
55
- if (!store) throw new Error("useWorkspacePersistentStateStore requires WorkspacePersistentStateProvider");
56
- return store;
57
- };
58
- const useComponentPersistentState = (componentInstanceId)=>{
59
- const store = useWorkspacePersistentStateStore();
60
- const state = useSyncExternalStore(store.subscribe, ()=>store.getSnapshot()[componentInstanceId], ()=>store.getSnapshot()[componentInstanceId]);
61
- return [
62
- state,
63
- (update)=>store.update(componentInstanceId, update),
64
- ()=>store.purge(componentInstanceId)
65
- ];
66
- };
67
- export { WorkspacePersistentStateProvider, WorkspacePersistentStateStore, useComponentPersistentState, useWorkspacePersistentStateStore };