quilt-core 0.4.0 → 0.6.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.
- package/dist/controller.d.ts +11 -3
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +91 -15
- package/dist/controller.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +11 -1
- package/dist/model.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/controller.ts +91 -16
- package/src/index.ts +1 -0
- package/src/model.ts +11 -1
- package/src/types.ts +11 -1
package/dist/controller.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AutoCollapse, LayoutStoreOptions, JoinOptions, Axis, Capability, Change, CommandOptions, Group, Layout, Pane, WindowPlacement } from './types.js';
|
|
1
|
+
import type { AutoCollapse, LayoutStoreOptions, JoinOptions, Axis, Capability, CapabilityPolicy, Change, CommandOptions, Group, Layout, Pane, WindowPlacement } from './types.js';
|
|
2
2
|
export declare class LayoutStore {
|
|
3
3
|
private state;
|
|
4
4
|
private initial;
|
|
@@ -10,6 +10,7 @@ export declare class LayoutStore {
|
|
|
10
10
|
private notifying;
|
|
11
11
|
private pending;
|
|
12
12
|
private autoCollapse;
|
|
13
|
+
private capabilities;
|
|
13
14
|
constructor(input: unknown, options?: LayoutStoreOptions);
|
|
14
15
|
/** Stable immutable snapshot, suitable for useSyncExternalStore. */
|
|
15
16
|
getSnapshot: () => Layout;
|
|
@@ -28,7 +29,14 @@ export declare class LayoutStore {
|
|
|
28
29
|
getAutoCollapse(): AutoCollapse;
|
|
29
30
|
setAutoCollapse(mode: AutoCollapse): void;
|
|
30
31
|
private tidy;
|
|
32
|
+
/** Replace session policy; layout export/load never serializes or resets it. */
|
|
33
|
+
setCapabilities(policy?: CapabilityPolicy): void;
|
|
34
|
+
private canPane;
|
|
31
35
|
can(paneId: string, capability: Capability): boolean;
|
|
36
|
+
private canNodeIn;
|
|
37
|
+
/** Test every affected tab, including policy on empty regions. */
|
|
38
|
+
canNode(nodeId: string, capability: Capability): boolean;
|
|
39
|
+
private permitNode;
|
|
32
40
|
load(input: unknown): void;
|
|
33
41
|
reset(): void;
|
|
34
42
|
setTabDisplay(groupId: string, display: Group['tabDisplay']): void;
|
|
@@ -37,7 +45,7 @@ export declare class LayoutStore {
|
|
|
37
45
|
resize(splitId: string, ratio: number, options?: CommandOptions): void;
|
|
38
46
|
/** Atomically update coupled split ratios without intermediate layouts. */
|
|
39
47
|
resizeMany(ratios: Record<string, number>, options?: CommandOptions): void;
|
|
40
|
-
maximize(groupId: string | null): void;
|
|
48
|
+
maximize(groupId: string | null, options?: CommandOptions): void;
|
|
41
49
|
add(pane: Pane, groupId: string, options?: CommandOptions): void;
|
|
42
50
|
updatePane(pane: Pane): void;
|
|
43
51
|
split(groupId: string, axis: Axis, pane: Pane | null, options?: CommandOptions & {
|
|
@@ -45,7 +53,7 @@ export declare class LayoutStore {
|
|
|
45
53
|
ratio?: number;
|
|
46
54
|
}): string;
|
|
47
55
|
/** Cancel only an unfilled region; never roll back edits made elsewhere. */
|
|
48
|
-
removeEmptyGroup(groupId: string): void;
|
|
56
|
+
removeEmptyGroup(groupId: string, options?: CommandOptions): void;
|
|
49
57
|
/** Move to a tab group or to a new split at an edge. */
|
|
50
58
|
move(paneId: string, groupId: string, position?: 'tab' | 'left' | 'right' | 'top' | 'bottom', index?: number, options?: CommandOptions): void;
|
|
51
59
|
/** Join the sibling region at this split, retaining its content as tabs. */
|
package/dist/controller.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,IAAI,EACJ,UAAU,EACV,MAAM,EACN,cAAc,EACd,KAAK,EACL,MAAM,EAEN,IAAI,EACJ,eAAe,EAChB,MAAM,YAAY,CAAC;AAWpB,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,UAAU,CAAwD;IAC1E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAA4B;IAChD,YAAY,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAuB,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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"}
|
package/dist/controller.js
CHANGED
|
@@ -22,7 +22,9 @@ export class LayoutStore {
|
|
|
22
22
|
notifying = false;
|
|
23
23
|
pending = [];
|
|
24
24
|
autoCollapse = 'disabled';
|
|
25
|
+
capabilities = {};
|
|
25
26
|
constructor(input, options = {}) {
|
|
27
|
+
this.setCapabilities(options.capabilities);
|
|
26
28
|
this.setAutoCollapse(options.autoCollapse ?? 'disabled');
|
|
27
29
|
this.state = freeze(parseLayout(input));
|
|
28
30
|
this.initial = this.export();
|
|
@@ -128,7 +130,7 @@ export class LayoutStore {
|
|
|
128
130
|
}
|
|
129
131
|
permit(draft, ids, cap, options) {
|
|
130
132
|
for (const id of ids)
|
|
131
|
-
if (options.source === 'user' && this.
|
|
133
|
+
if (options.source === 'user' && !this.canPane(draft, id, cap))
|
|
132
134
|
problem(`${cap} is disabled for ${id}`);
|
|
133
135
|
}
|
|
134
136
|
id(draft) {
|
|
@@ -176,9 +178,80 @@ export class LayoutStore {
|
|
|
176
178
|
if (draft.maximized && !findNode(draft.root, draft.maximized))
|
|
177
179
|
draft.maximized = null;
|
|
178
180
|
}
|
|
181
|
+
/** Replace session policy; layout export/load never serializes or resets it. */
|
|
182
|
+
setCapabilities(policy = {}) {
|
|
183
|
+
this.alive();
|
|
184
|
+
const flags = (value) => {
|
|
185
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
186
|
+
problem('Invalid capabilities');
|
|
187
|
+
for (const [key, flag] of Object.entries(value))
|
|
188
|
+
if (![
|
|
189
|
+
'resize',
|
|
190
|
+
'move',
|
|
191
|
+
'reorder',
|
|
192
|
+
'addTab',
|
|
193
|
+
'maximize',
|
|
194
|
+
'split',
|
|
195
|
+
'join',
|
|
196
|
+
'close',
|
|
197
|
+
'popout',
|
|
198
|
+
].includes(key) ||
|
|
199
|
+
typeof flag !== 'boolean')
|
|
200
|
+
problem('Invalid capability: ' + key);
|
|
201
|
+
};
|
|
202
|
+
if (!policy || typeof policy !== 'object' || Array.isArray(policy))
|
|
203
|
+
problem('Invalid capability policy');
|
|
204
|
+
for (const [key, value] of Object.entries(policy)) {
|
|
205
|
+
if (value === undefined)
|
|
206
|
+
continue;
|
|
207
|
+
if (key === 'defaults')
|
|
208
|
+
flags(value);
|
|
209
|
+
else if (key === 'groups' || key === 'panes') {
|
|
210
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
211
|
+
problem('Invalid capability overrides');
|
|
212
|
+
Object.values(value).forEach(flags);
|
|
213
|
+
}
|
|
214
|
+
else
|
|
215
|
+
problem('Unknown capability scope: ' + key);
|
|
216
|
+
}
|
|
217
|
+
this.capabilities = structuredClone(policy);
|
|
218
|
+
}
|
|
219
|
+
canPane(layout, paneId, capability) {
|
|
220
|
+
const pane = layout.panes[paneId];
|
|
221
|
+
if (!pane)
|
|
222
|
+
return false;
|
|
223
|
+
const groupId = groups(layout.root).find((g) => g.panes.includes(paneId))?.id ??
|
|
224
|
+
layout.popouts.find((p) => p.paneId === paneId)?.groupId;
|
|
225
|
+
return (this.capabilities.panes?.[paneId]?.[capability] ??
|
|
226
|
+
pane.capabilities?.[capability] ??
|
|
227
|
+
(groupId ? this.capabilities.groups?.[groupId]?.[capability] : undefined) ??
|
|
228
|
+
this.capabilities.defaults?.[capability] ??
|
|
229
|
+
(capability === 'addTab' || capability === 'reorder'
|
|
230
|
+
? this.canPane(layout, paneId, 'move')
|
|
231
|
+
: true));
|
|
232
|
+
}
|
|
179
233
|
can(paneId, capability) {
|
|
180
|
-
return (
|
|
181
|
-
|
|
234
|
+
return this.canPane(this.state, paneId, capability);
|
|
235
|
+
}
|
|
236
|
+
canNodeIn(layout, node, capability) {
|
|
237
|
+
if (node.kind === 'split')
|
|
238
|
+
return node.children.every((child) => this.canNodeIn(layout, child, capability));
|
|
239
|
+
return node.panes.length
|
|
240
|
+
? node.panes.every((id) => this.canPane(layout, id, capability))
|
|
241
|
+
: (this.capabilities.groups?.[node.id]?.[capability] ??
|
|
242
|
+
this.capabilities.defaults?.[capability] ??
|
|
243
|
+
(capability === 'addTab' || capability === 'reorder'
|
|
244
|
+
? this.canNodeIn(layout, node, 'move')
|
|
245
|
+
: true));
|
|
246
|
+
}
|
|
247
|
+
/** Test every affected tab, including policy on empty regions. */
|
|
248
|
+
canNode(nodeId, capability) {
|
|
249
|
+
const node = findNode(this.state.root, nodeId);
|
|
250
|
+
return !!node && this.canNodeIn(this.state, node, capability);
|
|
251
|
+
}
|
|
252
|
+
permitNode(layout, node, capability, options) {
|
|
253
|
+
if (options.source === 'user' && !this.canNodeIn(layout, node, capability))
|
|
254
|
+
problem(`${capability} is disabled for ${node.id}`);
|
|
182
255
|
}
|
|
183
256
|
load(input) {
|
|
184
257
|
this.commit('load', (draft) => {
|
|
@@ -226,7 +299,7 @@ export class LayoutStore {
|
|
|
226
299
|
const n = findNode(d.root, splitId);
|
|
227
300
|
if (n?.kind !== 'split')
|
|
228
301
|
problem('Split not found');
|
|
229
|
-
this.
|
|
302
|
+
this.permitNode(d, n, 'resize', options);
|
|
230
303
|
n.ratio = ratio;
|
|
231
304
|
});
|
|
232
305
|
}
|
|
@@ -237,22 +310,22 @@ export class LayoutStore {
|
|
|
237
310
|
const node = findNode(d.root, id);
|
|
238
311
|
if (node?.kind !== 'split')
|
|
239
312
|
problem('Split not found');
|
|
240
|
-
this.
|
|
313
|
+
this.permitNode(d, node, 'resize', options);
|
|
241
314
|
node.ratio = ratio;
|
|
242
315
|
}
|
|
243
316
|
});
|
|
244
317
|
}
|
|
245
|
-
maximize(groupId) {
|
|
318
|
+
maximize(groupId, options = {}) {
|
|
246
319
|
this.commit('maximize', (d) => {
|
|
247
320
|
if (groupId)
|
|
248
|
-
this.group(d, groupId);
|
|
321
|
+
this.permitNode(d, this.group(d, groupId), 'maximize', options);
|
|
249
322
|
d.maximized = groupId;
|
|
250
323
|
});
|
|
251
324
|
}
|
|
252
325
|
add(pane, groupId, options = {}) {
|
|
253
326
|
this.commit('add', (d) => {
|
|
254
327
|
const g = this.group(d, groupId);
|
|
255
|
-
this.
|
|
328
|
+
this.permitNode(d, g, 'addTab', options);
|
|
256
329
|
if (Object.hasOwn(d.panes, pane.id))
|
|
257
330
|
problem('Pane id already exists');
|
|
258
331
|
Object.defineProperty(d.panes, pane.id, {
|
|
@@ -275,7 +348,7 @@ export class LayoutStore {
|
|
|
275
348
|
let created = '';
|
|
276
349
|
this.commit('split', (d) => {
|
|
277
350
|
const g = this.group(d, groupId);
|
|
278
|
-
this.
|
|
351
|
+
this.permitNode(d, g, 'split', options);
|
|
279
352
|
if (pane) {
|
|
280
353
|
if (Object.hasOwn(d.panes, pane.id))
|
|
281
354
|
problem('Pane id already exists');
|
|
@@ -304,13 +377,14 @@ export class LayoutStore {
|
|
|
304
377
|
return created;
|
|
305
378
|
}
|
|
306
379
|
/** Cancel only an unfilled region; never roll back edits made elsewhere. */
|
|
307
|
-
removeEmptyGroup(groupId) {
|
|
380
|
+
removeEmptyGroup(groupId, options = {}) {
|
|
308
381
|
const existing = findNode(this.state.root, groupId);
|
|
309
382
|
if (existing?.kind !== 'group' ||
|
|
310
383
|
existing.panes.length ||
|
|
311
384
|
!findParent(this.state.root, groupId))
|
|
312
385
|
return;
|
|
313
386
|
this.commit('removeEmptyGroup', (d) => {
|
|
387
|
+
this.permitNode(d, this.group(d, groupId), 'close', options);
|
|
314
388
|
if (d.maximized === groupId)
|
|
315
389
|
d.maximized = null;
|
|
316
390
|
const parent = findParent(d.root, groupId);
|
|
@@ -324,9 +398,11 @@ export class LayoutStore {
|
|
|
324
398
|
const source = groups(d.root).find((g) => g.panes.includes(paneId));
|
|
325
399
|
if (!source)
|
|
326
400
|
problem('Return a popped-out pane before moving it');
|
|
327
|
-
|
|
401
|
+
const capability = source === target && position === 'tab' ? 'reorder' : 'move';
|
|
402
|
+
this.permit(d, [paneId], capability, options);
|
|
403
|
+
this.permitNode(d, target, capability, options);
|
|
328
404
|
if (position !== 'tab')
|
|
329
|
-
this.
|
|
405
|
+
this.permitNode(d, target, 'split', options);
|
|
330
406
|
if (source === target && target.panes.length === 1)
|
|
331
407
|
return;
|
|
332
408
|
this.detach(d, paneId);
|
|
@@ -354,7 +430,7 @@ export class LayoutStore {
|
|
|
354
430
|
const g = this.group(d, groupId), parent = findParent(d.root, groupId);
|
|
355
431
|
if (!parent)
|
|
356
432
|
return;
|
|
357
|
-
this.
|
|
433
|
+
this.permitNode(d, parent, 'join', options);
|
|
358
434
|
g.panes = paneIds(parent);
|
|
359
435
|
g.active ??= g.panes[0] ?? null;
|
|
360
436
|
this.replace(d, parent, g);
|
|
@@ -365,7 +441,7 @@ export class LayoutStore {
|
|
|
365
441
|
closeGroup(groupId, options = {}) {
|
|
366
442
|
this.commit('closeGroup', (d) => {
|
|
367
443
|
const group = this.group(d, groupId);
|
|
368
|
-
this.
|
|
444
|
+
this.permitNode(d, group, 'close', options);
|
|
369
445
|
for (const id of group.panes)
|
|
370
446
|
delete d.panes[id];
|
|
371
447
|
group.panes = [];
|
|
@@ -386,7 +462,7 @@ export class LayoutStore {
|
|
|
386
462
|
problem('Join requires contiguous regions in one row or column');
|
|
387
463
|
const { row, regions, boundaries, start, end, selected } = range;
|
|
388
464
|
const panes = selected.flatMap((g) => g.panes);
|
|
389
|
-
this.
|
|
465
|
+
selected.forEach((group) => this.permitNode(d, group, 'join', options));
|
|
390
466
|
let sizes = range.weights;
|
|
391
467
|
let gaps = boundaries.map(() => 0);
|
|
392
468
|
if (options.extents) {
|
package/dist/controller.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { joinRange } from './join.js';\nimport { findNode, findParent, groups, paneIds, parseLayout, validate } from './model.js';\nimport { LayoutError } from './types.js';\nimport type {\n AutoCollapse,\n LayoutStoreOptions,\n JoinOptions,\n Axis,\n Capability,\n Change,\n CommandOptions,\n Group,\n Layout,\n Node,\n Pane,\n WindowPlacement,\n} from './types.js';\nconst freeze = <T>(value: T): T => {\n if (value && typeof value === 'object') {\n Object.freeze(value);\n Object.values(value).forEach(freeze);\n }\n return value;\n};\nfunction problem(message: string): never {\n throw new LayoutError([{ path: 'command', message }]);\n}\nexport class LayoutStore {\n private state: Layout;\n private initial: Layout;\n private listeners = new Set<(event: Change) => void>();\n private errors = new Set<(error: unknown) => void>();\n private disposed = false;\n private serial = 0;\n private closedTabs: { pane: Pane; groupId: string; index: number }[] = [];\n private notifying = false;\n private pending: Change[] = [];\n private autoCollapse: AutoCollapse = 'disabled';\n constructor(input: unknown, options: LayoutStoreOptions = {}) {\n this.setAutoCollapse(options.autoCollapse ?? 'disabled');\n this.state = freeze(parseLayout(input));\n this.initial = this.export();\n }\n /** Stable immutable snapshot, suitable for useSyncExternalStore. */\n getSnapshot = (): Layout => this.state;\n export(): Layout {\n return structuredClone(this.state);\n }\n subscribe = (listener: (event: Change) => void): (() => void) => {\n this.alive();\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n onError(listener: (error: unknown) => void): () => void {\n this.errors.add(listener);\n return () => {\n this.errors.delete(listener);\n };\n }\n private alive() {\n if (this.disposed) problem('Store has been disposed');\n }\n private report(error: unknown) {\n for (const listener of this.errors) {\n try {\n listener(error);\n } catch {\n /* A reporting callback cannot invalidate a committed layout. */\n }\n }\n }\n private commit(action: string, mutate: (draft: Layout) => void) {\n this.alive();\n let next: Layout;\n try {\n next = this.export();\n mutate(next);\n next = parseLayout(next);\n } catch (error) {\n this.report(error);\n throw error;\n }\n // Update session history only after validation, before notifying subscribers.\n if (action === 'load') this.closedTabs = [];\n if (action === 'close' || action === 'closeGroup') {\n for (const pane of Object.values(this.state.panes)) {\n if (Object.hasOwn(next.panes, pane.id)) continue;\n const group = groups(this.state.root).find((g) => g.panes.includes(pane.id));\n const detached = this.state.popouts.find((p) => p.paneId === pane.id);\n this.closedTabs.push({\n pane: structuredClone(pane),\n groupId: group?.id ?? detached!.groupId,\n index: group ? group.panes.indexOf(pane.id) : detached!.index,\n });\n }\n this.closedTabs = this.closedTabs.slice(-50);\n }\n if (action === 'restoreClosedTab') {\n this.closedTabs = this.closedTabs.filter(\n (entry) => !Object.hasOwn(next.panes, entry.pane.id),\n );\n }\n this.state = freeze(next);\n this.pending.push({ action, layout: this.state });\n if (this.notifying) return;\n this.notifying = true;\n try {\n while (this.pending.length) {\n const event = this.pending.shift()!;\n for (const listener of [...this.listeners]) {\n if (!this.listeners.has(listener)) continue;\n try {\n listener(event);\n } catch (error) {\n this.report(error);\n }\n }\n }\n } finally {\n this.notifying = false;\n }\n }\n\n private group(draft: Layout, id: string): Group {\n const n = findNode(draft.root, id);\n if (n?.kind !== 'group') problem('Group not found: ' + id);\n return n;\n }\n private pane(draft: Layout, id: string): Pane {\n if (!Object.hasOwn(draft.panes, id)) problem('Pane not found: ' + id);\n return draft.panes[id]!;\n }\n private permit(draft: Layout, ids: string[], cap: Capability, options: CommandOptions) {\n for (const id of ids)\n if (options.source === 'user' && this.pane(draft, id).capabilities?.[cap] === false)\n problem(`${cap} is disabled for ${id}`);\n }\n private id(draft: Layout): string {\n let id: string;\n do {\n id = `layout-${++this.serial}`;\n } while (findNode(draft.root, id));\n return id;\n }\n private replace(draft: Layout, old: Node, next: Node) {\n const parent = findParent(draft.root, old.id);\n if (parent) parent.children[parent.children[0].id === old.id ? 0 : 1] = next;\n else draft.root = next;\n }\n private detach(draft: Layout, id: string): Group {\n const g = groups(draft.root).find((n) => n.panes.includes(id));\n if (!g) problem('Pane is not docked: ' + id);\n const at = g.panes.indexOf(id);\n g.panes.splice(at, 1);\n if (g.active === id) g.active = g.panes[Math.min(at, g.panes.length - 1)] ?? null;\n return g;\n }\n getAutoCollapse(): AutoCollapse {\n return this.autoCollapse;\n }\n setAutoCollapse(mode: AutoCollapse): void {\n this.alive();\n if (!['enabled', 'protected', 'disabled'].includes(mode)) problem('Invalid autoCollapse mode');\n this.autoCollapse = mode;\n }\n private tidy(draft: Layout, source?: Group, popout = false) {\n if (\n source &&\n !source.panes.length &&\n this.autoCollapse !== 'disabled' &&\n (!popout || this.autoCollapse === 'enabled')\n ) {\n const parent = findParent(draft.root, source.id);\n if (parent)\n this.replace(draft, parent, parent.children[parent.children[0].id === source.id ? 1 : 0]);\n }\n if (draft.maximized && !findNode(draft.root, draft.maximized)) draft.maximized = null;\n }\n can(paneId: string, capability: Capability): boolean {\n return (\n Boolean(this.state.panes[paneId]) &&\n this.state.panes[paneId]!.capabilities?.[capability] !== false\n );\n }\n load(input: unknown) {\n this.commit('load', (draft) => {\n const next = parseLayout(input);\n for (const key of Object.keys(draft)) Reflect.deleteProperty(draft, key);\n Object.assign(draft, next);\n });\n }\n reset() {\n this.load(this.initial);\n }\n setTabDisplay(groupId: string, display: Group['tabDisplay']) {\n this.commit('setTabDisplay', (draft) => {\n const group = findNode(draft.root, groupId);\n if (!group || group.kind !== 'group') problem('Expected a group id');\n if (display === undefined) delete group.tabDisplay;\n else group.tabDisplay = display;\n });\n }\n setTabPlacement(groupId: string, placement: Group['tabPlacement']) {\n this.commit('setTabPlacement', (draft) => {\n const group = findNode(draft.root, groupId);\n if (!group || group.kind !== 'group') problem('Expected a group id');\n if (placement === undefined) delete group.tabPlacement;\n else group.tabPlacement = placement;\n });\n }\n activate(groupId: string, paneId: string) {\n this.commit('activate', (d) => {\n const g = this.group(d, groupId);\n if (!g.panes.includes(paneId)) problem('Tab does not belong to group');\n g.active = paneId;\n });\n }\n resize(splitId: string, ratio: number, options: CommandOptions = {}) {\n this.commit('resize', (d) => {\n const n = findNode(d.root, splitId);\n if (n?.kind !== 'split') problem('Split not found');\n this.permit(d, paneIds(n), 'resize', options);\n n.ratio = ratio;\n });\n }\n /** Atomically update coupled split ratios without intermediate layouts. */\n resizeMany(ratios: Record<string, number>, options: CommandOptions = {}) {\n this.commit('resize', (d) => {\n for (const [id, ratio] of Object.entries(ratios)) {\n const node = findNode(d.root, id);\n if (node?.kind !== 'split') problem('Split not found');\n this.permit(d, paneIds(node), 'resize', options);\n node.ratio = ratio;\n }\n });\n }\n maximize(groupId: string | null) {\n this.commit('maximize', (d) => {\n if (groupId) this.group(d, groupId);\n d.maximized = groupId;\n });\n }\n add(pane: Pane, groupId: string, options: CommandOptions = {}) {\n this.commit('add', (d) => {\n const g = this.group(d, groupId);\n this.permit(d, g.panes, 'move', options);\n if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');\n Object.defineProperty(d.panes, pane.id, {\n value: structuredClone(pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n g.panes.push(pane.id);\n g.active = pane.id;\n });\n }\n updatePane(pane: Pane) {\n this.commit('updatePane', (d) => {\n this.pane(d, pane.id);\n d.panes[pane.id] = structuredClone(pane);\n });\n }\n split(\n groupId: string,\n axis: Axis,\n pane: Pane | null,\n options: CommandOptions & { before?: boolean; ratio?: number } = {},\n ) {\n let created = '';\n this.commit('split', (d) => {\n const g = this.group(d, groupId);\n this.permit(d, g.panes, 'split', options);\n if (pane) {\n if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');\n Object.defineProperty(d.panes, pane.id, {\n value: structuredClone(pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n const group: Group = {\n kind: 'group',\n id: this.id(d),\n panes: pane ? [pane.id] : [],\n active: pane?.id ?? null,\n };\n created = group.id;\n this.replace(d, g, {\n kind: 'split',\n id: this.id(d),\n axis,\n ratio: options.ratio ?? 0.5,\n children: options.before ? [group, g] : [g, group],\n });\n });\n return created;\n }\n /** Cancel only an unfilled region; never roll back edits made elsewhere. */\n removeEmptyGroup(groupId: string) {\n const existing = findNode(this.state.root, groupId);\n if (\n existing?.kind !== 'group' ||\n existing.panes.length ||\n !findParent(this.state.root, groupId)\n )\n return;\n this.commit('removeEmptyGroup', (d) => {\n if (d.maximized === groupId) d.maximized = null;\n const parent = findParent(d.root, groupId)!;\n this.replace(d, parent, parent.children[parent.children[0].id === groupId ? 1 : 0]);\n });\n }\n /** Move to a tab group or to a new split at an edge. */\n move(\n paneId: string,\n groupId: string,\n position: 'tab' | 'left' | 'right' | 'top' | 'bottom' = 'tab',\n index?: number,\n options: CommandOptions = {},\n ) {\n this.commit('move', (d) => {\n const target = this.group(d, groupId);\n const source = groups(d.root).find((g) => g.panes.includes(paneId));\n if (!source) problem('Return a popped-out pane before moving it');\n this.permit(d, [paneId, ...target.panes], 'move', options);\n if (position !== 'tab') this.permit(d, target.panes, 'split', options);\n if (source === target && target.panes.length === 1) return;\n this.detach(d, paneId);\n if (position === 'tab') {\n target.panes.splice(\n Math.max(0, Math.min(index ?? target.panes.length, target.panes.length)),\n 0,\n paneId,\n );\n target.active = paneId;\n } else {\n const g: Group = { kind: 'group', id: this.id(d), panes: [paneId], active: paneId };\n const before = position === 'left' || position === 'top';\n this.replace(d, target, {\n kind: 'split',\n id: this.id(d),\n axis: position === 'left' || position === 'right' ? 'horizontal' : 'vertical',\n ratio: 0.5,\n children: before ? [g, target] : [target, g],\n });\n }\n this.tidy(d, source);\n });\n }\n /** Join the sibling region at this split, retaining its content as tabs. */\n join(groupId: string, options: CommandOptions = {}) {\n this.commit('join', (d) => {\n const g = this.group(d, groupId),\n parent = findParent(d.root, groupId);\n if (!parent) return;\n this.permit(d, paneIds(parent), 'join', options);\n g.panes = paneIds(parent);\n g.active ??= g.panes[0] ?? null;\n this.replace(d, parent, g);\n this.tidy(d);\n });\n }\n /** Close all docked tabs and remove their region in one atomic command. */\n closeGroup(groupId: string, options: CommandOptions = {}) {\n this.commit('closeGroup', (d) => {\n const group = this.group(d, groupId);\n this.permit(d, group.panes, 'close', options);\n for (const id of group.panes) delete d.panes[id];\n group.panes = [];\n group.active = null;\n if (d.maximized === groupId) d.maximized = null;\n const parent = findParent(d.root, groupId);\n if (parent)\n this.replace(d, parent, parent.children[parent.children[0].id === groupId ? 1 : 0]);\n });\n }\n /** Join a contiguous row/column range into the receiver, including both endpoints. */\n joinRegions(receiverId: string, otherId: string, options: JoinOptions = {}) {\n this.commit('join', (d) => {\n const receiver = this.group(d, receiverId);\n const range = joinRange(d.root, receiverId, otherId);\n if (!range) problem('Join requires contiguous regions in one row or column');\n const { row, regions, boundaries, start, end, selected } = range;\n const panes = selected.flatMap((g) => g.panes);\n this.permit(d, panes, 'join', options);\n let sizes = range.weights;\n let gaps = boundaries.map(() => 0);\n if (options.extents) {\n const extent = (node: Node): number => {\n const value = options.extents![node.id];\n if (value === undefined || !Number.isFinite(value) || value <= 0)\n problem('Join extents must include a positive finite size for every node in the row');\n return value;\n };\n sizes = regions.map(extent);\n gaps = boundaries.map((split) => {\n const gap = extent(split) - extent(split.children[0]) - extent(split.children[1]);\n if (gap < -0.5) problem('Join extents must describe a non-overlapping row');\n return Math.max(0, gap);\n });\n }\n receiver.panes = panes;\n receiver.active ??= panes[0] ?? null;\n const combined =\n sizes.slice(start, end + 1).reduce((a, b) => a + b, 0) +\n gaps.slice(start, end).reduce((a, b) => a + b, 0);\n const remaining = [...regions.slice(0, start), receiver, ...regions.slice(end + 1)];\n const lengths = [...sizes.slice(0, start), combined, ...sizes.slice(end + 1)];\n const dividers = [...boundaries.slice(0, start), ...boundaries.slice(end)];\n const remainingGaps = [...gaps.slice(0, start), ...gaps.slice(end)];\n // Reuse the surviving boundary IDs and their settings. Removed boundaries alone disappear.\n let replacement = remaining[remaining.length - 1]!;\n let length = lengths[lengths.length - 1]!;\n for (let i = remaining.length - 2; i >= 0; i--) {\n const first = lengths[i]!;\n replacement = {\n ...dividers[i]!,\n ratio: first / (first + length),\n children: [remaining[i]!, replacement],\n };\n length += first + remainingGaps[i]!;\n }\n this.replace(d, row, replacement);\n if (selected.some((g) => g.id === d.maximized)) d.maximized = receiver.id;\n this.tidy(d);\n });\n }\n close(paneId: string, options: CommandOptions = {}) {\n this.commit('close', (d) => {\n this.permit(d, [paneId], 'close', options);\n this.pane(d, paneId);\n let source: Group | undefined;\n if (d.popouts.some((p) => p.paneId === paneId))\n d.popouts = d.popouts.filter((p) => p.paneId !== paneId);\n else source = this.detach(d, paneId);\n delete d.panes[paneId];\n this.tidy(d, source);\n });\n }\n canRestoreClosedTab(): boolean {\n return this.closedTabs.some((entry) => !Object.hasOwn(this.state.panes, entry.pane.id));\n }\n /** Restore the latest closed tab without undoing unrelated layout changes. */\n restoreClosedTab(): void {\n this.alive();\n const entry = [...this.closedTabs]\n .reverse()\n .find((item) => !Object.hasOwn(this.state.panes, item.pane.id));\n if (!entry) return;\n this.commit('restoreClosedTab', (d) => {\n Object.defineProperty(d.panes, entry.pane.id, {\n value: structuredClone(entry.pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n this.dockPane(d, entry.pane.id, entry.groupId, entry.index);\n });\n }\n private dockPane(d: Layout, paneId: string, groupId: string, index: number) {\n const preferred = findNode(d.root, groupId);\n d.maximized = null;\n const candidates = [\n ...(preferred?.kind === 'group' ? [preferred] : []),\n ...groups(d.root).filter(\n (g) => g.id !== groupId && g.panes.every((id) => d.panes[id]!.header !== false),\n ),\n ];\n for (const target of candidates) {\n const previousActive = target.active;\n target.panes.splice(Math.min(index, target.panes.length), 0, paneId);\n target.active = paneId;\n if (!validate(d).length) return;\n target.panes.splice(target.panes.indexOf(paneId), 1);\n target.active = previousActive;\n }\n const g: Group = { kind: 'group', id: this.id(d), panes: [paneId], active: paneId };\n d.root = {\n kind: 'split',\n id: this.id(d),\n axis: 'horizontal',\n ratio: 0.7,\n children: [d.root, g],\n };\n }\n popout(paneId: string, placement?: WindowPlacement, options: CommandOptions = {}) {\n this.commit('popout', (d) => {\n this.permit(d, [paneId], 'popout', options);\n const group = groups(d.root).find((g) => g.panes.includes(paneId));\n if (!group) problem('Pane is not docked');\n const entry = {\n paneId,\n groupId: group.id,\n index: group.panes.indexOf(paneId),\n ...(placement ? { placement } : {}),\n };\n this.detach(d, paneId);\n d.popouts.push(entry);\n this.tidy(d, group, true);\n });\n }\n returnPane(paneId: string) {\n this.commit('return', (d) => {\n const entry = d.popouts.find((p) => p.paneId === paneId);\n if (!entry) return;\n d.popouts = d.popouts.filter((p) => p.paneId !== paneId);\n this.dockPane(d, paneId, entry.groupId, entry.index);\n });\n }\n dispose() {\n this.closedTabs = [];\n this.listeners.clear();\n this.errors.clear();\n this.pending = [];\n this.disposed = true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { joinRange } from './join.js';\nimport { findNode, findParent, groups, paneIds, parseLayout, validate } from './model.js';\nimport { LayoutError } from './types.js';\nimport type {\n AutoCollapse,\n LayoutStoreOptions,\n JoinOptions,\n Axis,\n Capability,\n CapabilityPolicy,\n Change,\n CommandOptions,\n Group,\n Layout,\n Node,\n Pane,\n WindowPlacement,\n} from './types.js';\nconst freeze = <T>(value: T): T => {\n if (value && typeof value === 'object') {\n Object.freeze(value);\n Object.values(value).forEach(freeze);\n }\n return value;\n};\nfunction problem(message: string): never {\n throw new LayoutError([{ path: 'command', message }]);\n}\nexport class LayoutStore {\n private state: Layout;\n private initial: Layout;\n private listeners = new Set<(event: Change) => void>();\n private errors = new Set<(error: unknown) => void>();\n private disposed = false;\n private serial = 0;\n private closedTabs: { pane: Pane; groupId: string; index: number }[] = [];\n private notifying = false;\n private pending: Change[] = [];\n private autoCollapse: AutoCollapse = 'disabled';\n private capabilities: CapabilityPolicy = {};\n constructor(input: unknown, options: LayoutStoreOptions = {}) {\n this.setCapabilities(options.capabilities);\n this.setAutoCollapse(options.autoCollapse ?? 'disabled');\n this.state = freeze(parseLayout(input));\n this.initial = this.export();\n }\n /** Stable immutable snapshot, suitable for useSyncExternalStore. */\n getSnapshot = (): Layout => this.state;\n export(): Layout {\n return structuredClone(this.state);\n }\n subscribe = (listener: (event: Change) => void): (() => void) => {\n this.alive();\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n onError(listener: (error: unknown) => void): () => void {\n this.errors.add(listener);\n return () => {\n this.errors.delete(listener);\n };\n }\n private alive() {\n if (this.disposed) problem('Store has been disposed');\n }\n private report(error: unknown) {\n for (const listener of this.errors) {\n try {\n listener(error);\n } catch {\n /* A reporting callback cannot invalidate a committed layout. */\n }\n }\n }\n private commit(action: string, mutate: (draft: Layout) => void) {\n this.alive();\n let next: Layout;\n try {\n next = this.export();\n mutate(next);\n next = parseLayout(next);\n } catch (error) {\n this.report(error);\n throw error;\n }\n // Update session history only after validation, before notifying subscribers.\n if (action === 'load') this.closedTabs = [];\n if (action === 'close' || action === 'closeGroup') {\n for (const pane of Object.values(this.state.panes)) {\n if (Object.hasOwn(next.panes, pane.id)) continue;\n const group = groups(this.state.root).find((g) => g.panes.includes(pane.id));\n const detached = this.state.popouts.find((p) => p.paneId === pane.id);\n this.closedTabs.push({\n pane: structuredClone(pane),\n groupId: group?.id ?? detached!.groupId,\n index: group ? group.panes.indexOf(pane.id) : detached!.index,\n });\n }\n this.closedTabs = this.closedTabs.slice(-50);\n }\n if (action === 'restoreClosedTab') {\n this.closedTabs = this.closedTabs.filter(\n (entry) => !Object.hasOwn(next.panes, entry.pane.id),\n );\n }\n this.state = freeze(next);\n this.pending.push({ action, layout: this.state });\n if (this.notifying) return;\n this.notifying = true;\n try {\n while (this.pending.length) {\n const event = this.pending.shift()!;\n for (const listener of [...this.listeners]) {\n if (!this.listeners.has(listener)) continue;\n try {\n listener(event);\n } catch (error) {\n this.report(error);\n }\n }\n }\n } finally {\n this.notifying = false;\n }\n }\n\n private group(draft: Layout, id: string): Group {\n const n = findNode(draft.root, id);\n if (n?.kind !== 'group') problem('Group not found: ' + id);\n return n;\n }\n private pane(draft: Layout, id: string): Pane {\n if (!Object.hasOwn(draft.panes, id)) problem('Pane not found: ' + id);\n return draft.panes[id]!;\n }\n private permit(draft: Layout, ids: string[], cap: Capability, options: CommandOptions) {\n for (const id of ids)\n if (options.source === 'user' && !this.canPane(draft, id, cap))\n problem(`${cap} is disabled for ${id}`);\n }\n private id(draft: Layout): string {\n let id: string;\n do {\n id = `layout-${++this.serial}`;\n } while (findNode(draft.root, id));\n return id;\n }\n private replace(draft: Layout, old: Node, next: Node) {\n const parent = findParent(draft.root, old.id);\n if (parent) parent.children[parent.children[0].id === old.id ? 0 : 1] = next;\n else draft.root = next;\n }\n private detach(draft: Layout, id: string): Group {\n const g = groups(draft.root).find((n) => n.panes.includes(id));\n if (!g) problem('Pane is not docked: ' + id);\n const at = g.panes.indexOf(id);\n g.panes.splice(at, 1);\n if (g.active === id) g.active = g.panes[Math.min(at, g.panes.length - 1)] ?? null;\n return g;\n }\n getAutoCollapse(): AutoCollapse {\n return this.autoCollapse;\n }\n setAutoCollapse(mode: AutoCollapse): void {\n this.alive();\n if (!['enabled', 'protected', 'disabled'].includes(mode)) problem('Invalid autoCollapse mode');\n this.autoCollapse = mode;\n }\n private tidy(draft: Layout, source?: Group, popout = false) {\n if (\n source &&\n !source.panes.length &&\n this.autoCollapse !== 'disabled' &&\n (!popout || this.autoCollapse === 'enabled')\n ) {\n const parent = findParent(draft.root, source.id);\n if (parent)\n this.replace(draft, parent, parent.children[parent.children[0].id === source.id ? 1 : 0]);\n }\n if (draft.maximized && !findNode(draft.root, draft.maximized)) draft.maximized = null;\n }\n /** Replace session policy; layout export/load never serializes or resets it. */\n setCapabilities(policy: CapabilityPolicy = {}): void {\n this.alive();\n const flags = (value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n problem('Invalid capabilities');\n for (const [key, flag] of Object.entries(value!))\n if (\n ![\n 'resize',\n 'move',\n 'reorder',\n 'addTab',\n 'maximize',\n 'split',\n 'join',\n 'close',\n 'popout',\n ].includes(key) ||\n typeof flag !== 'boolean'\n )\n problem('Invalid capability: ' + key);\n };\n if (!policy || typeof policy !== 'object' || Array.isArray(policy))\n problem('Invalid capability policy');\n for (const [key, value] of Object.entries(policy)) {\n if (value === undefined) continue;\n if (key === 'defaults') flags(value);\n else if (key === 'groups' || key === 'panes') {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n problem('Invalid capability overrides');\n Object.values(value).forEach(flags);\n } else problem('Unknown capability scope: ' + key);\n }\n this.capabilities = structuredClone(policy);\n }\n private canPane(layout: Layout, paneId: string, capability: Capability): boolean {\n const pane = layout.panes[paneId];\n if (!pane) return false;\n const groupId =\n groups(layout.root).find((g) => g.panes.includes(paneId))?.id ??\n layout.popouts.find((p) => p.paneId === paneId)?.groupId;\n return (\n this.capabilities.panes?.[paneId]?.[capability] ??\n pane.capabilities?.[capability] ??\n (groupId ? this.capabilities.groups?.[groupId]?.[capability] : undefined) ??\n this.capabilities.defaults?.[capability] ??\n (capability === 'addTab' || capability === 'reorder'\n ? this.canPane(layout, paneId, 'move')\n : true)\n );\n }\n can(paneId: string, capability: Capability): boolean {\n return this.canPane(this.state, paneId, capability);\n }\n private canNodeIn(layout: Layout, node: Node, capability: Capability): boolean {\n if (node.kind === 'split')\n return node.children.every((child) => this.canNodeIn(layout, child, capability));\n return node.panes.length\n ? node.panes.every((id) => this.canPane(layout, id, capability))\n : (this.capabilities.groups?.[node.id]?.[capability] ??\n this.capabilities.defaults?.[capability] ??\n (capability === 'addTab' || capability === 'reorder'\n ? this.canNodeIn(layout, node, 'move')\n : true));\n }\n /** Test every affected tab, including policy on empty regions. */\n canNode(nodeId: string, capability: Capability): boolean {\n const node = findNode(this.state.root, nodeId);\n return !!node && this.canNodeIn(this.state, node, capability);\n }\n private permitNode(layout: Layout, node: Node, capability: Capability, options: CommandOptions) {\n if (options.source === 'user' && !this.canNodeIn(layout, node, capability))\n problem(`${capability} is disabled for ${node.id}`);\n }\n load(input: unknown) {\n this.commit('load', (draft) => {\n const next = parseLayout(input);\n for (const key of Object.keys(draft)) Reflect.deleteProperty(draft, key);\n Object.assign(draft, next);\n });\n }\n reset() {\n this.load(this.initial);\n }\n setTabDisplay(groupId: string, display: Group['tabDisplay']) {\n this.commit('setTabDisplay', (draft) => {\n const group = findNode(draft.root, groupId);\n if (!group || group.kind !== 'group') problem('Expected a group id');\n if (display === undefined) delete group.tabDisplay;\n else group.tabDisplay = display;\n });\n }\n setTabPlacement(groupId: string, placement: Group['tabPlacement']) {\n this.commit('setTabPlacement', (draft) => {\n const group = findNode(draft.root, groupId);\n if (!group || group.kind !== 'group') problem('Expected a group id');\n if (placement === undefined) delete group.tabPlacement;\n else group.tabPlacement = placement;\n });\n }\n activate(groupId: string, paneId: string) {\n this.commit('activate', (d) => {\n const g = this.group(d, groupId);\n if (!g.panes.includes(paneId)) problem('Tab does not belong to group');\n g.active = paneId;\n });\n }\n resize(splitId: string, ratio: number, options: CommandOptions = {}) {\n this.commit('resize', (d) => {\n const n = findNode(d.root, splitId);\n if (n?.kind !== 'split') problem('Split not found');\n this.permitNode(d, n, 'resize', options);\n n.ratio = ratio;\n });\n }\n /** Atomically update coupled split ratios without intermediate layouts. */\n resizeMany(ratios: Record<string, number>, options: CommandOptions = {}) {\n this.commit('resize', (d) => {\n for (const [id, ratio] of Object.entries(ratios)) {\n const node = findNode(d.root, id);\n if (node?.kind !== 'split') problem('Split not found');\n this.permitNode(d, node, 'resize', options);\n node.ratio = ratio;\n }\n });\n }\n maximize(groupId: string | null, options: CommandOptions = {}) {\n this.commit('maximize', (d) => {\n if (groupId) this.permitNode(d, this.group(d, groupId), 'maximize', options);\n d.maximized = groupId;\n });\n }\n add(pane: Pane, groupId: string, options: CommandOptions = {}) {\n this.commit('add', (d) => {\n const g = this.group(d, groupId);\n this.permitNode(d, g, 'addTab', options);\n if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');\n Object.defineProperty(d.panes, pane.id, {\n value: structuredClone(pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n g.panes.push(pane.id);\n g.active = pane.id;\n });\n }\n updatePane(pane: Pane) {\n this.commit('updatePane', (d) => {\n this.pane(d, pane.id);\n d.panes[pane.id] = structuredClone(pane);\n });\n }\n split(\n groupId: string,\n axis: Axis,\n pane: Pane | null,\n options: CommandOptions & { before?: boolean; ratio?: number } = {},\n ) {\n let created = '';\n this.commit('split', (d) => {\n const g = this.group(d, groupId);\n this.permitNode(d, g, 'split', options);\n if (pane) {\n if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');\n Object.defineProperty(d.panes, pane.id, {\n value: structuredClone(pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n const group: Group = {\n kind: 'group',\n id: this.id(d),\n panes: pane ? [pane.id] : [],\n active: pane?.id ?? null,\n };\n created = group.id;\n this.replace(d, g, {\n kind: 'split',\n id: this.id(d),\n axis,\n ratio: options.ratio ?? 0.5,\n children: options.before ? [group, g] : [g, group],\n });\n });\n return created;\n }\n /** Cancel only an unfilled region; never roll back edits made elsewhere. */\n removeEmptyGroup(groupId: string, options: CommandOptions = {}) {\n const existing = findNode(this.state.root, groupId);\n if (\n existing?.kind !== 'group' ||\n existing.panes.length ||\n !findParent(this.state.root, groupId)\n )\n return;\n this.commit('removeEmptyGroup', (d) => {\n this.permitNode(d, this.group(d, groupId), 'close', options);\n if (d.maximized === groupId) d.maximized = null;\n const parent = findParent(d.root, groupId)!;\n this.replace(d, parent, parent.children[parent.children[0].id === groupId ? 1 : 0]);\n });\n }\n /** Move to a tab group or to a new split at an edge. */\n move(\n paneId: string,\n groupId: string,\n position: 'tab' | 'left' | 'right' | 'top' | 'bottom' = 'tab',\n index?: number,\n options: CommandOptions = {},\n ) {\n this.commit('move', (d) => {\n const target = this.group(d, groupId);\n const source = groups(d.root).find((g) => g.panes.includes(paneId));\n if (!source) problem('Return a popped-out pane before moving it');\n const capability = source === target && position === 'tab' ? 'reorder' : 'move';\n this.permit(d, [paneId], capability, options);\n this.permitNode(d, target, capability, options);\n if (position !== 'tab') this.permitNode(d, target, 'split', options);\n if (source === target && target.panes.length === 1) return;\n this.detach(d, paneId);\n if (position === 'tab') {\n target.panes.splice(\n Math.max(0, Math.min(index ?? target.panes.length, target.panes.length)),\n 0,\n paneId,\n );\n target.active = paneId;\n } else {\n const g: Group = { kind: 'group', id: this.id(d), panes: [paneId], active: paneId };\n const before = position === 'left' || position === 'top';\n this.replace(d, target, {\n kind: 'split',\n id: this.id(d),\n axis: position === 'left' || position === 'right' ? 'horizontal' : 'vertical',\n ratio: 0.5,\n children: before ? [g, target] : [target, g],\n });\n }\n this.tidy(d, source);\n });\n }\n /** Join the sibling region at this split, retaining its content as tabs. */\n join(groupId: string, options: CommandOptions = {}) {\n this.commit('join', (d) => {\n const g = this.group(d, groupId),\n parent = findParent(d.root, groupId);\n if (!parent) return;\n this.permitNode(d, parent, 'join', options);\n g.panes = paneIds(parent);\n g.active ??= g.panes[0] ?? null;\n this.replace(d, parent, g);\n this.tidy(d);\n });\n }\n /** Close all docked tabs and remove their region in one atomic command. */\n closeGroup(groupId: string, options: CommandOptions = {}) {\n this.commit('closeGroup', (d) => {\n const group = this.group(d, groupId);\n this.permitNode(d, group, 'close', options);\n for (const id of group.panes) delete d.panes[id];\n group.panes = [];\n group.active = null;\n if (d.maximized === groupId) d.maximized = null;\n const parent = findParent(d.root, groupId);\n if (parent)\n this.replace(d, parent, parent.children[parent.children[0].id === groupId ? 1 : 0]);\n });\n }\n /** Join a contiguous row/column range into the receiver, including both endpoints. */\n joinRegions(receiverId: string, otherId: string, options: JoinOptions = {}) {\n this.commit('join', (d) => {\n const receiver = this.group(d, receiverId);\n const range = joinRange(d.root, receiverId, otherId);\n if (!range) problem('Join requires contiguous regions in one row or column');\n const { row, regions, boundaries, start, end, selected } = range;\n const panes = selected.flatMap((g) => g.panes);\n selected.forEach((group) => this.permitNode(d, group, 'join', options));\n let sizes = range.weights;\n let gaps = boundaries.map(() => 0);\n if (options.extents) {\n const extent = (node: Node): number => {\n const value = options.extents![node.id];\n if (value === undefined || !Number.isFinite(value) || value <= 0)\n problem('Join extents must include a positive finite size for every node in the row');\n return value;\n };\n sizes = regions.map(extent);\n gaps = boundaries.map((split) => {\n const gap = extent(split) - extent(split.children[0]) - extent(split.children[1]);\n if (gap < -0.5) problem('Join extents must describe a non-overlapping row');\n return Math.max(0, gap);\n });\n }\n receiver.panes = panes;\n receiver.active ??= panes[0] ?? null;\n const combined =\n sizes.slice(start, end + 1).reduce((a, b) => a + b, 0) +\n gaps.slice(start, end).reduce((a, b) => a + b, 0);\n const remaining = [...regions.slice(0, start), receiver, ...regions.slice(end + 1)];\n const lengths = [...sizes.slice(0, start), combined, ...sizes.slice(end + 1)];\n const dividers = [...boundaries.slice(0, start), ...boundaries.slice(end)];\n const remainingGaps = [...gaps.slice(0, start), ...gaps.slice(end)];\n // Reuse the surviving boundary IDs and their settings. Removed boundaries alone disappear.\n let replacement = remaining[remaining.length - 1]!;\n let length = lengths[lengths.length - 1]!;\n for (let i = remaining.length - 2; i >= 0; i--) {\n const first = lengths[i]!;\n replacement = {\n ...dividers[i]!,\n ratio: first / (first + length),\n children: [remaining[i]!, replacement],\n };\n length += first + remainingGaps[i]!;\n }\n this.replace(d, row, replacement);\n if (selected.some((g) => g.id === d.maximized)) d.maximized = receiver.id;\n this.tidy(d);\n });\n }\n close(paneId: string, options: CommandOptions = {}) {\n this.commit('close', (d) => {\n this.permit(d, [paneId], 'close', options);\n this.pane(d, paneId);\n let source: Group | undefined;\n if (d.popouts.some((p) => p.paneId === paneId))\n d.popouts = d.popouts.filter((p) => p.paneId !== paneId);\n else source = this.detach(d, paneId);\n delete d.panes[paneId];\n this.tidy(d, source);\n });\n }\n canRestoreClosedTab(): boolean {\n return this.closedTabs.some((entry) => !Object.hasOwn(this.state.panes, entry.pane.id));\n }\n /** Restore the latest closed tab without undoing unrelated layout changes. */\n restoreClosedTab(): void {\n this.alive();\n const entry = [...this.closedTabs]\n .reverse()\n .find((item) => !Object.hasOwn(this.state.panes, item.pane.id));\n if (!entry) return;\n this.commit('restoreClosedTab', (d) => {\n Object.defineProperty(d.panes, entry.pane.id, {\n value: structuredClone(entry.pane),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n this.dockPane(d, entry.pane.id, entry.groupId, entry.index);\n });\n }\n private dockPane(d: Layout, paneId: string, groupId: string, index: number) {\n const preferred = findNode(d.root, groupId);\n d.maximized = null;\n const candidates = [\n ...(preferred?.kind === 'group' ? [preferred] : []),\n ...groups(d.root).filter(\n (g) => g.id !== groupId && g.panes.every((id) => d.panes[id]!.header !== false),\n ),\n ];\n for (const target of candidates) {\n const previousActive = target.active;\n target.panes.splice(Math.min(index, target.panes.length), 0, paneId);\n target.active = paneId;\n if (!validate(d).length) return;\n target.panes.splice(target.panes.indexOf(paneId), 1);\n target.active = previousActive;\n }\n const g: Group = { kind: 'group', id: this.id(d), panes: [paneId], active: paneId };\n d.root = {\n kind: 'split',\n id: this.id(d),\n axis: 'horizontal',\n ratio: 0.7,\n children: [d.root, g],\n };\n }\n popout(paneId: string, placement?: WindowPlacement, options: CommandOptions = {}) {\n this.commit('popout', (d) => {\n this.permit(d, [paneId], 'popout', options);\n const group = groups(d.root).find((g) => g.panes.includes(paneId));\n if (!group) problem('Pane is not docked');\n const entry = {\n paneId,\n groupId: group.id,\n index: group.panes.indexOf(paneId),\n ...(placement ? { placement } : {}),\n };\n this.detach(d, paneId);\n d.popouts.push(entry);\n this.tidy(d, group, true);\n });\n }\n returnPane(paneId: string) {\n this.commit('return', (d) => {\n const entry = d.popouts.find((p) => p.paneId === paneId);\n if (!entry) return;\n d.popouts = d.popouts.filter((p) => p.paneId !== paneId);\n this.dockPane(d, paneId, entry.groupId, entry.index);\n });\n }\n dispose() {\n this.closedTabs = [];\n this.listeners.clear();\n this.errors.clear();\n this.pending = [];\n this.disposed = true;\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { AutoCollapse, LayoutStoreOptions, Json, Capability, Axis, Pane, Group, Split, Node, WindowPlacement, Popout, Layout, Issue, CommandOptions, Change, Bounds, JoinOptions, } from './types.js';
|
|
1
|
+
export type { AutoCollapse, LayoutStoreOptions, Json, Capability, CapabilityPolicy, Axis, Pane, Group, Split, Node, WindowPlacement, Popout, Layout, Issue, CommandOptions, Change, Bounds, JoinOptions, } from './types.js';
|
|
2
2
|
export { LayoutError } from './types.js';
|
|
3
3
|
export { LayoutStore } from './controller.js';
|
|
4
4
|
export { createLayout, validate, parseLayout, findNode, findParent, groups, paneIds, DIVIDER, bounds, allocate, } from './model.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,eAAe,EACf,MAAM,EACN,MAAM,EACN,KAAK,EACL,cAAc,EACd,MAAM,EACN,MAAM,EACN,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,IAAI,EACJ,UAAU,EACV,gBAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,eAAe,EACf,MAAM,EACN,MAAM,EACN,KAAK,EACL,cAAc,EACd,MAAM,EACN,MAAM,EACN,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,UAAU,EACV,MAAM,EACN,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC","sourcesContent":["export type {\n AutoCollapse,\n LayoutStoreOptions,\n Json,\n Capability,\n CapabilityPolicy,\n Axis,\n Pane,\n Group,\n Split,\n Node,\n WindowPlacement,\n Popout,\n Layout,\n Issue,\n CommandOptions,\n Change,\n Bounds,\n JoinOptions,\n} from './types.js';\nexport { LayoutError } from './types.js';\nexport { LayoutStore } from './controller.js';\nexport {\n createLayout,\n validate,\n parseLayout,\n findNode,\n findParent,\n groups,\n paneIds,\n DIVIDER,\n bounds,\n allocate,\n} from './model.js';\nexport { joinRange } from './join.js';\n"]}
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAQ,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAoBjF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAQ,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAoBjF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,CAkKhD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIlD;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAMjE;AACD,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,YAAY,EAAE,KAAK,GAAG,SAAS,CAKzF;AACD,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,EAAE,CAE1C;AACD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAE5C;AASD,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,iGAAiG;AACjG,wBAAgB,MAAM,CACpB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAC3D,MAAM,CA0BR;AACD,+FAA+F;AAC/F,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,SAAU,GACZ,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlB;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CASpF"}
|
package/dist/model.js
CHANGED
|
@@ -52,7 +52,17 @@ export function validate(input) {
|
|
|
52
52
|
fail(`panes.${id}.capabilities`, 'Expected object');
|
|
53
53
|
else
|
|
54
54
|
for (const [key, value] of Object.entries(pane.capabilities))
|
|
55
|
-
if (![
|
|
55
|
+
if (![
|
|
56
|
+
'resize',
|
|
57
|
+
'move',
|
|
58
|
+
'reorder',
|
|
59
|
+
'addTab',
|
|
60
|
+
'maximize',
|
|
61
|
+
'split',
|
|
62
|
+
'join',
|
|
63
|
+
'close',
|
|
64
|
+
'popout',
|
|
65
|
+
].includes(key) ||
|
|
56
66
|
typeof value !== 'boolean')
|
|
57
67
|
fail(`panes.${id}.capabilities.${key}`, 'Unknown capability or non-boolean flag');
|
|
58
68
|
}
|
package/dist/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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","sourcesContent":["import { LayoutError } from './types.js';\nimport type { Bounds, Group, Issue, Json, Layout, Node, Pane } from './types.js';\nconst record = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nfunction isJson(v: unknown, seen = new Set<unknown>(), depth = 0): v is Json {\n if (depth > 256) return false;\n if (v === null || typeof v === 'string' || typeof v === 'boolean') return true;\n if (typeof v === 'number') return Number.isFinite(v);\n if (typeof v !== 'object' || seen.has(v)) return false;\n if (\n !Array.isArray(v) &&\n Object.getPrototypeOf(v) !== Object.prototype &&\n Object.getPrototypeOf(v) !== null\n )\n return false;\n seen.add(v);\n const result = Object.values(v).every((x) => isJson(x, seen, depth + 1));\n seen.delete(v);\n return result;\n}\nexport function validate(input: unknown): Issue[] {\n const errors: Issue[] = [];\n const fail = (path: string, message: string) => {\n errors.push({ path, message });\n };\n if (!record(input) || !isJson(input))\n return [{ path: '$', message: 'Expected a finite, acyclic JSON object' }];\n if (input.version !== 1) fail('version', 'Expected version 1');\n if (!record(input.panes))\n return [...errors, { path: 'panes', message: 'Expected pane dictionary' }];\n const panes = input.panes;\n for (const [id, pane] of Object.entries(panes)) {\n if (\n !record(pane) ||\n pane.id !== id ||\n !id ||\n typeof pane.type !== 'string' ||\n !pane.type ||\n typeof pane.title !== 'string'\n ) {\n fail(`panes.${id}`, 'Expected matching id, type, and title');\n continue;\n }\n if (pane.confirmClose !== undefined && typeof pane.confirmClose !== 'boolean')\n fail(`panes.${id}.confirmClose`, 'Expected boolean');\n if (pane.icon !== undefined && typeof pane.icon !== 'string')\n fail(`panes.${id}.icon`, 'Expected string');\n if (pane.header !== undefined && typeof pane.header !== 'boolean')\n fail(`panes.${id}.header`, 'Expected boolean');\n if (pane.capabilities !== undefined) {\n if (!record(pane.capabilities)) fail(`panes.${id}.capabilities`, 'Expected object');\n else\n for (const [key, value] of Object.entries(pane.capabilities))\n if (\n !['resize', 'move', 'split', 'join', 'close', 'popout'].includes(key) ||\n typeof value !== 'boolean'\n )\n fail(`panes.${id}.capabilities.${key}`, 'Unknown capability or non-boolean flag');\n }\n if (pane.size !== undefined) {\n if (!record(pane.size)) fail(`panes.${id}.size`, 'Expected object');\n else {\n for (const [key, value] of Object.entries(pane.size))\n if (\n !['minWidth', 'maxWidth', 'minHeight', 'maxHeight'].includes(key) ||\n !finite(value) ||\n value < 0\n )\n fail(`panes.${id}.size.${key}`, 'Expected nonnegative finite size');\n for (const axis of ['Width', 'Height'])\n if (\n finite(pane.size['min' + axis]) &&\n finite(pane.size['max' + axis]) &&\n Number(pane.size['min' + axis]) > Number(pane.size['max' + axis])\n )\n fail(`panes.${id}.size`, 'Minimum exceeds maximum');\n }\n }\n }\n const ids = new Set<string>();\n const assigned = new Set<string>();\n const groups = new Set<string>();\n const use = (id: unknown, path: string) => {\n if (typeof id !== 'string' || !Object.hasOwn(panes, id)) fail(path, 'Unknown pane');\n else if (assigned.has(id)) fail(path, 'Pane is placed more than once');\n else assigned.add(id);\n };\n function walk(node: unknown, path: string, depth: number) {\n if (depth > 64) {\n fail(path, 'Maximum split depth is 64');\n return;\n }\n if (!record(node) || typeof node.id !== 'string' || !node.id) {\n fail(path, 'Expected node with id');\n return;\n }\n if (ids.has(node.id)) fail(path, 'Duplicate node id');\n ids.add(node.id);\n if (node.kind === 'group') {\n groups.add(node.id);\n if (\n node.tabDisplay !== undefined &&\n node.tabDisplay !== 'automatic' &&\n node.tabDisplay !== 'compact'\n )\n fail(path + '.tabDisplay', 'Expected automatic or compact');\n if (\n node.tabPlacement !== undefined &&\n node.tabPlacement !== 'top' &&\n node.tabPlacement !== 'left'\n )\n fail(path + '.tabPlacement', 'Expected top or left');\n if (!Array.isArray(node.panes)) {\n fail(path, 'Expected pane array');\n return;\n }\n node.panes.forEach((p, i) => use(p, `${path}.panes[${i}]`));\n if (node.panes.length ? !node.panes.includes(node.active) : node.active !== null)\n fail(path + '.active', 'Active tab must belong to group (or be null for empty group)');\n } else if (node.kind === 'split') {\n if (node.gap !== undefined && (!finite(node.gap) || node.gap < 0))\n fail(path + '.gap', 'Expected nonnegative divider space');\n if (!['horizontal', 'vertical'].includes(String(node.axis)))\n fail(path + '.axis', 'Expected horizontal or vertical');\n if (!finite(node.ratio) || node.ratio <= 0 || node.ratio >= 1)\n fail(path + '.ratio', 'Expected ratio between 0 and 1');\n if (!Array.isArray(node.children) || node.children.length !== 2)\n fail(path + '.children', 'Expected two children');\n else node.children.forEach((n, i) => walk(n, `${path}.children[${i}]`, depth + 1));\n } else fail(path + '.kind', 'Expected group or split');\n }\n walk(input.root, 'root', 0);\n if (!Array.isArray(input.popouts)) fail('popouts', 'Expected array');\n else\n input.popouts.forEach((p, i) => {\n const path = `popouts[${i}]`;\n if (!record(p)) {\n fail(path, 'Expected popout object');\n return;\n }\n use(p.paneId, path + '.paneId');\n if (typeof p.groupId !== 'string' || !Number.isInteger(p.index) || Number(p.index) < 0)\n fail(path, 'Expected return group id and nonnegative index');\n if (p.placement !== undefined) {\n if (!record(p.placement)) fail(path + '.placement', 'Expected placement object');\n else\n for (const [key, value] of Object.entries(p.placement))\n if (\n !['width', 'height', 'left', 'top'].includes(key) ||\n !finite(value) ||\n (['width', 'height'].includes(key) && value <= 0)\n )\n fail(path + '.placement.' + key, 'Invalid window placement');\n }\n });\n for (const id of Object.keys(panes))\n if (!assigned.has(id)) fail(`panes.${id}`, 'Pane has no placement');\n if (\n input.maximized !== null &&\n (typeof input.maximized !== 'string' || !groups.has(input.maximized))\n )\n fail('maximized', 'Expected a group id or null');\n if (!errors.length) {\n const check = (n: Node) => {\n const b = bounds(n, input as unknown as Layout);\n if (b.minWidth > b.maxWidth || b.minHeight > b.maxHeight)\n fail(n.id, 'Pane constraints cannot coexist in this region');\n if (n.kind === 'split') n.children.forEach(check);\n };\n check(input.root as unknown as Node);\n }\n return errors;\n}\nexport function parseLayout(input: unknown): Layout {\n const issues = validate(input);\n if (issues.length) throw new LayoutError(issues);\n return structuredClone(input) as Layout;\n}\nexport function findNode(root: Node, id: string): Node | undefined {\n return root.id === id\n ? root\n : root.kind === 'split'\n ? (findNode(root.children[0], id) ?? findNode(root.children[1], id))\n : undefined;\n}\nexport function findParent(root: Node, id: string): import('./types.js').Split | undefined {\n if (root.kind === 'group') return undefined;\n return root.children.some((n) => n.id === id)\n ? root\n : (findParent(root.children[0], id) ?? findParent(root.children[1], id));\n}\nexport function groups(root: Node): Group[] {\n return root.kind === 'group' ? [root] : root.children.flatMap(groups);\n}\nexport function paneIds(root: Node): string[] {\n return groups(root).flatMap((g) => g.panes);\n}\nfunction paneBounds(p: Pane): Bounds {\n return {\n minWidth: p.size?.minWidth ?? 0,\n maxWidth: p.size?.maxWidth ?? Infinity,\n minHeight: p.size?.minHeight ?? 0,\n maxHeight: p.size?.maxHeight ?? Infinity,\n };\n}\nexport const DIVIDER = 4;\n/** Aggregate model constraints, optionally resolving each group's bounds for a host renderer. */\nexport function bounds(\n node: Node,\n layout: Layout,\n resolveGroup?: (group: Group, constraints: Bounds) => Bounds,\n): Bounds {\n if (node.kind === 'group') {\n const values = node.panes.map((id) => paneBounds(layout.panes[id]!));\n const constraints = {\n minWidth: Math.max(0, ...values.map((b) => b.minWidth)),\n maxWidth: Math.min(Infinity, ...values.map((b) => b.maxWidth)),\n minHeight: Math.max(0, ...values.map((b) => b.minHeight)),\n maxHeight: Math.min(Infinity, ...values.map((b) => b.maxHeight)),\n };\n return resolveGroup ? resolveGroup(node, constraints) : constraints;\n }\n const a = bounds(node.children[0], layout, resolveGroup),\n b = bounds(node.children[1], layout, resolveGroup);\n return node.axis === 'horizontal'\n ? {\n minWidth: a.minWidth + b.minWidth + (node.gap ?? DIVIDER),\n maxWidth: a.maxWidth + b.maxWidth + (node.gap ?? DIVIDER),\n minHeight: Math.max(a.minHeight, b.minHeight),\n maxHeight: Math.max(a.maxHeight, b.maxHeight),\n }\n : {\n minHeight: a.minHeight + b.minHeight + (node.gap ?? DIVIDER),\n maxHeight: a.maxHeight + b.maxHeight + (node.gap ?? DIVIDER),\n minWidth: Math.max(a.minWidth, b.minWidth),\n maxWidth: Math.max(a.maxWidth, b.maxWidth),\n };\n}\n/** Returns content extents; overflow retains minimums, surplus beyond maximums stays empty. */\nexport function allocate(\n total: number,\n ratio: number,\n minA: number,\n maxA: number,\n minB: number,\n maxB: number,\n gap = DIVIDER,\n): [number, number] {\n const available = Math.max(total - gap, minA + minB);\n const used = Math.min(available, maxA + maxB);\n const low = Math.max(minA, used - maxB),\n high = Math.min(maxA, used - minB);\n const a = Math.max(low, Math.min(high, used * ratio));\n return [a, used - a];\n}\n\n/** Create independent, validated JSON for an empty or single-pane workspace. */\nexport function createLayout(options: { pane?: Pane; groupId?: string } = {}): Layout {\n const { pane, groupId = 'main' } = options;\n return parseLayout({\n version: 1,\n root: { kind: 'group', id: groupId, panes: pane ? [pane.id] : [], active: pane?.id ?? null },\n panes: pane ? { [pane.id]: pane } : {},\n popouts: [],\n maximized: null,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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","sourcesContent":["import { LayoutError } from './types.js';\nimport type { Bounds, Group, Issue, Json, Layout, Node, Pane } from './types.js';\nconst record = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nfunction isJson(v: unknown, seen = new Set<unknown>(), depth = 0): v is Json {\n if (depth > 256) return false;\n if (v === null || typeof v === 'string' || typeof v === 'boolean') return true;\n if (typeof v === 'number') return Number.isFinite(v);\n if (typeof v !== 'object' || seen.has(v)) return false;\n if (\n !Array.isArray(v) &&\n Object.getPrototypeOf(v) !== Object.prototype &&\n Object.getPrototypeOf(v) !== null\n )\n return false;\n seen.add(v);\n const result = Object.values(v).every((x) => isJson(x, seen, depth + 1));\n seen.delete(v);\n return result;\n}\nexport function validate(input: unknown): Issue[] {\n const errors: Issue[] = [];\n const fail = (path: string, message: string) => {\n errors.push({ path, message });\n };\n if (!record(input) || !isJson(input))\n return [{ path: '$', message: 'Expected a finite, acyclic JSON object' }];\n if (input.version !== 1) fail('version', 'Expected version 1');\n if (!record(input.panes))\n return [...errors, { path: 'panes', message: 'Expected pane dictionary' }];\n const panes = input.panes;\n for (const [id, pane] of Object.entries(panes)) {\n if (\n !record(pane) ||\n pane.id !== id ||\n !id ||\n typeof pane.type !== 'string' ||\n !pane.type ||\n typeof pane.title !== 'string'\n ) {\n fail(`panes.${id}`, 'Expected matching id, type, and title');\n continue;\n }\n if (pane.confirmClose !== undefined && typeof pane.confirmClose !== 'boolean')\n fail(`panes.${id}.confirmClose`, 'Expected boolean');\n if (pane.icon !== undefined && typeof pane.icon !== 'string')\n fail(`panes.${id}.icon`, 'Expected string');\n if (pane.header !== undefined && typeof pane.header !== 'boolean')\n fail(`panes.${id}.header`, 'Expected boolean');\n if (pane.capabilities !== undefined) {\n if (!record(pane.capabilities)) fail(`panes.${id}.capabilities`, 'Expected object');\n else\n for (const [key, value] of Object.entries(pane.capabilities))\n if (\n ![\n 'resize',\n 'move',\n 'reorder',\n 'addTab',\n 'maximize',\n 'split',\n 'join',\n 'close',\n 'popout',\n ].includes(key) ||\n typeof value !== 'boolean'\n )\n fail(`panes.${id}.capabilities.${key}`, 'Unknown capability or non-boolean flag');\n }\n if (pane.size !== undefined) {\n if (!record(pane.size)) fail(`panes.${id}.size`, 'Expected object');\n else {\n for (const [key, value] of Object.entries(pane.size))\n if (\n !['minWidth', 'maxWidth', 'minHeight', 'maxHeight'].includes(key) ||\n !finite(value) ||\n value < 0\n )\n fail(`panes.${id}.size.${key}`, 'Expected nonnegative finite size');\n for (const axis of ['Width', 'Height'])\n if (\n finite(pane.size['min' + axis]) &&\n finite(pane.size['max' + axis]) &&\n Number(pane.size['min' + axis]) > Number(pane.size['max' + axis])\n )\n fail(`panes.${id}.size`, 'Minimum exceeds maximum');\n }\n }\n }\n const ids = new Set<string>();\n const assigned = new Set<string>();\n const groups = new Set<string>();\n const use = (id: unknown, path: string) => {\n if (typeof id !== 'string' || !Object.hasOwn(panes, id)) fail(path, 'Unknown pane');\n else if (assigned.has(id)) fail(path, 'Pane is placed more than once');\n else assigned.add(id);\n };\n function walk(node: unknown, path: string, depth: number) {\n if (depth > 64) {\n fail(path, 'Maximum split depth is 64');\n return;\n }\n if (!record(node) || typeof node.id !== 'string' || !node.id) {\n fail(path, 'Expected node with id');\n return;\n }\n if (ids.has(node.id)) fail(path, 'Duplicate node id');\n ids.add(node.id);\n if (node.kind === 'group') {\n groups.add(node.id);\n if (\n node.tabDisplay !== undefined &&\n node.tabDisplay !== 'automatic' &&\n node.tabDisplay !== 'compact'\n )\n fail(path + '.tabDisplay', 'Expected automatic or compact');\n if (\n node.tabPlacement !== undefined &&\n node.tabPlacement !== 'top' &&\n node.tabPlacement !== 'left'\n )\n fail(path + '.tabPlacement', 'Expected top or left');\n if (!Array.isArray(node.panes)) {\n fail(path, 'Expected pane array');\n return;\n }\n node.panes.forEach((p, i) => use(p, `${path}.panes[${i}]`));\n if (node.panes.length ? !node.panes.includes(node.active) : node.active !== null)\n fail(path + '.active', 'Active tab must belong to group (or be null for empty group)');\n } else if (node.kind === 'split') {\n if (node.gap !== undefined && (!finite(node.gap) || node.gap < 0))\n fail(path + '.gap', 'Expected nonnegative divider space');\n if (!['horizontal', 'vertical'].includes(String(node.axis)))\n fail(path + '.axis', 'Expected horizontal or vertical');\n if (!finite(node.ratio) || node.ratio <= 0 || node.ratio >= 1)\n fail(path + '.ratio', 'Expected ratio between 0 and 1');\n if (!Array.isArray(node.children) || node.children.length !== 2)\n fail(path + '.children', 'Expected two children');\n else node.children.forEach((n, i) => walk(n, `${path}.children[${i}]`, depth + 1));\n } else fail(path + '.kind', 'Expected group or split');\n }\n walk(input.root, 'root', 0);\n if (!Array.isArray(input.popouts)) fail('popouts', 'Expected array');\n else\n input.popouts.forEach((p, i) => {\n const path = `popouts[${i}]`;\n if (!record(p)) {\n fail(path, 'Expected popout object');\n return;\n }\n use(p.paneId, path + '.paneId');\n if (typeof p.groupId !== 'string' || !Number.isInteger(p.index) || Number(p.index) < 0)\n fail(path, 'Expected return group id and nonnegative index');\n if (p.placement !== undefined) {\n if (!record(p.placement)) fail(path + '.placement', 'Expected placement object');\n else\n for (const [key, value] of Object.entries(p.placement))\n if (\n !['width', 'height', 'left', 'top'].includes(key) ||\n !finite(value) ||\n (['width', 'height'].includes(key) && value <= 0)\n )\n fail(path + '.placement.' + key, 'Invalid window placement');\n }\n });\n for (const id of Object.keys(panes))\n if (!assigned.has(id)) fail(`panes.${id}`, 'Pane has no placement');\n if (\n input.maximized !== null &&\n (typeof input.maximized !== 'string' || !groups.has(input.maximized))\n )\n fail('maximized', 'Expected a group id or null');\n if (!errors.length) {\n const check = (n: Node) => {\n const b = bounds(n, input as unknown as Layout);\n if (b.minWidth > b.maxWidth || b.minHeight > b.maxHeight)\n fail(n.id, 'Pane constraints cannot coexist in this region');\n if (n.kind === 'split') n.children.forEach(check);\n };\n check(input.root as unknown as Node);\n }\n return errors;\n}\nexport function parseLayout(input: unknown): Layout {\n const issues = validate(input);\n if (issues.length) throw new LayoutError(issues);\n return structuredClone(input) as Layout;\n}\nexport function findNode(root: Node, id: string): Node | undefined {\n return root.id === id\n ? root\n : root.kind === 'split'\n ? (findNode(root.children[0], id) ?? findNode(root.children[1], id))\n : undefined;\n}\nexport function findParent(root: Node, id: string): import('./types.js').Split | undefined {\n if (root.kind === 'group') return undefined;\n return root.children.some((n) => n.id === id)\n ? root\n : (findParent(root.children[0], id) ?? findParent(root.children[1], id));\n}\nexport function groups(root: Node): Group[] {\n return root.kind === 'group' ? [root] : root.children.flatMap(groups);\n}\nexport function paneIds(root: Node): string[] {\n return groups(root).flatMap((g) => g.panes);\n}\nfunction paneBounds(p: Pane): Bounds {\n return {\n minWidth: p.size?.minWidth ?? 0,\n maxWidth: p.size?.maxWidth ?? Infinity,\n minHeight: p.size?.minHeight ?? 0,\n maxHeight: p.size?.maxHeight ?? Infinity,\n };\n}\nexport const DIVIDER = 4;\n/** Aggregate model constraints, optionally resolving each group's bounds for a host renderer. */\nexport function bounds(\n node: Node,\n layout: Layout,\n resolveGroup?: (group: Group, constraints: Bounds) => Bounds,\n): Bounds {\n if (node.kind === 'group') {\n const values = node.panes.map((id) => paneBounds(layout.panes[id]!));\n const constraints = {\n minWidth: Math.max(0, ...values.map((b) => b.minWidth)),\n maxWidth: Math.min(Infinity, ...values.map((b) => b.maxWidth)),\n minHeight: Math.max(0, ...values.map((b) => b.minHeight)),\n maxHeight: Math.min(Infinity, ...values.map((b) => b.maxHeight)),\n };\n return resolveGroup ? resolveGroup(node, constraints) : constraints;\n }\n const a = bounds(node.children[0], layout, resolveGroup),\n b = bounds(node.children[1], layout, resolveGroup);\n return node.axis === 'horizontal'\n ? {\n minWidth: a.minWidth + b.minWidth + (node.gap ?? DIVIDER),\n maxWidth: a.maxWidth + b.maxWidth + (node.gap ?? DIVIDER),\n minHeight: Math.max(a.minHeight, b.minHeight),\n maxHeight: Math.max(a.maxHeight, b.maxHeight),\n }\n : {\n minHeight: a.minHeight + b.minHeight + (node.gap ?? DIVIDER),\n maxHeight: a.maxHeight + b.maxHeight + (node.gap ?? DIVIDER),\n minWidth: Math.max(a.minWidth, b.minWidth),\n maxWidth: Math.max(a.maxWidth, b.maxWidth),\n };\n}\n/** Returns content extents; overflow retains minimums, surplus beyond maximums stays empty. */\nexport function allocate(\n total: number,\n ratio: number,\n minA: number,\n maxA: number,\n minB: number,\n maxB: number,\n gap = DIVIDER,\n): [number, number] {\n const available = Math.max(total - gap, minA + minB);\n const used = Math.min(available, maxA + maxB);\n const low = Math.max(minA, used - maxB),\n high = Math.min(maxA, used - minB);\n const a = Math.max(low, Math.min(high, used * ratio));\n return [a, used - a];\n}\n\n/** Create independent, validated JSON for an empty or single-pane workspace. */\nexport function createLayout(options: { pane?: Pane; groupId?: string } = {}): Layout {\n const { pane, groupId = 'main' } = options;\n return parseLayout({\n version: 1,\n root: { kind: 'group', id: groupId, panes: pane ? [pane.id] : [], active: pane?.id ?? null },\n panes: pane ? { [pane.id]: pane } : {},\n popouts: [],\n maximized: null,\n });\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
export type AutoCollapse = 'enabled' | 'protected' | 'disabled';
|
|
2
|
+
/** User interaction policy. More specific values override workspace defaults. */
|
|
3
|
+
export interface CapabilityPolicy {
|
|
4
|
+
defaults?: Partial<Record<Capability, boolean>>;
|
|
5
|
+
/** Region overrides, keyed by Group.id. */
|
|
6
|
+
groups?: Record<string, Partial<Record<Capability, boolean>>>;
|
|
7
|
+
/** Tab overrides, keyed by Pane.id; take precedence over saved pane capabilities. */
|
|
8
|
+
panes?: Record<string, Partial<Record<Capability, boolean>>>;
|
|
9
|
+
}
|
|
2
10
|
export interface LayoutStoreOptions {
|
|
11
|
+
capabilities?: CapabilityPolicy;
|
|
3
12
|
/** Session policy; omitted defaults to disabled. Not serialized in Layout JSON. */
|
|
4
13
|
autoCollapse?: AutoCollapse;
|
|
5
14
|
}
|
|
6
15
|
export type Json = null | boolean | number | string | Json[] | {
|
|
7
16
|
[key: string]: Json;
|
|
8
17
|
};
|
|
9
|
-
export type Capability = 'resize' | 'move' | 'split' | 'join' | 'close' | 'popout';
|
|
18
|
+
export type Capability = 'resize' | 'move' | 'reorder' | 'addTab' | 'maximize' | 'split' | 'join' | 'close' | 'popout';
|
|
10
19
|
export type Axis = 'horizontal' | 'vertical';
|
|
11
20
|
export interface Pane {
|
|
12
21
|
/** Override the pane-type close confirmation default. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAChE,MAAM,WAAW,kBAAkB;IACjC,mFAAmF;IACnF,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AACD,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AACvF,MAAM,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2EA,MAAM,OAAO,WAAY,SAAQ,KAAK;IACR,MAAM;IAAlC,YAA4B,MAAe;QACzC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;sBADrC,MAAM;QAEhC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF","sourcesContent":["export type AutoCollapse = 'enabled' | 'protected' | 'disabled';\n/** User interaction policy. More specific values override workspace defaults. */\nexport interface CapabilityPolicy {\n defaults?: Partial<Record<Capability, boolean>>;\n /** Region overrides, keyed by Group.id. */\n groups?: Record<string, Partial<Record<Capability, boolean>>>;\n /** Tab overrides, keyed by Pane.id; take precedence over saved pane capabilities. */\n panes?: Record<string, Partial<Record<Capability, boolean>>>;\n}\nexport interface LayoutStoreOptions {\n capabilities?: CapabilityPolicy;\n /** Session policy; omitted defaults to disabled. Not serialized in Layout JSON. */\n autoCollapse?: AutoCollapse;\n}\nexport type Json = null | boolean | number | string | Json[] | { [key: string]: Json };\nexport type Capability =\n 'resize' | 'move' | 'reorder' | 'addTab' | 'maximize' | 'split' | 'join' | 'close' | 'popout';\nexport type Axis = 'horizontal' | 'vertical';\nexport interface Pane {\n /** Override the pane-type close confirmation default. */\n confirmClose?: boolean;\n id: string;\n type: string;\n title: string;\n /** Application-defined icon key, resolved by the view adapter. */\n icon?: string;\n params?: Json;\n capabilities?: Partial<Record<Capability, boolean>>;\n size?: { minWidth?: number; maxWidth?: number; minHeight?: number; maxHeight?: number };\n /** Hide chrome only for a one-tab group. Host commands can still operate on it. */\n header?: boolean;\n}\nexport interface Group {\n kind: 'group';\n id: string;\n panes: string[];\n active: string | null;\n /** Persisted tab orientation for this region; omitted inherits renderer settings. */\n tabPlacement?: 'top' | 'left';\n /** Omitted inherits the workspace tab display setting. */\n tabDisplay?: 'automatic' | 'compact';\n}\nexport interface Split {\n kind: 'split';\n id: string;\n axis: Axis;\n ratio: number;\n /** Divider space in pixels; zero removes fixed-bar gaps. Default 4. */\n gap?: number;\n children: [Node, Node];\n}\nexport type Node = Group | Split;\nexport interface WindowPlacement {\n width?: number;\n height?: number;\n left?: number;\n top?: number;\n}\nexport interface Popout {\n paneId: string;\n groupId: string;\n index: number;\n placement?: WindowPlacement;\n}\nexport interface Layout {\n version: 1;\n root: Node;\n panes: Record<string, Pane>;\n popouts: Popout[];\n maximized: string | null;\n}\nexport interface Issue {\n path: string;\n message: string;\n}\nexport class LayoutError extends Error {\n constructor(public readonly issues: Issue[]) {\n super(issues.map((i) => `${i.path}: ${i.message}`).join('; '));\n this.name = 'LayoutError';\n }\n}\nexport interface CommandOptions {\n /** Treat capability flags as user-interaction restrictions. */ source?: 'user' | 'api';\n}\nexport interface Change {\n action: string;\n layout: Layout;\n}\nexport interface Bounds {\n minWidth: number;\n maxWidth: number;\n minHeight: number;\n maxHeight: number;\n}\n\nexport interface JoinOptions extends CommandOptions {\n /** Optional rendered extents along the join axis, keyed by node ID, including splits.\n * Supply the complete row to retain actual sizes under constraints and custom dividers.\n * Without measurements, joins retain proportional shares of the row/column.\n */\n extents?: Record<string, number>;\n}\n"]}
|
package/package.json
CHANGED
package/src/controller.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
JoinOptions,
|
|
8
8
|
Axis,
|
|
9
9
|
Capability,
|
|
10
|
+
CapabilityPolicy,
|
|
10
11
|
Change,
|
|
11
12
|
CommandOptions,
|
|
12
13
|
Group,
|
|
@@ -36,7 +37,9 @@ export class LayoutStore {
|
|
|
36
37
|
private notifying = false;
|
|
37
38
|
private pending: Change[] = [];
|
|
38
39
|
private autoCollapse: AutoCollapse = 'disabled';
|
|
40
|
+
private capabilities: CapabilityPolicy = {};
|
|
39
41
|
constructor(input: unknown, options: LayoutStoreOptions = {}) {
|
|
42
|
+
this.setCapabilities(options.capabilities);
|
|
40
43
|
this.setAutoCollapse(options.autoCollapse ?? 'disabled');
|
|
41
44
|
this.state = freeze(parseLayout(input));
|
|
42
45
|
this.initial = this.export();
|
|
@@ -134,7 +137,7 @@ export class LayoutStore {
|
|
|
134
137
|
}
|
|
135
138
|
private permit(draft: Layout, ids: string[], cap: Capability, options: CommandOptions) {
|
|
136
139
|
for (const id of ids)
|
|
137
|
-
if (options.source === 'user' && this.
|
|
140
|
+
if (options.source === 'user' && !this.canPane(draft, id, cap))
|
|
138
141
|
problem(`${cap} is disabled for ${id}`);
|
|
139
142
|
}
|
|
140
143
|
private id(draft: Layout): string {
|
|
@@ -178,12 +181,81 @@ export class LayoutStore {
|
|
|
178
181
|
}
|
|
179
182
|
if (draft.maximized && !findNode(draft.root, draft.maximized)) draft.maximized = null;
|
|
180
183
|
}
|
|
181
|
-
|
|
184
|
+
/** Replace session policy; layout export/load never serializes or resets it. */
|
|
185
|
+
setCapabilities(policy: CapabilityPolicy = {}): void {
|
|
186
|
+
this.alive();
|
|
187
|
+
const flags = (value: unknown) => {
|
|
188
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
189
|
+
problem('Invalid capabilities');
|
|
190
|
+
for (const [key, flag] of Object.entries(value!))
|
|
191
|
+
if (
|
|
192
|
+
![
|
|
193
|
+
'resize',
|
|
194
|
+
'move',
|
|
195
|
+
'reorder',
|
|
196
|
+
'addTab',
|
|
197
|
+
'maximize',
|
|
198
|
+
'split',
|
|
199
|
+
'join',
|
|
200
|
+
'close',
|
|
201
|
+
'popout',
|
|
202
|
+
].includes(key) ||
|
|
203
|
+
typeof flag !== 'boolean'
|
|
204
|
+
)
|
|
205
|
+
problem('Invalid capability: ' + key);
|
|
206
|
+
};
|
|
207
|
+
if (!policy || typeof policy !== 'object' || Array.isArray(policy))
|
|
208
|
+
problem('Invalid capability policy');
|
|
209
|
+
for (const [key, value] of Object.entries(policy)) {
|
|
210
|
+
if (value === undefined) continue;
|
|
211
|
+
if (key === 'defaults') flags(value);
|
|
212
|
+
else if (key === 'groups' || key === 'panes') {
|
|
213
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
214
|
+
problem('Invalid capability overrides');
|
|
215
|
+
Object.values(value).forEach(flags);
|
|
216
|
+
} else problem('Unknown capability scope: ' + key);
|
|
217
|
+
}
|
|
218
|
+
this.capabilities = structuredClone(policy);
|
|
219
|
+
}
|
|
220
|
+
private canPane(layout: Layout, paneId: string, capability: Capability): boolean {
|
|
221
|
+
const pane = layout.panes[paneId];
|
|
222
|
+
if (!pane) return false;
|
|
223
|
+
const groupId =
|
|
224
|
+
groups(layout.root).find((g) => g.panes.includes(paneId))?.id ??
|
|
225
|
+
layout.popouts.find((p) => p.paneId === paneId)?.groupId;
|
|
182
226
|
return (
|
|
183
|
-
|
|
184
|
-
|
|
227
|
+
this.capabilities.panes?.[paneId]?.[capability] ??
|
|
228
|
+
pane.capabilities?.[capability] ??
|
|
229
|
+
(groupId ? this.capabilities.groups?.[groupId]?.[capability] : undefined) ??
|
|
230
|
+
this.capabilities.defaults?.[capability] ??
|
|
231
|
+
(capability === 'addTab' || capability === 'reorder'
|
|
232
|
+
? this.canPane(layout, paneId, 'move')
|
|
233
|
+
: true)
|
|
185
234
|
);
|
|
186
235
|
}
|
|
236
|
+
can(paneId: string, capability: Capability): boolean {
|
|
237
|
+
return this.canPane(this.state, paneId, capability);
|
|
238
|
+
}
|
|
239
|
+
private canNodeIn(layout: Layout, node: Node, capability: Capability): boolean {
|
|
240
|
+
if (node.kind === 'split')
|
|
241
|
+
return node.children.every((child) => this.canNodeIn(layout, child, capability));
|
|
242
|
+
return node.panes.length
|
|
243
|
+
? node.panes.every((id) => this.canPane(layout, id, capability))
|
|
244
|
+
: (this.capabilities.groups?.[node.id]?.[capability] ??
|
|
245
|
+
this.capabilities.defaults?.[capability] ??
|
|
246
|
+
(capability === 'addTab' || capability === 'reorder'
|
|
247
|
+
? this.canNodeIn(layout, node, 'move')
|
|
248
|
+
: true));
|
|
249
|
+
}
|
|
250
|
+
/** Test every affected tab, including policy on empty regions. */
|
|
251
|
+
canNode(nodeId: string, capability: Capability): boolean {
|
|
252
|
+
const node = findNode(this.state.root, nodeId);
|
|
253
|
+
return !!node && this.canNodeIn(this.state, node, capability);
|
|
254
|
+
}
|
|
255
|
+
private permitNode(layout: Layout, node: Node, capability: Capability, options: CommandOptions) {
|
|
256
|
+
if (options.source === 'user' && !this.canNodeIn(layout, node, capability))
|
|
257
|
+
problem(`${capability} is disabled for ${node.id}`);
|
|
258
|
+
}
|
|
187
259
|
load(input: unknown) {
|
|
188
260
|
this.commit('load', (draft) => {
|
|
189
261
|
const next = parseLayout(input);
|
|
@@ -221,7 +293,7 @@ export class LayoutStore {
|
|
|
221
293
|
this.commit('resize', (d) => {
|
|
222
294
|
const n = findNode(d.root, splitId);
|
|
223
295
|
if (n?.kind !== 'split') problem('Split not found');
|
|
224
|
-
this.
|
|
296
|
+
this.permitNode(d, n, 'resize', options);
|
|
225
297
|
n.ratio = ratio;
|
|
226
298
|
});
|
|
227
299
|
}
|
|
@@ -231,21 +303,21 @@ export class LayoutStore {
|
|
|
231
303
|
for (const [id, ratio] of Object.entries(ratios)) {
|
|
232
304
|
const node = findNode(d.root, id);
|
|
233
305
|
if (node?.kind !== 'split') problem('Split not found');
|
|
234
|
-
this.
|
|
306
|
+
this.permitNode(d, node, 'resize', options);
|
|
235
307
|
node.ratio = ratio;
|
|
236
308
|
}
|
|
237
309
|
});
|
|
238
310
|
}
|
|
239
|
-
maximize(groupId: string | null) {
|
|
311
|
+
maximize(groupId: string | null, options: CommandOptions = {}) {
|
|
240
312
|
this.commit('maximize', (d) => {
|
|
241
|
-
if (groupId) this.group(d, groupId);
|
|
313
|
+
if (groupId) this.permitNode(d, this.group(d, groupId), 'maximize', options);
|
|
242
314
|
d.maximized = groupId;
|
|
243
315
|
});
|
|
244
316
|
}
|
|
245
317
|
add(pane: Pane, groupId: string, options: CommandOptions = {}) {
|
|
246
318
|
this.commit('add', (d) => {
|
|
247
319
|
const g = this.group(d, groupId);
|
|
248
|
-
this.
|
|
320
|
+
this.permitNode(d, g, 'addTab', options);
|
|
249
321
|
if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');
|
|
250
322
|
Object.defineProperty(d.panes, pane.id, {
|
|
251
323
|
value: structuredClone(pane),
|
|
@@ -272,7 +344,7 @@ export class LayoutStore {
|
|
|
272
344
|
let created = '';
|
|
273
345
|
this.commit('split', (d) => {
|
|
274
346
|
const g = this.group(d, groupId);
|
|
275
|
-
this.
|
|
347
|
+
this.permitNode(d, g, 'split', options);
|
|
276
348
|
if (pane) {
|
|
277
349
|
if (Object.hasOwn(d.panes, pane.id)) problem('Pane id already exists');
|
|
278
350
|
Object.defineProperty(d.panes, pane.id, {
|
|
@@ -300,7 +372,7 @@ export class LayoutStore {
|
|
|
300
372
|
return created;
|
|
301
373
|
}
|
|
302
374
|
/** Cancel only an unfilled region; never roll back edits made elsewhere. */
|
|
303
|
-
removeEmptyGroup(groupId: string) {
|
|
375
|
+
removeEmptyGroup(groupId: string, options: CommandOptions = {}) {
|
|
304
376
|
const existing = findNode(this.state.root, groupId);
|
|
305
377
|
if (
|
|
306
378
|
existing?.kind !== 'group' ||
|
|
@@ -309,6 +381,7 @@ export class LayoutStore {
|
|
|
309
381
|
)
|
|
310
382
|
return;
|
|
311
383
|
this.commit('removeEmptyGroup', (d) => {
|
|
384
|
+
this.permitNode(d, this.group(d, groupId), 'close', options);
|
|
312
385
|
if (d.maximized === groupId) d.maximized = null;
|
|
313
386
|
const parent = findParent(d.root, groupId)!;
|
|
314
387
|
this.replace(d, parent, parent.children[parent.children[0].id === groupId ? 1 : 0]);
|
|
@@ -326,8 +399,10 @@ export class LayoutStore {
|
|
|
326
399
|
const target = this.group(d, groupId);
|
|
327
400
|
const source = groups(d.root).find((g) => g.panes.includes(paneId));
|
|
328
401
|
if (!source) problem('Return a popped-out pane before moving it');
|
|
329
|
-
|
|
330
|
-
|
|
402
|
+
const capability = source === target && position === 'tab' ? 'reorder' : 'move';
|
|
403
|
+
this.permit(d, [paneId], capability, options);
|
|
404
|
+
this.permitNode(d, target, capability, options);
|
|
405
|
+
if (position !== 'tab') this.permitNode(d, target, 'split', options);
|
|
331
406
|
if (source === target && target.panes.length === 1) return;
|
|
332
407
|
this.detach(d, paneId);
|
|
333
408
|
if (position === 'tab') {
|
|
@@ -357,7 +432,7 @@ export class LayoutStore {
|
|
|
357
432
|
const g = this.group(d, groupId),
|
|
358
433
|
parent = findParent(d.root, groupId);
|
|
359
434
|
if (!parent) return;
|
|
360
|
-
this.
|
|
435
|
+
this.permitNode(d, parent, 'join', options);
|
|
361
436
|
g.panes = paneIds(parent);
|
|
362
437
|
g.active ??= g.panes[0] ?? null;
|
|
363
438
|
this.replace(d, parent, g);
|
|
@@ -368,7 +443,7 @@ export class LayoutStore {
|
|
|
368
443
|
closeGroup(groupId: string, options: CommandOptions = {}) {
|
|
369
444
|
this.commit('closeGroup', (d) => {
|
|
370
445
|
const group = this.group(d, groupId);
|
|
371
|
-
this.
|
|
446
|
+
this.permitNode(d, group, 'close', options);
|
|
372
447
|
for (const id of group.panes) delete d.panes[id];
|
|
373
448
|
group.panes = [];
|
|
374
449
|
group.active = null;
|
|
@@ -386,7 +461,7 @@ export class LayoutStore {
|
|
|
386
461
|
if (!range) problem('Join requires contiguous regions in one row or column');
|
|
387
462
|
const { row, regions, boundaries, start, end, selected } = range;
|
|
388
463
|
const panes = selected.flatMap((g) => g.panes);
|
|
389
|
-
this.
|
|
464
|
+
selected.forEach((group) => this.permitNode(d, group, 'join', options));
|
|
390
465
|
let sizes = range.weights;
|
|
391
466
|
let gaps = boundaries.map(() => 0);
|
|
392
467
|
if (options.extents) {
|
package/src/index.ts
CHANGED
package/src/model.ts
CHANGED
|
@@ -53,7 +53,17 @@ export function validate(input: unknown): Issue[] {
|
|
|
53
53
|
else
|
|
54
54
|
for (const [key, value] of Object.entries(pane.capabilities))
|
|
55
55
|
if (
|
|
56
|
-
![
|
|
56
|
+
![
|
|
57
|
+
'resize',
|
|
58
|
+
'move',
|
|
59
|
+
'reorder',
|
|
60
|
+
'addTab',
|
|
61
|
+
'maximize',
|
|
62
|
+
'split',
|
|
63
|
+
'join',
|
|
64
|
+
'close',
|
|
65
|
+
'popout',
|
|
66
|
+
].includes(key) ||
|
|
57
67
|
typeof value !== 'boolean'
|
|
58
68
|
)
|
|
59
69
|
fail(`panes.${id}.capabilities.${key}`, 'Unknown capability or non-boolean flag');
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
export type AutoCollapse = 'enabled' | 'protected' | 'disabled';
|
|
2
|
+
/** User interaction policy. More specific values override workspace defaults. */
|
|
3
|
+
export interface CapabilityPolicy {
|
|
4
|
+
defaults?: Partial<Record<Capability, boolean>>;
|
|
5
|
+
/** Region overrides, keyed by Group.id. */
|
|
6
|
+
groups?: Record<string, Partial<Record<Capability, boolean>>>;
|
|
7
|
+
/** Tab overrides, keyed by Pane.id; take precedence over saved pane capabilities. */
|
|
8
|
+
panes?: Record<string, Partial<Record<Capability, boolean>>>;
|
|
9
|
+
}
|
|
2
10
|
export interface LayoutStoreOptions {
|
|
11
|
+
capabilities?: CapabilityPolicy;
|
|
3
12
|
/** Session policy; omitted defaults to disabled. Not serialized in Layout JSON. */
|
|
4
13
|
autoCollapse?: AutoCollapse;
|
|
5
14
|
}
|
|
6
15
|
export type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
|
|
7
|
-
export type Capability =
|
|
16
|
+
export type Capability =
|
|
17
|
+
'resize' | 'move' | 'reorder' | 'addTab' | 'maximize' | 'split' | 'join' | 'close' | 'popout';
|
|
8
18
|
export type Axis = 'horizontal' | 'vertical';
|
|
9
19
|
export interface Pane {
|
|
10
20
|
/** Override the pane-type close confirmation default. */
|