@pstdio/workbench 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +100 -88
  2. package/dist/context-key-service-W4QEfVdN.js +1031 -0
  3. package/dist/context-key-service-W4QEfVdN.js.map +1 -0
  4. package/dist/extensions.d.ts +737 -255
  5. package/dist/extensions.js +891 -699
  6. package/dist/extensions.js.map +1 -1
  7. package/dist/file-renderer-view-DrrhYnb_.js.map +1 -1
  8. package/dist/index.d.ts +746 -448
  9. package/dist/index.js +2974 -60
  10. package/dist/index.js.map +1 -1
  11. package/dist/layout-types-DMoZz38-.js +100 -0
  12. package/dist/layout-types-DMoZz38-.js.map +1 -0
  13. package/dist/react.d.ts +735 -231
  14. package/dist/react.js +3562 -2584
  15. package/dist/react.js.map +1 -1
  16. package/dist/storage.d.ts +109 -14
  17. package/dist/storage.js +142 -47
  18. package/dist/storage.js.map +1 -1
  19. package/dist/surface-map-C1pOTUmF.js +52 -0
  20. package/dist/surface-map-C1pOTUmF.js.map +1 -0
  21. package/dist/testing.d.ts +685 -198
  22. package/dist/testing.js +46 -34
  23. package/dist/testing.js.map +1 -1
  24. package/dist/webview-runtime.js +5 -1
  25. package/dist/webview-runtime.js.map +1 -1
  26. package/dist/workbench-menu-paths-B_QJzcNU.js +12 -0
  27. package/dist/workbench-menu-paths-B_QJzcNU.js.map +1 -0
  28. package/package.json +6 -7
  29. package/dist/context-key-service-C--cHa0B.js +0 -447
  30. package/dist/context-key-service-C--cHa0B.js.map +0 -1
  31. package/dist/core.d.ts +0 -1885
  32. package/dist/core.js +0 -64
  33. package/dist/core.js.map +0 -1
  34. package/dist/surface-reconcile-DkRf01ro.js +0 -260
  35. package/dist/surface-reconcile-DkRf01ro.js.map +0 -1
  36. package/dist/workbench-core-DFpwi8Lo.js +0 -2264
  37. package/dist/workbench-core-DFpwi8Lo.js.map +0 -1
  38. package/dist/workbench-menu-paths-CQVH6z4_.js +0 -11
  39. package/dist/workbench-menu-paths-CQVH6z4_.js.map +0 -1
package/dist/storage.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  declare type ContributionSource = "module" | "extension";
2
2
 
3
+ export declare const createLocalStorageHistoryPersistence: (input: CreateWorkbenchStoragePersistenceInput) => WorkbenchHistoryPersistence;
4
+
3
5
  export declare const createLocalStorageLastResourcePersistence: (input: CreateLocalStorageLastResourcePersistenceInput) => LastResourcePersistenceAdapter;
4
6
 
5
7
  export declare interface CreateLocalStorageLastResourcePersistenceInput extends CreateWorkbenchStoragePersistenceInput {
@@ -21,6 +23,9 @@ export declare interface CreateLocalStorageTreePersistenceInput extends CreateWo
21
23
  }
22
24
 
23
25
  export declare const createLocalStorageWorkbenchPersistence: (input: CreateLocalStorageWorkbenchPersistenceInput) => {
26
+ snapshotPersistence: WorkbenchPersistenceAdapter;
27
+ historyPersistence: WorkbenchHistoryPersistence;
28
+ layoutPersistence: LayoutPersistenceAdapter;
24
29
  panelsPersistence: WorkbenchPanelsPersistenceAdapter;
25
30
  treePersistence: TreeRendererPersistenceAdapter;
26
31
  lastResourcePersistence: LastResourcePersistenceAdapter;
@@ -31,10 +36,22 @@ export declare interface CreateLocalStorageWorkbenchPersistenceInput extends Cre
31
36
  }
32
37
 
33
38
  declare interface CreateWorkbenchStoragePersistenceInput {
39
+ debounceMs?: number;
40
+ eventTarget?: {
41
+ addEventListener(type: "pagehide", listener: () => void): void;
42
+ removeEventListener(type: "pagehide", listener: () => void): void;
43
+ };
34
44
  namespace: string;
35
45
  storage?: WorkbenchStorageLike;
36
46
  }
37
47
 
48
+ declare interface HistoryStoreState {
49
+ entries: readonly WorkbenchNavigationEntry[];
50
+ cursor: number;
51
+ recentlyClosed: readonly WorkbenchNavigationEntry[];
52
+ hydrating: boolean;
53
+ }
54
+
38
55
  declare interface LastResourcePersistenceAdapter {
39
56
  getLastResource(): ResourceRef | undefined;
40
57
  setLastResource(resource: ResourceRef | undefined): void;
@@ -43,6 +60,8 @@ declare interface LastResourcePersistenceAdapter {
43
60
  declare interface LayoutPersistenceAdapter {
44
61
  getLayout(scope?: LayoutScope): WorkbenchLayout | undefined;
45
62
  setLayout(layout: WorkbenchLayout, scope?: LayoutScope): void;
63
+ flush?(): void;
64
+ dispose?(): void;
46
65
  }
47
66
 
48
67
  declare type LayoutScope = string;
@@ -51,8 +70,12 @@ declare interface PersistedTreeRendererStates {
51
70
  statesByTreeId: Record<string, TreeRendererState>;
52
71
  }
53
72
 
73
+ declare interface PersistedWorkbenchHistory extends Omit<HistoryStoreState, "hydrating"> {
74
+ version: 1;
75
+ }
76
+
54
77
  declare interface PersistedWorkbenchPanels {
55
- openByAreaId: Record<string, boolean>;
78
+ openByRegionId: Record<string, boolean>;
56
79
  }
57
80
 
58
81
  declare interface ResourceRef {
@@ -78,27 +101,79 @@ declare interface TreeRendererState {
78
101
 
79
102
  declare type WidgetMountStrategy = "active" | "keep-mounted";
80
103
 
81
- declare type WorkbenchArea = (typeof workbenchAreas)[number];
82
-
83
- declare const workbenchAreas: readonly ["nav", "activity", "left-header", "left", "main-header", "main-left", "main", "main-right", "secondary-header", "secondary", "status", "overlay", "floating-header", "floating"];
104
+ declare interface WorkbenchClosedSubPanel {
105
+ region: WorkbenchPanelRegion;
106
+ reference: WorkbenchSubPanelRef;
107
+ resource?: ResourceRef;
108
+ title?: string;
109
+ }
84
110
 
85
- declare interface WorkbenchAreaState {
86
- id: WorkbenchArea;
87
- visible: boolean;
88
- size?: number;
89
- widgets: WorkbenchWidgetPlacement[];
90
- activeWidgetId?: string;
111
+ declare interface WorkbenchHistoryPersistence {
112
+ getHistory(scope?: string): PersistedWorkbenchHistory | undefined;
113
+ setHistory(state: PersistedWorkbenchHistory, scope?: string): void;
91
114
  }
92
115
 
93
116
  declare interface WorkbenchLayout {
94
- areas: Record<WorkbenchArea, WorkbenchAreaState>;
117
+ regions: Record<WorkbenchRegion, WorkbenchRegionState>;
118
+ locationSubPanelSelections?: Record<string, Partial<Record<WorkbenchPanelRegion, string>>>;
95
119
  activeWidgetId?: string;
120
+ activeLocationWidgetId?: string;
96
121
  activeResourceUri?: string;
97
122
  }
98
123
 
124
+ declare interface WorkbenchLocationRef {
125
+ key: string;
126
+ modeId?: string;
127
+ resource?: ResourceRef;
128
+ contributionId?: string;
129
+ instanceKey?: string;
130
+ title?: string;
131
+ }
132
+
133
+ declare interface WorkbenchNavigationEntry {
134
+ entryId: string;
135
+ recordedAt: number;
136
+ location: WorkbenchLocationRef;
137
+ selectedSubPanels: Partial<Record<WorkbenchPanelRegion, WorkbenchSubPanelRef>>;
138
+ kind: "resource" | "widget" | "mode";
139
+ modeId?: string;
140
+ resource?: ResourceRef;
141
+ widgetId?: string;
142
+ contributionId?: string;
143
+ title?: string;
144
+ closedSubPanel?: WorkbenchClosedSubPanel;
145
+ }
146
+
147
+ declare type WorkbenchPanelRegion = (typeof workbenchPanelRegions)[number];
148
+
149
+ declare const workbenchPanelRegions: readonly ["main", "secondary", "side"];
150
+
99
151
  declare interface WorkbenchPanelsPersistenceAdapter {
100
- getPanelStates(): PersistedWorkbenchPanels | undefined;
101
- setPanelStates(state: PersistedWorkbenchPanels): void;
152
+ getPanelStates(scope?: string): PersistedWorkbenchPanels | undefined;
153
+ setPanelStates(state: PersistedWorkbenchPanels, scope?: string): void;
154
+ }
155
+
156
+ declare interface WorkbenchPersistenceAdapter {
157
+ getSnapshot(scope?: string): WorkbenchSnapshot | undefined;
158
+ setSnapshot(snapshot: WorkbenchSnapshot, scope?: string): void;
159
+ flush?(): void;
160
+ dispose?(): void;
161
+ }
162
+
163
+ declare type WorkbenchRegion = (typeof workbenchRegions)[number];
164
+
165
+ declare const workbenchRegions: readonly ["nav", "activity", "sidenav-header", "sidenav", "main-header", "main-left-menu", "main", "main-right-menu", "secondary-header", "secondary-left-menu", "secondary", "secondary-right-menu", "side-header", "side-left-menu", "side", "side-right-menu", "status", "overlay"];
166
+
167
+ declare interface WorkbenchRegionState {
168
+ id: WorkbenchRegion;
169
+ visible: boolean;
170
+ size?: number;
171
+ widgets: WorkbenchWidgetPlacement[];
172
+ activeWidgetId?: string;
173
+ }
174
+
175
+ declare interface WorkbenchSnapshot {
176
+ layout: WorkbenchLayout;
102
177
  }
103
178
 
104
179
  export declare interface WorkbenchStorageLike {
@@ -109,7 +184,15 @@ export declare interface WorkbenchStorageLike {
109
184
 
110
185
  export declare const workbenchStoragePersistenceKey: (namespace: string, kind: WorkbenchStoragePersistenceKind, scope: string | undefined) => string;
111
186
 
112
- export declare type WorkbenchStoragePersistenceKind = "layout" | "panels" | "tree" | "last-resource";
187
+ export declare type WorkbenchStoragePersistenceKind = "history" | "layout" | "layout-resource-index" | "panels" | "tree" | "last-resource";
188
+
189
+ declare interface WorkbenchSubPanelRef {
190
+ contributionId: string;
191
+ resourceUri?: string;
192
+ instanceKey?: string;
193
+ }
194
+
195
+ declare type WorkbenchTabRetention = "preview" | "persistent";
113
196
 
114
197
  declare interface WorkbenchWidgetPlacement {
115
198
  widgetId: string;
@@ -118,11 +201,23 @@ declare interface WorkbenchWidgetPlacement {
118
201
  source?: ContributionSource;
119
202
  resource?: ResourceRef;
120
203
  resourceUri?: string;
204
+ ownerResourceUri?: string;
121
205
  title?: string;
122
206
  pinned?: boolean;
123
207
  closable?: boolean;
124
208
  mountStrategy?: WidgetMountStrategy;
125
209
  hiddenByDefault?: boolean;
210
+ tabRetention?: WorkbenchTabRetention;
211
+ tab?: WorkbenchWidgetTab;
212
+ role?: WorkbenchWidgetRole;
213
+ }
214
+
215
+ declare type WorkbenchWidgetRole = "content" | "location" | "sub-panel" | "panel-menu";
216
+
217
+ declare interface WorkbenchWidgetTab {
218
+ contentRendererId?: string;
219
+ /** Custom actions shown when the user activates an already-active tab. */
220
+ customMenuRendererId?: string;
126
221
  }
127
222
 
128
223
  export { }
package/dist/storage.js CHANGED
@@ -1,87 +1,182 @@
1
- const o = (e, t, s) => `${e}:${t}:${s ?? "global"}`, n = () => {
1
+ import { b as E } from "./layout-types-DMoZz38-.js";
2
+ const S = 2, P = 1, b = 50, r = (e, s, t) => `${e}:${s}:${t ?? "global"}`, N = () => {
2
3
  const e = /* @__PURE__ */ new Map();
3
4
  return {
4
- getItem: (t) => e.get(t) ?? null,
5
- setItem: (t, s) => {
6
- e.set(t, s);
5
+ getItem: (s) => e.get(s) ?? null,
6
+ setItem: (s, t) => {
7
+ e.set(s, t);
7
8
  },
8
- removeItem: (t) => {
9
- e.delete(t);
9
+ removeItem: (s) => {
10
+ e.delete(s);
10
11
  }
11
12
  };
12
- }, a = (e) => e || (typeof localStorage < "u" ? localStorage : n()), c = (e, t) => {
13
- const s = e.getItem(t);
14
- if (s)
13
+ }, d = (e) => e || (typeof localStorage < "u" ? localStorage : N()), p = (e, s) => {
14
+ const t = e.getItem(s);
15
+ if (t)
15
16
  try {
16
- return JSON.parse(s);
17
+ return JSON.parse(t);
17
18
  } catch {
18
19
  return;
19
20
  }
20
- }, y = (e) => {
21
- const t = a(e.storage);
21
+ }, T = (e) => {
22
+ const s = d(e.storage), t = /* @__PURE__ */ new Map(), a = e.debounceMs ?? 250, m = e.eventTarget ?? (typeof window < "u" ? {
23
+ addEventListener: (n, o) => window.addEventListener(n, o),
24
+ removeEventListener: (n, o) => window.removeEventListener(n, o)
25
+ } : void 0);
26
+ let l;
27
+ const R = (n) => n?.match(/^project\/([^/]+)\/mode\/[^/]+\/resource\//)?.[1], O = (n) => {
28
+ const o = R(n);
29
+ if (!o || !n) return;
30
+ const y = r(e.namespace, "layout-resource-index", o), c = p(s, y), i = typeof c == "object" && c !== null && "version" in c && c.version === P && "scopes" in c && Array.isArray(c.scopes) ? c.scopes.filter((g) => typeof g == "string" && g !== n && s.getItem(r(e.namespace, "layout", g)) !== null) : [];
31
+ i.push(n);
32
+ for (const g of i.splice(0, Math.max(0, i.length - b)))
33
+ s.removeItem?.(r(e.namespace, "layout", g)), s.removeItem?.(r(e.namespace, "panels", g));
34
+ const v = {
35
+ version: P,
36
+ scopes: i
37
+ };
38
+ s.setItem(y, JSON.stringify(v));
39
+ }, f = () => {
40
+ l && clearTimeout(l), l = void 0;
41
+ const n = [...t.values()];
42
+ t.clear();
43
+ for (const o of n)
44
+ s.setItem(r(e.namespace, "layout", o.scope), o.raw), O(o.scope), o.legacyPanelsKey && s.removeItem?.(o.legacyPanelsKey);
45
+ }, I = () => {
46
+ l && clearTimeout(l), l = setTimeout(f, a);
47
+ };
48
+ return m?.addEventListener("pagehide", f), {
49
+ getLayout: (n) => {
50
+ const o = r(e.namespace, "layout", n), y = t.has(o) ? JSON.parse(t.get(o).raw) : p(s, o);
51
+ if (y?.version === S) return y.layout;
52
+ if (y?.version !== 1) return;
53
+ const c = r(e.namespace, "panels", n), i = p(s, c), v = typeof i == "object" && i !== null && "openByRegionId" in i && typeof i.openByRegionId == "object" && i.openByRegionId !== null ? i.openByRegionId : {}, g = {
54
+ ...y.layout.regions
55
+ };
56
+ for (const u of E) {
57
+ const L = v[u];
58
+ typeof L == "boolean" && g[u] && (g[u] = {
59
+ ...g[u],
60
+ visible: L
61
+ });
62
+ }
63
+ const h = {
64
+ ...y.layout,
65
+ regions: g
66
+ }, w = {
67
+ version: S,
68
+ layout: h
69
+ };
70
+ return t.set(o, {
71
+ legacyPanelsKey: s.getItem(c) === null ? void 0 : c,
72
+ raw: JSON.stringify(w),
73
+ scope: n
74
+ }), I(), h;
75
+ },
76
+ setLayout: (n, o) => {
77
+ const y = {
78
+ version: S,
79
+ layout: n
80
+ }, c = r(e.namespace, "layout", o), i = r(e.namespace, "panels", o);
81
+ t.delete(c), t.set(c, {
82
+ legacyPanelsKey: s.getItem(i) === null ? void 0 : i,
83
+ raw: JSON.stringify(y),
84
+ scope: o
85
+ }), I();
86
+ },
87
+ flush: f,
88
+ dispose() {
89
+ f(), m?.removeEventListener("pagehide", f);
90
+ }
91
+ };
92
+ }, K = (e) => {
93
+ const s = d(e.storage);
22
94
  return {
23
- getLayout: (s) => c(t, o(e.namespace, "layout", s)),
24
- setLayout: (s, r) => {
25
- t.setItem(o(e.namespace, "layout", r), JSON.stringify(s));
95
+ getHistory: (t) => p(s, r(e.namespace, "history", t)),
96
+ setHistory: (t, a) => {
97
+ s.setItem(r(e.namespace, "history", a), JSON.stringify(t));
26
98
  }
27
99
  };
28
- }, g = (e) => {
29
- const t = a(e.storage), s = o(e.namespace, "panels", e.scope);
100
+ }, J = (e) => {
101
+ const s = d(e.storage);
30
102
  return {
31
- getPanelStates: () => c(t, s),
32
- setPanelStates: (r) => {
33
- t.setItem(s, JSON.stringify(r));
103
+ getPanelStates: (t) => p(s, r(e.namespace, "panels", t ?? e.scope)),
104
+ setPanelStates: (t, a) => {
105
+ const m = r(e.namespace, "panels", a ?? e.scope);
106
+ s.setItem(m, JSON.stringify(t));
34
107
  }
35
108
  };
36
- }, l = (e) => {
37
- const t = a(e.storage), s = o(e.namespace, "tree", e.scope);
109
+ }, k = (e) => {
110
+ const s = d(e.storage), t = r(e.namespace, "tree", e.scope);
38
111
  return {
39
- getTreeStates: () => c(t, s),
40
- setTreeStates: (r) => {
41
- t.setItem(s, JSON.stringify(r));
112
+ getTreeStates: () => p(s, t),
113
+ setTreeStates: (a) => {
114
+ s.setItem(t, JSON.stringify(a));
42
115
  }
43
116
  };
44
- }, m = (e) => !!e && typeof e.kind == "string" && typeof e.uri == "string", S = (e) => {
45
- const t = a(e.storage), s = o(e.namespace, "last-resource", e.scope);
117
+ }, B = (e) => !!e && typeof e.kind == "string" && typeof e.uri == "string", M = (e) => {
118
+ const s = d(e.storage), t = r(e.namespace, "last-resource", e.scope);
46
119
  return {
47
120
  getLastResource: () => {
48
- const r = c(t, s);
49
- return m(r) ? r : void 0;
121
+ const a = p(s, t);
122
+ return B(a) ? a : void 0;
50
123
  },
51
- setLastResource: (r) => {
52
- if (!r) {
53
- t.removeItem?.(s);
124
+ setLastResource: (a) => {
125
+ if (!a) {
126
+ s.removeItem?.(t);
54
127
  return;
55
128
  }
56
- t.setItem(s, JSON.stringify(r));
129
+ s.setItem(t, JSON.stringify(a));
57
130
  }
58
131
  };
59
- }, i = (e) => {
60
- const t = a(e.storage);
132
+ }, j = (e) => {
133
+ const s = d(e.storage), t = T({
134
+ debounceMs: e.debounceMs,
135
+ eventTarget: e.eventTarget,
136
+ namespace: e.namespace,
137
+ storage: s
138
+ });
61
139
  return {
62
- panelsPersistence: g({
140
+ snapshotPersistence: {
141
+ getSnapshot: (m) => {
142
+ const l = t.getLayout(m);
143
+ return l ? {
144
+ layout: l
145
+ } : void 0;
146
+ },
147
+ setSnapshot: (m, l) => t.setLayout(m.layout, l),
148
+ flush: t.flush,
149
+ dispose: t.dispose
150
+ },
151
+ historyPersistence: K({
152
+ namespace: e.namespace,
153
+ storage: s
154
+ }),
155
+ layoutPersistence: t,
156
+ panelsPersistence: J({
63
157
  namespace: e.namespace,
64
158
  scope: e.scope ?? "global",
65
- storage: t
159
+ storage: s
66
160
  }),
67
- treePersistence: l({
161
+ treePersistence: k({
68
162
  namespace: e.namespace,
69
163
  scope: e.scope,
70
- storage: t
164
+ storage: s
71
165
  }),
72
- lastResourcePersistence: S({
166
+ lastResourcePersistence: M({
73
167
  namespace: e.namespace,
74
168
  scope: e.scope,
75
- storage: t
169
+ storage: s
76
170
  })
77
171
  };
78
172
  };
79
173
  export {
80
- S as createLocalStorageLastResourcePersistence,
81
- y as createLocalStorageLayoutPersistence,
82
- g as createLocalStoragePanelsPersistence,
83
- l as createLocalStorageTreePersistence,
84
- i as createLocalStorageWorkbenchPersistence,
85
- o as workbenchStoragePersistenceKey
174
+ K as createLocalStorageHistoryPersistence,
175
+ M as createLocalStorageLastResourcePersistence,
176
+ T as createLocalStorageLayoutPersistence,
177
+ J as createLocalStoragePanelsPersistence,
178
+ k as createLocalStorageTreePersistence,
179
+ j as createLocalStorageWorkbenchPersistence,
180
+ r as workbenchStoragePersistenceKey
86
181
  };
87
182
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sources":["../src/storage/local-storage-persistence.ts"],"sourcesContent":["import type {\n LastResourcePersistenceAdapter,\n LayoutPersistenceAdapter,\n PersistedTreeRendererStates,\n PersistedWorkbenchPanels,\n ResourceRef,\n TreeRendererPersistenceAdapter,\n WorkbenchLayout,\n WorkbenchPanelsPersistenceAdapter,\n} from \"../core\";\n\nexport interface WorkbenchStorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem?(key: string): void;\n}\n\nexport type WorkbenchStoragePersistenceKind = \"layout\" | \"panels\" | \"tree\" | \"last-resource\";\n\ninterface CreateWorkbenchStoragePersistenceInput {\n namespace: string;\n storage?: WorkbenchStorageLike;\n}\n\nexport interface CreateLocalStoragePanelsPersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope: string;\n}\n\nexport interface CreateLocalStorageTreePersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nexport interface CreateLocalStorageWorkbenchPersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nexport const workbenchStoragePersistenceKey = (\n namespace: string,\n kind: WorkbenchStoragePersistenceKind,\n scope: string | undefined,\n) => `${namespace}:${kind}:${scope ?? \"global\"}`;\n\nconst createMemoryStorage = (): WorkbenchStorageLike => {\n const map = new Map<string, string>();\n return {\n getItem: (key) => map.get(key) ?? null,\n setItem: (key, value) => {\n map.set(key, value);\n },\n removeItem: (key) => {\n map.delete(key);\n },\n };\n};\n\nconst resolveStorage = (storage?: WorkbenchStorageLike): WorkbenchStorageLike => {\n if (storage) return storage;\n if (typeof localStorage !== \"undefined\") return localStorage;\n return createMemoryStorage();\n};\n\nconst readJson = <T>(storage: WorkbenchStorageLike, key: string): T | undefined => {\n const raw = storage.getItem(key);\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n};\n\nexport const createLocalStorageLayoutPersistence = (\n input: CreateWorkbenchStoragePersistenceInput,\n): LayoutPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n return {\n getLayout: (scope) =>\n readJson<WorkbenchLayout>(storage, workbenchStoragePersistenceKey(input.namespace, \"layout\", scope)),\n setLayout: (layout, scope) => {\n storage.setItem(workbenchStoragePersistenceKey(input.namespace, \"layout\", scope), JSON.stringify(layout));\n },\n };\n};\n\nexport const createLocalStoragePanelsPersistence = (\n input: CreateLocalStoragePanelsPersistenceInput,\n): WorkbenchPanelsPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const key = workbenchStoragePersistenceKey(input.namespace, \"panels\", input.scope);\n return {\n getPanelStates: () => readJson<PersistedWorkbenchPanels>(storage, key),\n setPanelStates: (state) => {\n storage.setItem(key, JSON.stringify(state));\n },\n };\n};\n\nexport const createLocalStorageTreePersistence = (\n input: CreateLocalStorageTreePersistenceInput,\n): TreeRendererPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const key = workbenchStoragePersistenceKey(input.namespace, \"tree\", input.scope);\n return {\n getTreeStates: () => readJson<PersistedTreeRendererStates>(storage, key),\n setTreeStates: (state) => {\n storage.setItem(key, JSON.stringify(state));\n },\n };\n};\n\nexport interface CreateLocalStorageLastResourcePersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nconst isResourceRef = (value: unknown): value is ResourceRef =>\n Boolean(value) && typeof (value as ResourceRef).kind === \"string\" && typeof (value as ResourceRef).uri === \"string\";\n\nexport const createLocalStorageLastResourcePersistence = (\n input: CreateLocalStorageLastResourcePersistenceInput,\n): LastResourcePersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const key = workbenchStoragePersistenceKey(input.namespace, \"last-resource\", input.scope);\n return {\n getLastResource: () => {\n const parsed = readJson<unknown>(storage, key);\n return isResourceRef(parsed) ? parsed : undefined;\n },\n setLastResource: (resource) => {\n if (!resource) {\n storage.removeItem?.(key);\n return;\n }\n storage.setItem(key, JSON.stringify(resource));\n },\n };\n};\n\nexport const createLocalStorageWorkbenchPersistence = (input: CreateLocalStorageWorkbenchPersistenceInput) => {\n const storage = resolveStorage(input.storage);\n\n return {\n panelsPersistence: createLocalStoragePanelsPersistence({\n namespace: input.namespace,\n scope: input.scope ?? \"global\",\n storage,\n }),\n treePersistence: createLocalStorageTreePersistence({\n namespace: input.namespace,\n scope: input.scope,\n storage,\n }),\n lastResourcePersistence: createLocalStorageLastResourcePersistence({\n namespace: input.namespace,\n scope: input.scope,\n storage,\n }),\n };\n};\n"],"names":["workbenchStoragePersistenceKey","namespace","kind","scope","createMemoryStorage","map","Map","getItem","key","get","setItem","value","set","removeItem","delete","resolveStorage","storage","localStorage","readJson","raw","JSON","parse","createLocalStorageLayoutPersistence","input","getLayout","setLayout","layout","stringify","createLocalStoragePanelsPersistence","getPanelStates","setPanelStates","state","createLocalStorageTreePersistence","getTreeStates","setTreeStates","isResourceRef","Boolean","uri","createLocalStorageLastResourcePersistence","getLastResource","parsed","undefined","setLastResource","resource","createLocalStorageWorkbenchPersistence","panelsPersistence","treePersistence","lastResourcePersistence"],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sources":["../src/storage/local-storage-persistence.ts"],"sourcesContent":["import type {\n LastResourcePersistenceAdapter,\n LayoutPersistenceAdapter,\n PersistedTreeRendererStates,\n PersistedWorkbenchHistory,\n PersistedWorkbenchPanels,\n ResourceRef,\n TreeRendererPersistenceAdapter,\n WorkbenchHistoryPersistence,\n WorkbenchLayout,\n WorkbenchPanelsPersistenceAdapter,\n WorkbenchPersistenceAdapter,\n} from \"../core\";\nimport { workbenchRegions } from \"../core\";\n\nexport interface WorkbenchStorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem?(key: string): void;\n}\n\nexport type WorkbenchStoragePersistenceKind =\n | \"history\"\n | \"layout\"\n | \"layout-resource-index\"\n | \"panels\"\n | \"tree\"\n | \"last-resource\";\n\ninterface PersistedWorkbenchLayoutV1 {\n version: 1;\n layout: WorkbenchLayout;\n}\n\ninterface PersistedWorkbenchLayoutV2 {\n version: 2;\n layout: WorkbenchLayout;\n}\n\ntype PersistedWorkbenchLayout = PersistedWorkbenchLayoutV1 | PersistedWorkbenchLayoutV2;\n\nconst WORKBENCH_LAYOUT_VERSION = 2 as const;\nconst WORKBENCH_LAYOUT_RESOURCE_INDEX_VERSION = 1 as const;\nconst WORKBENCH_LAYOUT_RESOURCE_LIMIT = 50;\n\ninterface PersistedWorkbenchLayoutResourceIndex {\n version: 1;\n scopes: string[];\n}\n\ninterface CreateWorkbenchStoragePersistenceInput {\n debounceMs?: number;\n eventTarget?: {\n addEventListener(type: \"pagehide\", listener: () => void): void;\n removeEventListener(type: \"pagehide\", listener: () => void): void;\n };\n namespace: string;\n storage?: WorkbenchStorageLike;\n}\n\nexport interface CreateLocalStoragePanelsPersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope: string;\n}\n\nexport interface CreateLocalStorageTreePersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nexport interface CreateLocalStorageWorkbenchPersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nexport const workbenchStoragePersistenceKey = (\n namespace: string,\n kind: WorkbenchStoragePersistenceKind,\n scope: string | undefined,\n) => `${namespace}:${kind}:${scope ?? \"global\"}`;\n\nconst createMemoryStorage = (): WorkbenchStorageLike => {\n const map = new Map<string, string>();\n return {\n getItem: (key) => map.get(key) ?? null,\n setItem: (key, value) => {\n map.set(key, value);\n },\n removeItem: (key) => {\n map.delete(key);\n },\n };\n};\n\nconst resolveStorage = (storage?: WorkbenchStorageLike): WorkbenchStorageLike => {\n if (storage) return storage;\n if (typeof localStorage !== \"undefined\") return localStorage;\n return createMemoryStorage();\n};\n\nconst readJson = <T>(storage: WorkbenchStorageLike, key: string): T | undefined => {\n const raw = storage.getItem(key);\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n};\n\nexport const createLocalStorageLayoutPersistence = (\n input: CreateWorkbenchStoragePersistenceInput,\n): LayoutPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const pending = new Map<string, { legacyPanelsKey?: string; raw: string; scope: string | undefined }>();\n const debounceMs = input.debounceMs ?? 250;\n const eventTarget =\n input.eventTarget ??\n (typeof window !== \"undefined\"\n ? {\n addEventListener: (type: \"pagehide\", listener: () => void) => window.addEventListener(type, listener),\n removeEventListener: (type: \"pagehide\", listener: () => void) => window.removeEventListener(type, listener),\n }\n : undefined);\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const resourceProjectId = (scope: string | undefined) =>\n scope?.match(/^project\\/([^/]+)\\/mode\\/[^/]+\\/resource\\//)?.[1];\n\n const touchResourceScope = (scope: string | undefined) => {\n const projectId = resourceProjectId(scope);\n if (!projectId || !scope) return;\n\n const indexKey = workbenchStoragePersistenceKey(input.namespace, \"layout-resource-index\", projectId);\n const persisted = readJson<unknown>(storage, indexKey);\n const scopes =\n typeof persisted === \"object\" &&\n persisted !== null &&\n \"version\" in persisted &&\n persisted.version === WORKBENCH_LAYOUT_RESOURCE_INDEX_VERSION &&\n \"scopes\" in persisted &&\n Array.isArray(persisted.scopes)\n ? persisted.scopes.filter(\n (candidate): candidate is string =>\n typeof candidate === \"string\" &&\n candidate !== scope &&\n storage.getItem(workbenchStoragePersistenceKey(input.namespace, \"layout\", candidate)) !== null,\n )\n : [];\n scopes.push(scope);\n\n for (const evictedScope of scopes.splice(0, Math.max(0, scopes.length - WORKBENCH_LAYOUT_RESOURCE_LIMIT))) {\n storage.removeItem?.(workbenchStoragePersistenceKey(input.namespace, \"layout\", evictedScope));\n storage.removeItem?.(workbenchStoragePersistenceKey(input.namespace, \"panels\", evictedScope));\n }\n\n const next: PersistedWorkbenchLayoutResourceIndex = {\n version: WORKBENCH_LAYOUT_RESOURCE_INDEX_VERSION,\n scopes,\n };\n storage.setItem(indexKey, JSON.stringify(next));\n };\n\n const flush = () => {\n if (timer) clearTimeout(timer);\n timer = undefined;\n const writes = [...pending.values()];\n pending.clear();\n for (const write of writes) {\n storage.setItem(workbenchStoragePersistenceKey(input.namespace, \"layout\", write.scope), write.raw);\n touchResourceScope(write.scope);\n if (write.legacyPanelsKey) storage.removeItem?.(write.legacyPanelsKey);\n }\n };\n\n const scheduleFlush = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(flush, debounceMs);\n };\n\n eventTarget?.addEventListener(\"pagehide\", flush);\n\n return {\n getLayout: (scope) => {\n const key = workbenchStoragePersistenceKey(input.namespace, \"layout\", scope);\n const persisted = pending.has(key)\n ? (JSON.parse(pending.get(key)!.raw) as PersistedWorkbenchLayout)\n : readJson<PersistedWorkbenchLayout>(storage, key);\n if (persisted?.version === WORKBENCH_LAYOUT_VERSION) return persisted.layout;\n if (persisted?.version !== 1) return undefined;\n\n const legacyPanelsKey = workbenchStoragePersistenceKey(input.namespace, \"panels\", scope);\n const panels = readJson<unknown>(storage, legacyPanelsKey);\n const openByRegionId =\n typeof panels === \"object\" &&\n panels !== null &&\n \"openByRegionId\" in panels &&\n typeof panels.openByRegionId === \"object\" &&\n panels.openByRegionId !== null\n ? panels.openByRegionId\n : {};\n const regions = { ...persisted.layout.regions };\n for (const region of workbenchRegions) {\n const open = (openByRegionId as Record<string, unknown>)[region];\n if (typeof open === \"boolean\" && regions[region]) {\n regions[region] = { ...regions[region], visible: open };\n }\n }\n const layout = { ...persisted.layout, regions };\n const migrated: PersistedWorkbenchLayoutV2 = { version: WORKBENCH_LAYOUT_VERSION, layout };\n pending.set(key, {\n legacyPanelsKey: storage.getItem(legacyPanelsKey) === null ? undefined : legacyPanelsKey,\n raw: JSON.stringify(migrated),\n scope,\n });\n scheduleFlush();\n return layout;\n },\n setLayout: (layout, scope) => {\n const persisted: PersistedWorkbenchLayoutV2 = { version: WORKBENCH_LAYOUT_VERSION, layout };\n const key = workbenchStoragePersistenceKey(input.namespace, \"layout\", scope);\n const legacyPanelsKey = workbenchStoragePersistenceKey(input.namespace, \"panels\", scope);\n pending.delete(key);\n pending.set(key, {\n legacyPanelsKey: storage.getItem(legacyPanelsKey) === null ? undefined : legacyPanelsKey,\n raw: JSON.stringify(persisted),\n scope,\n });\n scheduleFlush();\n },\n flush,\n dispose() {\n flush();\n eventTarget?.removeEventListener(\"pagehide\", flush);\n },\n };\n};\n\nexport const createLocalStorageHistoryPersistence = (\n input: CreateWorkbenchStoragePersistenceInput,\n): WorkbenchHistoryPersistence => {\n const storage = resolveStorage(input.storage);\n return {\n getHistory: (scope) =>\n readJson<PersistedWorkbenchHistory>(storage, workbenchStoragePersistenceKey(input.namespace, \"history\", scope)),\n setHistory: (history, scope) => {\n storage.setItem(workbenchStoragePersistenceKey(input.namespace, \"history\", scope), JSON.stringify(history));\n },\n };\n};\n\nexport const createLocalStoragePanelsPersistence = (\n input: CreateLocalStoragePanelsPersistenceInput,\n): WorkbenchPanelsPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n return {\n getPanelStates: (scope) =>\n readJson<PersistedWorkbenchPanels>(\n storage,\n workbenchStoragePersistenceKey(input.namespace, \"panels\", scope ?? input.scope),\n ),\n setPanelStates: (state, scope) => {\n const key = workbenchStoragePersistenceKey(input.namespace, \"panels\", scope ?? input.scope);\n storage.setItem(key, JSON.stringify(state));\n },\n };\n};\n\nexport const createLocalStorageTreePersistence = (\n input: CreateLocalStorageTreePersistenceInput,\n): TreeRendererPersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const key = workbenchStoragePersistenceKey(input.namespace, \"tree\", input.scope);\n return {\n getTreeStates: () => readJson<PersistedTreeRendererStates>(storage, key),\n setTreeStates: (state) => {\n storage.setItem(key, JSON.stringify(state));\n },\n };\n};\n\nexport interface CreateLocalStorageLastResourcePersistenceInput extends CreateWorkbenchStoragePersistenceInput {\n scope?: string;\n}\n\nconst isResourceRef = (value: unknown): value is ResourceRef =>\n Boolean(value) && typeof (value as ResourceRef).kind === \"string\" && typeof (value as ResourceRef).uri === \"string\";\n\nexport const createLocalStorageLastResourcePersistence = (\n input: CreateLocalStorageLastResourcePersistenceInput,\n): LastResourcePersistenceAdapter => {\n const storage = resolveStorage(input.storage);\n const key = workbenchStoragePersistenceKey(input.namespace, \"last-resource\", input.scope);\n return {\n getLastResource: () => {\n const parsed = readJson<unknown>(storage, key);\n return isResourceRef(parsed) ? parsed : undefined;\n },\n setLastResource: (resource) => {\n if (!resource) {\n storage.removeItem?.(key);\n return;\n }\n storage.setItem(key, JSON.stringify(resource));\n },\n };\n};\n\nexport const createLocalStorageWorkbenchPersistence = (input: CreateLocalStorageWorkbenchPersistenceInput) => {\n const storage = resolveStorage(input.storage);\n const layoutPersistence = createLocalStorageLayoutPersistence({\n debounceMs: input.debounceMs,\n eventTarget: input.eventTarget,\n namespace: input.namespace,\n storage,\n });\n const snapshotPersistence: WorkbenchPersistenceAdapter = {\n getSnapshot: (scope) => {\n const layout = layoutPersistence.getLayout(scope);\n return layout ? { layout } : undefined;\n },\n setSnapshot: (snapshot, scope) => layoutPersistence.setLayout(snapshot.layout, scope),\n flush: layoutPersistence.flush,\n dispose: layoutPersistence.dispose,\n };\n\n return {\n snapshotPersistence,\n historyPersistence: createLocalStorageHistoryPersistence({\n namespace: input.namespace,\n storage,\n }),\n layoutPersistence,\n panelsPersistence: createLocalStoragePanelsPersistence({\n namespace: input.namespace,\n scope: input.scope ?? \"global\",\n storage,\n }),\n treePersistence: createLocalStorageTreePersistence({\n namespace: input.namespace,\n scope: input.scope,\n storage,\n }),\n lastResourcePersistence: createLocalStorageLastResourcePersistence({\n namespace: input.namespace,\n scope: input.scope,\n storage,\n }),\n };\n};\n"],"names":["WORKBENCH_LAYOUT_VERSION","WORKBENCH_LAYOUT_RESOURCE_INDEX_VERSION","WORKBENCH_LAYOUT_RESOURCE_LIMIT","workbenchStoragePersistenceKey","namespace","kind","scope","createMemoryStorage","map","Map","getItem","key","get","setItem","value","set","removeItem","delete","resolveStorage","storage","localStorage","readJson","raw","JSON","parse","createLocalStorageLayoutPersistence","input","pending","debounceMs","eventTarget","window","addEventListener","type","listener","removeEventListener","undefined","timer","resourceProjectId","match","touchResourceScope","projectId","indexKey","persisted","scopes","version","Array","isArray","filter","candidate","push","evictedScope","splice","Math","max","length","next","stringify","flush","writes","values","clear","write","legacyPanelsKey","scheduleFlush","setTimeout","getLayout","has","layout","panels","openByRegionId","regions","region","workbenchRegions","open","visible","migrated","setLayout","dispose","createLocalStorageHistoryPersistence","getHistory","setHistory","history","createLocalStoragePanelsPersistence","getPanelStates","setPanelStates","state","createLocalStorageTreePersistence","getTreeStates","setTreeStates","isResourceRef","Boolean","uri","createLocalStorageLastResourcePersistence","getLastResource","parsed","setLastResource","resource","createLocalStorageWorkbenchPersistence","layoutPersistence","snapshotPersistence","getSnapshot","setSnapshot","snapshot","historyPersistence","panelsPersistence","treePersistence","lastResourcePersistence"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { b as s } from "./layout-types-DMoZz38-.js";
2
+ const n = (e, a, o) => ({
3
+ role: "anchor",
4
+ anchor: e,
5
+ persistence: a,
6
+ candidates: o
7
+ }), r = (e, a = !1) => a ? {
8
+ role: "projection",
9
+ reads: e,
10
+ navigator: a
11
+ } : {
12
+ role: "projection",
13
+ reads: e
14
+ }, i = {
15
+ role: "chrome"
16
+ }, d = {
17
+ role: "transient"
18
+ }, t = {
19
+ // The top bar hosts breadcrumbs (primary trail) and session status (attached), so it
20
+ // reads both anchors — it is a projection, not inert chrome.
21
+ nav: r(["primary", "attached"]),
22
+ activity: i,
23
+ "sidenav-header": r(["primary"]),
24
+ sidenav: r(["primary"], !0),
25
+ "main-header": r(["primary"]),
26
+ "main-left-menu": r(["primary"]),
27
+ main: n("primary", "primary", "global"),
28
+ "main-right-menu": r(["primary"]),
29
+ "secondary-header": r(["primary"]),
30
+ "secondary-left-menu": r(["secondary"]),
31
+ secondary: n("secondary", "derived", "scoped"),
32
+ "secondary-right-menu": r(["secondary"]),
33
+ status: r(["primary", "attached"]),
34
+ overlay: d,
35
+ "side-header": r(["attached"]),
36
+ "side-left-menu": r(["attached"]),
37
+ side: n("attached", "detached", "scoped"),
38
+ "side-right-menu": r(["attached"])
39
+ }, m = (e) => t[e], y = () => s.filter((e) => t[e].role === "anchor"), l = (e) => {
40
+ const a = s.find((o) => {
41
+ const c = t[o];
42
+ return c.role === "anchor" && c.anchor === e;
43
+ });
44
+ if (!a) throw new Error(`No region hosts anchor: ${e}`);
45
+ return a;
46
+ };
47
+ export {
48
+ m as g,
49
+ y as l,
50
+ l as r
51
+ };
52
+ //# sourceMappingURL=surface-map-C1pOTUmF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-map-C1pOTUmF.js","sources":["../src/core/registries/layout/surface-map.ts"],"sourcesContent":["import { type WorkbenchRegion, workbenchRegions } from \"./layout-types\";\n\n// The surface map describes the *behavioural* role of each workbench region: which\n// regions host a resource (anchors), which render an anchor's resource (projections),\n// and which are frame chrome or the transient overlay layer. The project scope root is\n// not a surface; it is handled by the layout persistence scope.\n\n// Logical anchor identity, independent of the region id that currently hosts it.\nexport type AnchorId = \"primary\" | \"secondary\" | \"attached\";\n\n// Does an anchor's active selection survive a primary change?\n// - primary: the subject itself.\n// - derived: re-scopes/clears on primary change (terminals follow the workspace).\n// - detached: persists across primary navigation, but disconnects when the new\n// primary's scoped candidates no longer list it (scope wins).\nexport type AnchorPersistence = \"primary\" | \"derived\" | \"detached\";\n\n// What the anchor's quick-pick offers: everything, or filtered by primary.\nexport type AnchorCandidates = \"global\" | \"scoped\";\n\n// Which anchor(s) a projection renders.\nexport type AnchorReadId = AnchorId;\n\nexport interface AnchorSurface {\n role: \"anchor\";\n anchor: AnchorId;\n persistence: AnchorPersistence;\n candidates: AnchorCandidates;\n}\n\nexport interface ProjectionSurface {\n role: \"projection\";\n reads: AnchorReadId[];\n // The sidenav navigator both reads primary (highlight) and selects it (the picker).\n navigator?: boolean;\n}\n\nexport interface ChromeSurface {\n role: \"chrome\";\n}\n\nexport interface TransientSurface {\n role: \"transient\";\n}\n\nexport type SurfaceDescriptor = AnchorSurface | ProjectionSurface | ChromeSurface | TransientSurface;\n\nconst anchor = (anchor: AnchorId, persistence: AnchorPersistence, candidates: AnchorCandidates): AnchorSurface => ({\n role: \"anchor\",\n anchor,\n persistence,\n candidates,\n});\n\nconst projection = (reads: AnchorReadId[], navigator = false): ProjectionSurface =>\n navigator ? { role: \"projection\", reads, navigator } : { role: \"projection\", reads };\n\nconst chrome: ChromeSurface = { role: \"chrome\" };\nconst transient: TransientSurface = { role: \"transient\" };\n\nexport const surfaceMap: Record<WorkbenchRegion, SurfaceDescriptor> = {\n // The top bar hosts breadcrumbs (primary trail) and session status (attached), so it\n // reads both anchors — it is a projection, not inert chrome.\n nav: projection([\"primary\", \"attached\"]),\n activity: chrome,\n \"sidenav-header\": projection([\"primary\"]),\n sidenav: projection([\"primary\"], true),\n \"main-header\": projection([\"primary\"]),\n \"main-left-menu\": projection([\"primary\"]),\n main: anchor(\"primary\", \"primary\", \"global\"),\n \"main-right-menu\": projection([\"primary\"]),\n \"secondary-header\": projection([\"primary\"]),\n \"secondary-left-menu\": projection([\"secondary\"]),\n secondary: anchor(\"secondary\", \"derived\", \"scoped\"),\n \"secondary-right-menu\": projection([\"secondary\"]),\n status: projection([\"primary\", \"attached\"]),\n overlay: transient,\n \"side-header\": projection([\"attached\"]),\n \"side-left-menu\": projection([\"attached\"]),\n side: anchor(\"attached\", \"detached\", \"scoped\"),\n \"side-right-menu\": projection([\"attached\"]),\n};\n\nexport const getSurface = (region: WorkbenchRegion) => surfaceMap[region];\n\nexport const listAnchorRegions = () =>\n workbenchRegions.filter((region): region is WorkbenchRegion => surfaceMap[region].role === \"anchor\");\n\nexport const listProjectionRegions = () =>\n workbenchRegions.filter((region): region is WorkbenchRegion => surfaceMap[region].role === \"projection\");\n\nexport const listProjectionsReading = (anchorId: AnchorReadId) =>\n workbenchRegions.filter((region) => {\n const surface = surfaceMap[region];\n return surface.role === \"projection\" && surface.reads.includes(anchorId);\n });\n\n// Reverse lookup: which region currently hosts a given logical anchor.\nexport const resolveAnchorRegion = (anchorId: AnchorId) => {\n const region = workbenchRegions.find((candidate) => {\n const surface = surfaceMap[candidate];\n return surface.role === \"anchor\" && surface.anchor === anchorId;\n });\n if (!region) throw new Error(`No region hosts anchor: ${anchorId}`);\n return region;\n};\n"],"names":["anchor","persistence","candidates","role","projection","reads","navigator","chrome","transient","surfaceMap","nav","activity","sidenav","main","secondary","status","overlay","side","getSurface","region","listAnchorRegions","workbenchRegions","filter","resolveAnchorRegion","anchorId","find","candidate","surface","Error"],"mappings":";AA+CA,MAAMA,IAASA,CAACA,GAAkBC,GAAgCC,OAAiD;AAAA,EACjHC,MAAM;AAAA,EACNH,QAAAA;AAAAA,EACAC,aAAAA;AAAAA,EACAC,YAAAA;AACF,IAEME,IAAaA,CAACC,GAAuBC,IAAY,OACrDA,IAAY;AAAA,EAAEH,MAAM;AAAA,EAAcE,OAAAA;AAAAA,EAAOC,WAAAA;AAAU,IAAI;AAAA,EAAEH,MAAM;AAAA,EAAcE,OAAAA;AAAM,GAE/EE,IAAwB;AAAA,EAAEJ,MAAM;AAAS,GACzCK,IAA8B;AAAA,EAAEL,MAAM;AAAY,GAE3CM,IAAyD;AAAA;AAAA;AAAA,EAGpEC,KAAKN,EAAW,CAAC,WAAW,UAAU,CAAC;AAAA,EACvCO,UAAUJ;AAAAA,EACV,kBAAkBH,EAAW,CAAC,SAAS,CAAC;AAAA,EACxCQ,SAASR,EAAW,CAAC,SAAS,GAAG,EAAI;AAAA,EACrC,eAAeA,EAAW,CAAC,SAAS,CAAC;AAAA,EACrC,kBAAkBA,EAAW,CAAC,SAAS,CAAC;AAAA,EACxCS,MAAMb,EAAO,WAAW,WAAW,QAAQ;AAAA,EAC3C,mBAAmBI,EAAW,CAAC,SAAS,CAAC;AAAA,EACzC,oBAAoBA,EAAW,CAAC,SAAS,CAAC;AAAA,EAC1C,uBAAuBA,EAAW,CAAC,WAAW,CAAC;AAAA,EAC/CU,WAAWd,EAAO,aAAa,WAAW,QAAQ;AAAA,EAClD,wBAAwBI,EAAW,CAAC,WAAW,CAAC;AAAA,EAChDW,QAAQX,EAAW,CAAC,WAAW,UAAU,CAAC;AAAA,EAC1CY,SAASR;AAAAA,EACT,eAAeJ,EAAW,CAAC,UAAU,CAAC;AAAA,EACtC,kBAAkBA,EAAW,CAAC,UAAU,CAAC;AAAA,EACzCa,MAAMjB,EAAO,YAAY,YAAY,QAAQ;AAAA,EAC7C,mBAAmBI,EAAW,CAAC,UAAU,CAAC;AAC5C,GAEac,IAAaA,CAACC,MAA4BV,EAAWU,CAAM,GAE3DC,IAAoBA,MAC/BC,EAAiBC,OAAO,CAACH,MAAsCV,EAAWU,CAAM,EAAEhB,SAAS,QAAQ,GAYxFoB,IAAsBA,CAACC,MAAuB;AACzD,QAAML,IAASE,EAAiBI,KAAMC,CAAAA,MAAc;AAClD,UAAMC,IAAUlB,EAAWiB,CAAS;AACpC,WAAOC,EAAQxB,SAAS,YAAYwB,EAAQ3B,WAAWwB;AAAAA,EACzD,CAAC;AACD,MAAI,CAACL,EAAQ,OAAM,IAAIS,MAAM,2BAA2BJ,CAAQ,EAAE;AAClE,SAAOL;AACT;"}