@dashfoo/core 0.5.2 → 1.1.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/README.md +19 -12
- package/dist/index.d.ts +317 -113
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +373 -267
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/model/schema.ts","../src/state/actions.ts","../src/model/ids.ts","../src/model/tree.ts","../src/model/builders.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/model/invariants.ts","../src/state/surgery.ts","../src/state/floats.ts","../src/state/reducer.ts","../src/state/history.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/model/serialize.ts","../src/model/stack.ts"],"sourcesContent":["import { z } from \"zod\";\n\ntype JsonValue = string | number | boolean | null | Array<JsonValue> | { [key: string]: JsonValue };\n\nconst jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nconst edgeSchema = z.enum([\"top\", \"bottom\", \"left\", \"right\"]);\nconst unitSchema = z.enum([\"px\", \"%\", \"em\", \"rem\", \"vh\", \"vw\"]);\nconst orientationSchema = z.enum([\"row\", \"column\"]);\n\nconst dimensionSchema = z.object({\n unit: unitSchema,\n value: z.number(),\n});\n\nconst snapSchema = z.object({\n divisions: z.union([z.number().positive(), z.literal(\"panels\")]).optional(),\n step: z.number().min(0).optional(),\n threshold: z.number().positive().optional(),\n});\n\nconst tabNodeSchema = z.object({\n component: z.string(),\n config: jsonValueSchema.optional(),\n enableClose: z.boolean().optional(),\n enableDrag: z.boolean().optional(),\n enableRename: z.boolean().optional(),\n id: z.string(),\n name: z.string(),\n type: z.literal(\"tab\"),\n});\n\nconst tabsetNodeSchema = z.object({\n children: z.array(tabNodeSchema),\n enableClose: z.boolean().optional(),\n enableMaximize: z.boolean().optional(),\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n name: z.string().optional(),\n selected: z.number().int(),\n type: z.literal(\"tabset\"),\n weight: z.number().optional(),\n});\n\ntype RowNode = {\n children: Array<RowNode | z.infer<typeof tabsetNodeSchema>>;\n id: string;\n max?: z.infer<typeof dimensionSchema>;\n min?: z.infer<typeof dimensionSchema>;\n orientation: z.infer<typeof orientationSchema>;\n snap?: z.infer<typeof snapSchema>;\n type: \"row\";\n weight?: number;\n};\n\nconst rowNodeSchema: z.ZodType<RowNode> = z.lazy(() =>\n z.object({\n children: z.array(z.union([rowNodeSchema, tabsetNodeSchema])),\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n type: z.literal(\"row\"),\n weight: z.number().optional(),\n }),\n);\n\nconst geometrySchema = z.object({\n height: z.number(),\n left: z.number(),\n top: z.number(),\n width: z.number(),\n});\n\nconst floatNodeSchema = z.object({\n geometry: geometrySchema,\n id: z.string(),\n layout: rowNodeSchema,\n\n minimized: z.boolean().optional(),\n name: z.string().optional(),\n type: z.literal(\"float\"),\n});\n\nconst globalAttributesSchema = z.object({\n enableSplitDock: z.boolean().optional(),\n enableSplitResize: z.boolean().optional(),\n snap: snapSchema.optional(),\n splitterSize: z.number().optional(),\n tabEnableClose: z.boolean().optional(),\n tabEnableDrag: z.boolean().optional(),\n tabEnableRename: z.boolean().optional(),\n tabLocation: z.enum([\"top\", \"bottom\"]).optional(),\n tabSetEnableMaximize: z.boolean().optional(),\n tabSetEnableTabStrip: z.boolean().optional(),\n tabSetMinSize: z.number().optional(),\n});\n\nconst dashfooSchema = z.object({\n activeTabsetId: z.string().optional(),\n floats: z.array(floatNodeSchema).optional(),\n global: globalAttributesSchema,\n layout: rowNodeSchema,\n maximizedTabsetId: z.string().optional(),\n version: z.literal(1),\n});\n\ntype Json = JsonValue;\ntype Edge = z.infer<typeof edgeSchema>;\ntype Unit = z.infer<typeof unitSchema>;\ntype Orientation = z.infer<typeof orientationSchema>;\ntype Dimension = z.infer<typeof dimensionSchema>;\ntype SnapConfig = z.infer<typeof snapSchema>;\ntype TabNode = z.infer<typeof tabNodeSchema>;\ntype TabsetNode = z.infer<typeof tabsetNodeSchema>;\ntype Geometry = z.infer<typeof geometrySchema>;\ntype FloatNode = z.infer<typeof floatNodeSchema>;\ntype GlobalAttributes = z.infer<typeof globalAttributesSchema>;\ntype Dashfoo = z.infer<typeof dashfooSchema>;\ntype Node = RowNode | TabsetNode | TabNode;\n\nexport {\n dashfooSchema,\n dimensionSchema,\n edgeSchema,\n floatNodeSchema,\n geometrySchema,\n globalAttributesSchema,\n jsonValueSchema,\n orientationSchema,\n rowNodeSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeSchema,\n unitSchema,\n};\n\nexport type {\n Dashfoo,\n Dimension,\n Edge,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n Node,\n Orientation,\n RowNode,\n SnapConfig,\n TabNode,\n TabsetNode,\n Unit,\n};\n","import { z } from \"zod\";\n\nimport {\n dimensionSchema,\n geometrySchema,\n globalAttributesSchema,\n orientationSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeSchema,\n} from \"../model/schema\";\n\nconst mutableTabAttrsSchema = tabNodeSchema\n .pick({\n config: true,\n enableClose: true,\n enableDrag: true,\n enableRename: true,\n name: true,\n })\n .partial();\n\nconst mutableTabsetAttrsSchema = tabsetNodeSchema\n .pick({\n enableClose: true,\n enableMaximize: true,\n max: true,\n min: true,\n selected: true,\n weight: true,\n })\n .partial();\n\nconst mutableRowAttrsSchema = z\n .object({\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n weight: z.number(),\n })\n .partial();\n\nconst mutableNodeAttrsSchema = z.union([\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n mutableRowAttrsSchema,\n]);\n\nconst dockLocationSchema = z.enum([\n \"center\",\n \"split-bottom\",\n \"split-left\",\n \"split-right\",\n \"split-top\",\n]);\n\nconst splitWeightsSchema = z.array(z.number());\n\nconst actionSchema = z.discriminatedUnion(\"type\", [\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n tab: tabNodeSchema,\n targetId: z.string(),\n type: z.literal(\"addNode\"),\n }),\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveNode\"),\n }),\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveTabset\"),\n }),\n z.object({ index: z.number().int(), tabsetId: z.string(), type: z.literal(\"selectTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"setActiveTabset\") }),\n z.object({ tabsetId: z.string().nullable(), type: z.literal(\"setMaximizedTabset\") }),\n z.object({ name: z.string(), tabId: z.string(), type: z.literal(\"renameTab\") }),\n z.object({ tabId: z.string(), type: z.literal(\"deleteTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"deleteTabset\") }),\n z.object({\n rowId: z.string(),\n type: z.literal(\"adjustSplit\"),\n weights: splitWeightsSchema,\n }),\n z.object({\n attrs: mutableNodeAttrsSchema,\n nodeId: z.string(),\n type: z.literal(\"updateNodeAttributes\"),\n }),\n z.object({ attrs: globalAttributesSchema.partial(), type: z.literal(\"updateGlobalAttributes\") }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabId: z.string(),\n type: z.literal(\"floatTab\"),\n }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabsetId: z.string(),\n type: z.literal(\"floatTabset\"),\n }),\n\n z.object({\n floatId: z.string(),\n location: dockLocationSchema.optional(),\n targetId: z.string().optional(),\n type: z.literal(\"dockFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n geometry: geometrySchema,\n type: z.literal(\"moveFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n minimized: z.boolean(),\n type: z.literal(\"setFloatMinimized\"),\n }),\n\n z.object({\n floatId: z.string(),\n name: z.string(),\n type: z.literal(\"renameFloat\"),\n }),\n]);\n\ntype DockLocation = z.infer<typeof dockLocationSchema>;\ntype MutableNodeAttrs = z.infer<typeof mutableNodeAttrsSchema>;\ntype Action = z.infer<typeof actionSchema>;\n\ntype DropIntent = { index?: number; location: DockLocation; targetId: string };\n\nexport { actionSchema, dockLocationSchema, mutableNodeAttrsSchema };\nexport type { Action, DockLocation, DropIntent, MutableNodeAttrs };\n","const createNodeId = (prefix = \"node\"): string => `${prefix}-${crypto.randomUUID()}`;\n\nconst createTabId = (): string => createNodeId(\"tab\");\n\nexport { createNodeId, createTabId };\n","import type { Dashfoo, FloatNode, RowNode, TabNode, TabsetNode } from \"./schema\";\n\ntype TabContainer = TabsetNode;\ntype TabLocation = { container: TabContainer; index: number; tab: TabNode };\n\nconst collectRoots = (model: Dashfoo): Array<RowNode> => [\n model.layout,\n ...(model.floats ?? []).map((float) => float.layout),\n];\n\nconst findFloat = (model: Dashfoo, floatId: string): FloatNode | undefined =>\n (model.floats ?? []).find((float) => float.id === floatId);\n\ntype AttributedNode = RowNode | TabNode | TabsetNode;\n\ntype Visit = {\n index: number;\n node: AttributedNode;\n // A tabset's parent is always a row, a tab's is always a tabset; only a\n // walk's own root has none.\n parent: RowNode | TabsetNode | undefined;\n};\n\n/**\n * Depth-first pre-order over one root: the row itself, then each child in\n * order, descending into nested rows and into a tabset's tabs. Returning a\n * defined value from `visit` stops the walk and becomes the result, so one\n * traversal serves both find-first and collect-all.\n *\n * Every query below used to carry its own copy of this recursion, and they had\n * drifted in child order: some scanned a row's own tabsets before descending,\n * others interleaved. With unique ids all orders agree, so they now share this\n * one; a model with duplicate ids (which the builder and the parser both warn\n * about) can see a different duplicate win than it did before.\n */\nconst walk = <T>(\n row: RowNode,\n visit: (found: Visit) => T | undefined,\n parent?: RowNode,\n index = -1,\n): T | undefined => {\n const atRoot = visit({ index, node: row, parent });\n if (atRoot !== undefined) {\n return atRoot;\n }\n for (const [childIndex, child] of row.children.entries()) {\n if (child.type === \"row\") {\n const inRow = walk(child, visit, row, childIndex);\n if (inRow !== undefined) {\n return inRow;\n }\n continue;\n }\n const atTabset = visit({ index: childIndex, node: child, parent: row });\n if (atTabset !== undefined) {\n return atTabset;\n }\n for (const [tabIndex, tab] of child.children.entries()) {\n const atTab = visit({ index: tabIndex, node: tab, parent: child });\n if (atTab !== undefined) {\n return atTab;\n }\n }\n }\n return undefined;\n};\n\nconst locate = (row: RowNode, id: string): Visit | undefined =>\n walk(row, (found) => (found.node.id === id ? found : undefined));\n\nconst collectTabsetsInRow = (row: RowNode, acc: Array<TabsetNode>): void => {\n walk(row, ({ node }) => {\n if (node.type === \"tabset\") {\n acc.push(node);\n }\n return undefined;\n });\n};\n\nconst collectTabsets = (model: Dashfoo): Array<TabsetNode> => {\n const acc: Array<TabsetNode> = [];\n for (const root of collectRoots(model)) {\n collectTabsetsInRow(root, acc);\n }\n return acc;\n};\n\nconst getFirstTabset = (model: Dashfoo): TabsetNode | undefined => collectTabsets(model)[0];\n\nconst findTabset = (model: Dashfoo, tabsetId: string): TabsetNode | undefined =>\n collectTabsets(model).find((tabset) => tabset.id === tabsetId);\n\nconst findTabInContainer = (container: TabContainer, tabId: string): TabLocation | undefined => {\n const index = container.children.findIndex((tab) => tab.id === tabId);\n if (index === -1) {\n return undefined;\n }\n\n const tab = container.children.at(index);\n if (!tab) {\n return undefined;\n }\n\n return { container, index, tab };\n};\n\nconst findTab = (model: Dashfoo, tabId: string): TabLocation | undefined => {\n for (const tabset of collectTabsets(model)) {\n const found = findTabInContainer(tabset, tabId);\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\nconst findRow = (row: RowNode, id: string): RowNode | undefined => {\n const found = locate(row, id)?.node;\n return found?.type === \"row\" ? found : undefined;\n};\n\nconst findAttributedNodeInRow = (row: RowNode, id: string): AttributedNode | undefined =>\n locate(row, id)?.node;\n\nconst findAttributedNode = (model: Dashfoo, id: string): AttributedNode | undefined => {\n for (const root of collectRoots(model)) {\n const found = findAttributedNodeInRow(root, id);\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst findRootContaining = (model: Dashfoo, nodeId: string): RowNode | undefined => {\n for (const root of collectRoots(model)) {\n if (findAttributedNodeInRow(root, nodeId)) {\n return root;\n }\n }\n return undefined;\n};\n\nconst findTabsetParent = (\n row: RowNode,\n tabsetId: string,\n): { index: number; parent: RowNode } | undefined => {\n const found = locate(row, tabsetId);\n return found?.node.type === \"tabset\" && found.parent?.type === \"row\"\n ? { index: found.index, parent: found.parent }\n : undefined;\n};\n\nconst collectIdsInRow = (row: RowNode, acc: Array<string>): void => {\n walk(row, ({ node }) => {\n acc.push(node.id);\n return undefined;\n });\n};\n\nconst findDuplicateIds = (model: Dashfoo): Array<string> => {\n const ids: Array<string> = [];\n for (const float of model.floats ?? []) {\n ids.push(float.id);\n }\n for (const root of collectRoots(model)) {\n collectIdsInRow(root, ids);\n }\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const id of ids) {\n if (seen.has(id)) {\n duplicates.add(id);\n }\n seen.add(id);\n }\n return [...duplicates];\n};\n\nexport {\n collectRoots,\n collectTabsets,\n collectTabsetsInRow,\n findAttributedNode,\n findDuplicateIds,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n findTabsetParent,\n getFirstTabset,\n};\nexport type { AttributedNode, TabContainer, TabLocation };\n","import { createNodeId } from \"./ids\";\nimport type {\n Dashfoo,\n Dimension,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n RowNode,\n SnapConfig,\n TabNode,\n TabsetNode,\n} from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst toDimension = (value: number | Dimension): Dimension =>\n typeof value === \"number\" ? { unit: \"px\", value } : value;\n\ntype TabOptions = {\n config?: Json;\n enableClose?: boolean;\n enableDrag?: boolean;\n enableRename?: boolean;\n id?: string;\n};\n\nconst tab = (component: string, name: string, options: TabOptions = {}): TabNode => ({\n component,\n name,\n type: \"tab\",\n ...options,\n id: options.id ?? component,\n});\n\ntype TabsetOptions = {\n enableClose?: boolean;\n enableMaximize?: boolean;\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n name?: string;\n selected?: number;\n weight?: number;\n};\n\nconst tabset = (children: Array<TabNode>, options: TabsetOptions = {}): TabsetNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"tabset\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"tabset\"),\n selected: options.selected ?? 0,\n };\n};\n\ntype RowOptions = {\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n orientation?: RowNode[\"orientation\"];\n snap?: SnapConfig;\n weight?: number;\n};\n\nconst row = (children: RowNode[\"children\"], options: RowOptions = {}): RowNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"row\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"row\"),\n orientation: options.orientation ?? \"row\",\n };\n};\n\ntype FloatOptions = {\n id?: string;\n name?: string;\n};\n\nconst floatNode = (layout: RowNode, geometry: Geometry, options: FloatOptions = {}): FloatNode => ({\n geometry,\n layout,\n type: \"float\",\n ...options,\n id: options.id ?? createNodeId(\"float\"),\n});\n\ntype ModelOptions = {\n activeTabsetId?: string;\n floats?: Array<FloatNode>;\n global?: GlobalAttributes;\n maximizedTabsetId?: string;\n};\n\nconst model = (layout: RowNode, options: ModelOptions = {}): Dashfoo => {\n const built: Dashfoo = {\n layout,\n version: 1,\n ...options,\n global: options.global ?? {},\n };\n const duplicates = findDuplicateIds(built);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(\n `[dashfoo] builder produced duplicate node ids: ${duplicates.join(\", \")}. Pass explicit ids when reusing a component`,\n );\n }\n return built;\n};\n\nexport { floatNode, model, row, tab, tabset };\nexport type { FloatOptions, ModelOptions, RowOptions, TabOptions, TabsetOptions };\n","import type { Edge } from \"../model/schema\";\nimport type { DockLocation } from \"../state/actions\";\n\ntype Point = { x: number; y: number };\ntype Rect = { height: number; width: number; x: number; y: number };\ntype DockTarget = { kind: \"tab\" } | { edge: Edge; kind: \"split\" };\ntype BandOptions = { bandFraction?: number };\ntype DockZone = { location: DockLocation; points: Array<Point> };\n\nconst DEFAULT_BAND_FRACTION = 0.22;\n\nconst edgeDistances = (\n pointer: Point,\n rect: Rect,\n): { bottom: number; left: number; right: number; top: number } => {\n const fx = (pointer.x - rect.x) / rect.width;\n const fy = (pointer.y - rect.y) / rect.height;\n return { bottom: 1 - fy, left: fx, right: 1 - fx, top: fy };\n};\n\nconst closestEdge = (d: { bottom: number; left: number; right: number; top: number }): Edge => {\n const min = Math.min(d.left, d.right, d.top, d.bottom);\n if (min === d.left) {\n return \"left\";\n }\n if (min === d.right) {\n return \"right\";\n }\n if (min === d.top) {\n return \"top\";\n }\n return \"bottom\";\n};\n\nconst resolveDockTarget = (pointer: Point, rect: Rect, opts?: BandOptions): DockTarget => {\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n\n if (rect.width <= 0 || rect.height <= 0) {\n return { kind: \"tab\" };\n }\n const distances = edgeDistances(pointer, rect);\n const min = Math.min(distances.left, distances.right, distances.top, distances.bottom);\n\n if (min > band) {\n return { kind: \"tab\" };\n }\n return { edge: closestEdge(distances), kind: \"split\" };\n};\n\nconst dockZonePolygons = (rect: Rect, opts?: BandOptions): Array<DockZone> => {\n const { height: h, width: w, x, y } = rect;\n const nw: Point = { x, y };\n const ne: Point = { x: x + w, y };\n const se: Point = { x: x + w, y: y + h };\n const sw: Point = { x, y: y + h };\n if (w <= 0 || h <= 0) {\n return [{ location: \"center\", points: [nw, ne, se, sw] }];\n }\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n const bx = band * w;\n const by = band * h;\n const innerNw: Point = { x: x + bx, y: y + by };\n const innerNe: Point = { x: x + w - bx, y: y + by };\n const innerSe: Point = { x: x + w - bx, y: y + h - by };\n const innerSw: Point = { x: x + bx, y: y + h - by };\n return [\n { location: \"center\", points: [innerNw, innerNe, innerSe, innerSw] },\n { location: \"split-left\", points: [nw, innerNw, innerSw, sw] },\n { location: \"split-right\", points: [ne, se, innerSe, innerNe] },\n { location: \"split-top\", points: [nw, ne, innerNe, innerNw] },\n { location: \"split-bottom\", points: [sw, innerSw, innerSe, se] },\n ];\n};\n\nconst zoneRect = (rect: Rect, location: DockLocation): Rect => {\n const halfW = rect.width / 2;\n const halfH = rect.height / 2;\n switch (location) {\n case \"split-bottom\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y + halfH };\n }\n case \"split-left\": {\n return { height: rect.height, width: halfW, x: rect.x, y: rect.y };\n }\n case \"split-right\": {\n return { height: rect.height, width: halfW, x: rect.x + halfW, y: rect.y };\n }\n case \"split-top\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y };\n }\n case \"center\": {\n return rect;\n }\n default: {\n return rect;\n }\n }\n};\n\nexport { dockZonePolygons, resolveDockTarget, zoneRect };\nexport type { BandOptions, DockTarget, DockZone, Point, Rect };\n","import type { SnapConfig } from \"../model/schema\";\n\nconst DEFAULT_SNAP_THRESHOLD = 4;\n\nconst TARGET_PRECISION = 1e6;\n\nconst addMultiples = (targets: Set<number>, increment: number): void => {\n if (increment <= 0) {\n return;\n }\n for (let position = increment; position < 100; position += increment) {\n const rounded = Math.round(position * TARGET_PRECISION) / TARGET_PRECISION;\n if (rounded < 100) {\n targets.add(rounded);\n }\n }\n};\n\nconst resolveSnapTargets = (config: SnapConfig, panelCount: number): Array<number> => {\n const targets = new Set<number>();\n if (config.step !== undefined && config.step > 0) {\n addMultiples(targets, config.step);\n }\n if (config.divisions !== undefined) {\n const divisions = config.divisions === \"panels\" ? panelCount : config.divisions;\n if (divisions >= 2) {\n addMultiples(targets, 100 / divisions);\n }\n }\n return [...targets].toSorted((a, b) => a - b);\n};\n\nconst snapEnabled = (config: SnapConfig | null): boolean =>\n config !== null &&\n ((config.step ?? 0) > 0 ||\n config.divisions === \"panels\" ||\n (typeof config.divisions === \"number\" && config.divisions >= 2));\n\nconst nearestTarget = (position: number, targets: Array<number>): number | undefined =>\n targets.reduce<number | undefined>((best, target) => {\n if (best === undefined || Math.abs(target - position) < Math.abs(best - position)) {\n return target;\n }\n return best;\n }, undefined);\n\ntype SnapResult = { sizes: Array<number>; snapped: boolean };\n\nconst snapSizes = (sizes: Array<number>, boundaryIndex: number, config: SnapConfig): SnapResult => {\n const threshold = config.threshold ?? DEFAULT_SNAP_THRESHOLD;\n const left = sizes[boundaryIndex];\n const right = sizes[boundaryIndex + 1];\n if (boundaryIndex < 0 || left === undefined || right === undefined) {\n return { sizes, snapped: false };\n }\n\n const targets = resolveSnapTargets(config, sizes.length);\n if (targets.length === 0) {\n return { sizes, snapped: false };\n }\n\n let position = 0;\n for (let index = 0; index <= boundaryIndex; index++) {\n position += sizes[index] ?? 0;\n }\n\n const target = nearestTarget(position, targets);\n if (target === undefined || Math.abs(target - position) > threshold) {\n return { sizes, snapped: false };\n }\n\n const delta = target - position;\n if (left + delta < 0 || right - delta < 0) {\n return { sizes, snapped: false };\n }\n\n const next = [...sizes];\n next[boundaryIndex] = left + delta;\n next[boundaryIndex + 1] = right - delta;\n return { sizes: next, snapped: true };\n};\n\nexport { DEFAULT_SNAP_THRESHOLD, resolveSnapTargets, snapEnabled, snapSizes };\nexport type { SnapResult };\n","import type { Dashfoo, FloatNode, RowNode, TabsetNode } from \"./schema\";\nimport { collectTabsets } from \"./tree\";\n\nconst clampSelected = (length: number, selected: number): number => {\n if (length === 0) {\n return 0;\n }\n\n const base = Number.isFinite(selected) ? Math.trunc(selected) : 0;\n if (base < 0) {\n return 0;\n }\n if (base > length - 1) {\n return length - 1;\n }\n return base;\n};\n\nconst normalizeTabset = (tabset: TabsetNode): TabsetNode => ({\n ...tabset,\n selected: clampSelected(tabset.children.length, tabset.selected),\n});\n\ntype RowChild = RowNode[\"children\"][number];\n\n/**\n * A row that collapses to a single child hands its slot in the parent to\n * that child, so the slot's sizing constraints have to travel with it.\n * Dropping them silently widens a pinned sidebar, and `normalize` runs on\n * load and on every persist, so the loss is permanent.\n *\n * `snap` only exists on rows, so it is carried only to a row survivor.\n */\nconst inheritSlot = (row: RowNode, survivor: RowChild): RowChild => {\n const sized: RowChild = {\n ...survivor,\n ...(row.weight === undefined ? {} : { weight: row.weight }),\n ...(row.min === undefined ? {} : { min: row.min }),\n ...(row.max === undefined ? {} : { max: row.max }),\n };\n\n if (sized.type === \"row\" && row.snap !== undefined) {\n return { ...sized, snap: row.snap };\n }\n return sized;\n};\n\nconst normalizeRowChildren = (children: RowNode[\"children\"]): RowNode[\"children\"] => {\n const out: RowNode[\"children\"] = [];\n\n for (const child of children) {\n if (child.type === \"tabset\") {\n if (child.children.length > 0) {\n out.push(normalizeTabset(child));\n }\n continue;\n }\n\n const grandchildren = normalizeRowChildren(child.children);\n if (grandchildren.length === 0) {\n continue;\n }\n if (grandchildren.length === 1) {\n const only = grandchildren[0];\n if (only !== undefined) {\n out.push(inheritSlot(child, only));\n }\n continue;\n }\n out.push({ ...child, children: grandchildren });\n }\n\n return out;\n};\n\nconst rowContainsTabset = (row: RowNode): boolean =>\n row.children.some((child) => (child.type === \"tabset\" ? true : rowContainsTabset(child)));\n\nconst normalizeLayout = (root: RowNode): RowNode => {\n let children = normalizeRowChildren(root.children);\n let orientation = root.orientation;\n\n let inner = children[0];\n while (children.length === 1 && inner?.type === \"row\") {\n children = inner.children;\n orientation = inner.orientation;\n inner = children[0];\n }\n\n return { ...root, children, orientation };\n};\n\nconst normalize = (model: Dashfoo): Dashfoo => {\n const layout = normalizeLayout(model.layout);\n\n const healedFloats: Array<FloatNode> = [];\n for (const float of model.floats ?? []) {\n const floatLayout = normalizeLayout(float.layout);\n if (rowContainsTabset(floatLayout)) {\n healedFloats.push({ ...float, layout: floatLayout });\n }\n }\n const floats = healedFloats.length > 0 ? healedFloats : undefined;\n\n const withRoots: Dashfoo = { ...model, floats, layout };\n\n const tabsetIds = new Set(collectTabsets(withRoots).map((tabset) => tabset.id));\n const firstTabsetId = collectTabsets(withRoots)[0]?.id;\n\n const activeTabsetId =\n model.activeTabsetId !== undefined && tabsetIds.has(model.activeTabsetId)\n ? model.activeTabsetId\n : firstTabsetId;\n\n const maximizedTabsetId =\n model.maximizedTabsetId !== undefined && tabsetIds.has(model.maximizedTabsetId)\n ? model.maximizedTabsetId\n : undefined;\n\n return { ...withRoots, activeTabsetId, maximizedTabsetId };\n};\n\nexport { clampSelected, normalize };\n","import { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, RowNode, TabNode, TabsetNode } from \"../model/schema\";\nimport { findRootContaining, findTabset, findTabsetParent } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\n\nconst removeTabsetReturning = (row: RowNode, tabsetId: string): TabsetNode | undefined => {\n const found = findTabsetParent(row, tabsetId);\n if (!found) {\n return undefined;\n }\n const [removed] = found.parent.children.splice(found.index, 1);\n return removed?.type === \"tabset\" ? removed : undefined;\n};\n\nconst removeTabset = (row: RowNode, tabsetId: string): boolean =>\n removeTabsetReturning(row, tabsetId) !== undefined;\n\nconst splitOrientation = (location: DockLocation): \"column\" | \"row\" =>\n location === \"split-left\" || location === \"split-right\" ? \"row\" : \"column\";\n\nconst splitsBefore = (location: DockLocation): boolean =>\n location === \"split-left\" || location === \"split-top\";\n\nconst placeBesideTarget = (\n draft: Dashfoo,\n placed: TabsetNode,\n targetId: string,\n location: DockLocation,\n): void => {\n const targetTabset = findTabset(draft, targetId);\n\n const targetRoot = findRootContaining(draft, targetId) ?? draft.layout;\n const found = findTabsetParent(targetRoot, targetId);\n if (!targetTabset || !found) {\n return;\n }\n\n const orientation = splitOrientation(location);\n const before = splitsBefore(location);\n\n if (found.parent.orientation === orientation) {\n const targetWeight = targetTabset.weight ?? 100;\n targetTabset.weight = targetWeight / 2;\n placed.weight = targetWeight / 2;\n found.parent.children.splice(before ? found.index : found.index + 1, 0, placed);\n } else {\n const targetWeight = targetTabset.weight;\n targetTabset.weight = 50;\n placed.weight = 50;\n const newRow: RowNode = {\n children: before ? [placed, targetTabset] : [targetTabset, placed],\n id: createNodeId(\"row\"),\n orientation,\n type: \"row\",\n };\n if (targetWeight !== undefined) {\n newRow.weight = targetWeight;\n }\n found.parent.children.splice(found.index, 1, newRow);\n }\n\n draft.activeTabsetId = placed.id;\n};\n\ntype DropTarget = { id: string; index?: number; location: DockLocation };\n\nconst insertTab = (draft: Dashfoo, tab: TabNode, target: DropTarget): void => {\n const { id: targetId, index, location } = target;\n const targetTabset = findTabset(draft, targetId);\n if (!targetTabset) {\n return;\n }\n\n if (location === \"center\") {\n const at = index ?? targetTabset.children.length;\n targetTabset.children.splice(at, 0, tab);\n targetTabset.selected = at;\n return;\n }\n\n const newTabset: TabsetNode = {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: 50,\n };\n placeBesideTarget(draft, newTabset, targetId, location);\n};\n\nconst mergeTabsInto = (target: TabsetNode, tabs: Array<TabNode>, selectedOffset: number): void => {\n const mergeStart = target.children.length;\n target.children.push(...tabs);\n target.selected = mergeStart + selectedOffset;\n};\n\nconst wrapTabInLayout = (tab: TabNode): RowNode => ({\n children: [{ children: [tab], id: createNodeId(\"tabset\"), selected: 0, type: \"tabset\" }],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n});\n\nconst wrapTabsetInLayout = (tabset: TabsetNode): RowNode => ({\n children: [tabset],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n});\n\nexport {\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabset,\n removeTabsetReturning,\n wrapTabInLayout,\n wrapTabsetInLayout,\n};\nexport type { DropTarget };\n","import { createNodeId } from \"../model/ids\";\nimport { clampSelected } from \"../model/invariants\";\nimport type { Dashfoo, FloatNode, Geometry, RowNode, TabsetNode } from \"../model/schema\";\nimport { collectTabsetsInRow, findRootContaining } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\nimport {\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabsetInLayout,\n} from \"./surgery\";\n\nconst DEFAULT_FLOAT_GEOMETRY: Geometry = { height: 360, left: 80, top: 80, width: 480 };\n\nconst uniqueFloatName = (base: string, floats: Array<FloatNode>): string => {\n const used = new Set(floats.map((float) => float.name));\n if (!used.has(base)) {\n return base;\n }\n let index = 1;\n while (used.has(`${base} ${index}`)) {\n index += 1;\n }\n return `${base} ${index}`;\n};\n\nconst pushFloat = (\n draft: Dashfoo,\n layout: RowNode,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): void => {\n const float: FloatNode = {\n geometry: geometry ?? DEFAULT_FLOAT_GEOMETRY,\n id: floatId ?? createNodeId(\"float\"),\n layout,\n name: uniqueFloatName(\"Panel\", draft.floats ?? []),\n type: \"float\",\n };\n draft.floats = [...(draft.floats ?? []), float];\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(layout, tabsets);\n const first = tabsets.at(0);\n if (first) {\n draft.activeTabsetId = first.id;\n }\n};\n\nconst floatTabsetById = (\n draft: Dashfoo,\n tabsetId: string,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): void => {\n const root = findRootContaining(draft, tabsetId);\n if (!root) {\n return;\n }\n const detached = removeTabsetReturning(root, tabsetId);\n if (detached) {\n pushFloat(draft, wrapTabsetInLayout(detached), geometry, floatId);\n }\n};\n\nconst resolveMainTarget = (\n draft: Dashfoo,\n targetId: string | undefined,\n): TabsetNode | undefined => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(draft.layout, mainTabsets);\n if (targetId !== undefined) {\n const explicit = mainTabsets.find((tabset) => tabset.id === targetId);\n if (explicit) {\n return explicit;\n }\n }\n if (draft.activeTabsetId !== undefined) {\n const active = mainTabsets.find((tabset) => tabset.id === draft.activeTabsetId);\n if (active) {\n return active;\n }\n }\n return mainTabsets[0];\n};\n\nconst dockFloat = (\n draft: Dashfoo,\n floatId: string,\n targetId: string | undefined,\n location: DockLocation | undefined,\n): void => {\n const floats = draft.floats ?? [];\n const index = floats.findIndex((float) => float.id === floatId);\n if (index === -1) {\n return;\n }\n const float = floats.splice(index, 1).at(0);\n draft.floats = floats;\n if (!float) {\n return;\n }\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(float.layout, tabsets);\n const tabs = tabsets.flatMap((tabset) => tabset.children);\n if (tabs.length === 0) {\n return;\n }\n\n const leadTabset = tabsets.at(0);\n const selectedOffset = leadTabset\n ? clampSelected(leadTabset.children.length, leadTabset.selected)\n : 0;\n\n const target = resolveMainTarget(draft, targetId);\n if (!target) {\n draft.layout = float.layout;\n draft.activeTabsetId = leadTabset?.id;\n return;\n }\n\n if (location === \"center\") {\n mergeTabsInto(target, tabs, selectedOffset);\n draft.activeTabsetId = target.id;\n return;\n }\n\n const where = location ?? \"split-right\";\n\n const placed: TabsetNode =\n tabsets.length === 1 && leadTabset\n ? leadTabset\n : { children: tabs, id: createNodeId(\"tabset\"), selected: selectedOffset, type: \"tabset\" };\n placed.weight = 50;\n placeBesideTarget(draft, placed, target.id, where);\n};\n\nexport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName };\n","import { clampSelected, normalize } from \"../model/invariants\";\nimport type { Dashfoo } from \"../model/schema\";\nimport {\n findAttributedNode,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n} from \"../model/tree\";\n\nimport type { Action } from \"./actions\";\nimport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName } from \"./floats\";\nimport {\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabset,\n removeTabsetReturning,\n wrapTabInLayout,\n} from \"./surgery\";\n\nconst assertNever = (value: never): never => {\n throw new Error(`Unhandled action: ${JSON.stringify(value)}`);\n};\n\nconst applyAction = (draft: Dashfoo, action: Action): void => {\n switch (action.type) {\n case \"addNode\": {\n insertTab(draft, action.tab, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n return;\n }\n case \"adjustSplit\": {\n const root = findRootContaining(draft, action.rowId) ?? draft.layout;\n const row = findRow(root, action.rowId);\n if (!row) {\n return;\n }\n for (let index = 0; index < action.weights.length; index++) {\n const child = row.children.at(index);\n const weight = action.weights[index];\n if (!child || weight === undefined) {\n continue;\n }\n child.weight = weight;\n }\n return;\n }\n case \"deleteTab\": {\n const location = findTab(draft, action.tabId);\n if (location) {\n location.container.children.splice(location.index, 1);\n }\n return;\n }\n case \"deleteTabset\": {\n const root = findRootContaining(draft, action.tabsetId);\n if (root) {\n removeTabset(root, action.tabsetId);\n }\n return;\n }\n case \"dockFloat\": {\n dockFloat(draft, action.floatId, action.targetId, action.location);\n return;\n }\n case \"floatTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return;\n }\n const removed = location.container.children.splice(location.index, 1).at(0);\n if (removed) {\n pushFloat(draft, wrapTabInLayout(removed), action.geometry, action.floatId);\n }\n return;\n }\n case \"floatTabset\": {\n floatTabsetById(draft, action.tabsetId, action.geometry, action.floatId);\n return;\n }\n case \"moveFloat\": {\n const float = findFloat(draft, action.floatId);\n if (float) {\n float.geometry = action.geometry;\n }\n return;\n }\n case \"moveNode\": {\n const source = findTab(draft, action.sourceId);\n if (!source) {\n return;\n }\n\n const removed = source.container.children.splice(source.index, 1).at(0);\n if (!removed) {\n return;\n }\n insertTab(draft, removed, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n return;\n }\n case \"moveTabset\": {\n if (action.sourceId === action.targetId) {\n return;\n }\n const source = findTabset(draft, action.sourceId);\n if (!source) {\n return;\n }\n if (action.location === \"center\") {\n const target = findTabset(draft, action.targetId);\n if (target) {\n mergeTabsInto(\n target,\n source.children,\n clampSelected(source.children.length, source.selected),\n );\n const sourceRoot = findRootContaining(draft, action.sourceId);\n if (sourceRoot) {\n removeTabset(sourceRoot, action.sourceId);\n }\n }\n return;\n }\n\n if (action.location.startsWith(\"split-\")) {\n const sourceRoot = findRootContaining(draft, action.sourceId);\n const detached = sourceRoot\n ? removeTabsetReturning(sourceRoot, action.sourceId)\n : undefined;\n if (detached) {\n placeBesideTarget(draft, detached, action.targetId, action.location);\n }\n }\n return;\n }\n case \"renameFloat\": {\n const float = findFloat(draft, action.floatId);\n if (float) {\n const others = (draft.floats ?? []).filter((other) => other.id !== action.floatId);\n float.name = uniqueFloatName(action.name, others);\n }\n return;\n }\n case \"renameTab\": {\n const location = findTab(draft, action.tabId);\n if (location) {\n location.tab.name = action.name;\n }\n return;\n }\n case \"selectTab\": {\n const tabset = findTabset(draft, action.tabsetId);\n if (tabset) {\n tabset.selected = action.index;\n }\n return;\n }\n case \"setActiveTabset\": {\n if (findTabset(draft, action.tabsetId)) {\n draft.activeTabsetId = action.tabsetId;\n }\n return;\n }\n case \"setFloatMinimized\": {\n const float = findFloat(draft, action.floatId);\n if (float) {\n float.minimized = action.minimized;\n }\n return;\n }\n case \"setMaximizedTabset\": {\n draft.maximizedTabsetId = action.tabsetId ?? undefined;\n return;\n }\n case \"updateGlobalAttributes\": {\n Object.assign(draft.global, action.attrs);\n return;\n }\n case \"updateNodeAttributes\": {\n const node = findAttributedNode(draft, action.nodeId);\n if (node) {\n Object.assign(node, action.attrs);\n }\n return;\n }\n default: {\n assertNever(action);\n }\n }\n};\n\nconst reducer = (model: Dashfoo, action: Action): Dashfoo => {\n const draft = structuredClone(model);\n applyAction(draft, action);\n return normalize(draft);\n};\n\nexport { reducer };\n","import type { Dashfoo } from \"../model/schema\";\n\nimport type { Action } from \"./actions\";\nimport { reducer } from \"./reducer\";\n\ntype History = {\n future: Array<Dashfoo>;\n past: Array<Dashfoo>;\n present: Dashfoo;\n};\n\nconst HISTORY_LIMIT = 100;\n\nconst createHistory = (present: Dashfoo): History => ({\n future: [],\n past: [],\n present,\n});\n\nconst canUndo = (history: History): boolean => history.past.length > 0;\nconst canRedo = (history: History): boolean => history.future.length > 0;\n\nconst dispatch = (history: History, action: Action): History => {\n const present = reducer(history.present, action);\n return { future: [], past: [...history.past, history.present].slice(-HISTORY_LIMIT), present };\n};\n\nconst undo = (history: History): History => {\n const previous = history.past.at(-1);\n if (previous === undefined) {\n return history;\n }\n return {\n future: [history.present, ...history.future],\n past: history.past.slice(0, -1),\n present: previous,\n };\n};\n\nconst redo = (history: History): History => {\n const [next, ...rest] = history.future;\n if (next === undefined) {\n return history;\n }\n return {\n future: rest,\n past: [...history.past, history.present].slice(-HISTORY_LIMIT),\n present: next,\n };\n};\n\nexport { canRedo, canUndo, createHistory, dispatch, HISTORY_LIMIT, redo, undo };\nexport type { History };\n","import { assign, setup } from \"xstate\";\n\nimport type { Dashfoo } from \"../model/schema\";\nimport type { Action } from \"../state/actions\";\nimport type { History } from \"../state/history\";\nimport { createHistory, dispatch, redo, undo } from \"../state/history\";\n\ntype DashfooContext = { history: History };\n\ntype DashfooEvent =\n | { action: Action; type: \"DISPATCH\" }\n | { model: Dashfoo; type: \"SET_MODEL\" }\n | { type: \"REDO\" }\n | { type: \"UNDO\" };\n\ntype DashfooInput = { model: Dashfoo };\n\nconst dashfooMachine = setup({\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DashfooContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DashfooEvent,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n input: {} as DashfooInput,\n },\n}).createMachine({\n context: ({ input }) => ({ history: createHistory(input.model) }),\n id: \"dashfoo\",\n initial: \"ready\",\n states: {\n ready: {\n on: {\n DISPATCH: {\n actions: assign({\n history: ({ context, event }) => dispatch(context.history, event.action),\n }),\n },\n REDO: {\n actions: assign({ history: ({ context }) => redo(context.history) }),\n },\n SET_MODEL: {\n actions: assign({ history: ({ event }) => createHistory(event.model) }),\n },\n UNDO: {\n actions: assign({ history: ({ context }) => undo(context.history) }),\n },\n },\n },\n },\n});\n\nexport { dashfooMachine };\nexport type { DashfooContext, DashfooEvent, DashfooInput };\n","import { assign, emit, setup } from \"xstate\";\n\nimport type { TabNode } from \"../model/schema\";\nimport type { Action, DropIntent } from \"../state/actions\";\n\ntype DragSubject =\n | { id: string; kind: \"tab\" | \"tabset\" }\n | { id: string; kind: \"external\"; tab: TabNode };\n\ntype DragContext = { intent: DropIntent | null; subject: DragSubject | null };\n\ntype DragEvent =\n | { intent: DropIntent | null; type: \"OVER\" }\n | { subject: DragSubject; type: \"START\" }\n | { type: \"CANCEL\" }\n | { type: \"DROP\" };\n\ntype DragEmitted = { action: Action; type: \"COMMIT\" };\n\nconst requireDrop = (context: DragContext): { intent: DropIntent; subject: DragSubject } => {\n if (context.subject === null || context.intent === null) {\n throw new Error(\"drop requires a subject and a drop intent\");\n }\n return { intent: context.intent, subject: context.subject };\n};\n\nconst dragDockMachine = setup({\n guards: {\n hasValidDrop: ({ context }) => context.subject !== null && context.intent !== null,\n },\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DragContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n emitted: {} as DragEmitted,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DragEvent,\n },\n}).createMachine({\n context: { intent: null, subject: null },\n id: \"dragDock\",\n initial: \"idle\",\n states: {\n dragging: {\n on: {\n CANCEL: { target: \"idle\" },\n DROP: [\n {\n actions: emit(({ context }) => {\n const { intent, subject } = requireDrop(context);\n const action: Action =\n subject.kind === \"external\"\n ? {\n index: intent.index,\n location: intent.location,\n tab: subject.tab,\n targetId: intent.targetId,\n type: \"addNode\",\n }\n : {\n index: intent.index,\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: subject.kind === \"tabset\" ? \"moveTabset\" : \"moveNode\",\n };\n return { action, type: \"COMMIT\" };\n }),\n guard: \"hasValidDrop\",\n target: \"idle\",\n },\n { target: \"idle\" },\n ],\n OVER: { actions: assign({ intent: ({ event }) => event.intent }) },\n },\n },\n idle: {\n entry: assign({ intent: null, subject: null }),\n on: {\n START: { actions: assign({ subject: ({ event }) => event.subject }), target: \"dragging\" },\n },\n },\n },\n});\n\nexport { dragDockMachine };\nexport type { DragContext, DragEmitted, DragEvent, DragSubject };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo } from \"./schema\";\nimport { dashfooSchema } from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst parseModel = (value: unknown): Dashfoo => {\n const model = normalize(dashfooSchema.parse(value));\n const duplicates = findDuplicateIds(model);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(`[dashfoo] duplicate node ids in the loaded layout: ${duplicates.join(\", \")}`);\n }\n return model;\n};\n\nconst toJSON = (model: Dashfoo): string => JSON.stringify(model);\n\nconst fromJSON = (json: string): Dashfoo => parseModel(JSON.parse(json));\n\nexport { fromJSON, parseModel, toJSON };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo, Orientation, TabsetNode } from \"./schema\";\nimport { collectTabsetsInRow } from \"./tree\";\n\nconst stackModel = (model: Dashfoo, orientation: Orientation = \"column\"): Dashfoo => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(model.layout, mainTabsets);\n const children: Array<TabsetNode> = [];\n for (const tabset of mainTabsets) {\n children.push({ ...tabset, weight: 1 });\n }\n\n return normalize({\n ...model,\n layout: { children, id: model.layout.id, orientation, type: \"row\" },\n maximizedTabsetId: undefined,\n });\n};\n\nexport { stackModel };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/clamp-selected.ts","../src/model/schema.ts","../src/state/node-attrs.ts","../src/state/actions.ts","../src/model/ids.ts","../src/model/tree.ts","../src/model/builders.ts","../src/lib/assert-never.ts","../src/geometry/geometry.ts","../src/geometry/snap.ts","../src/model/invariants.ts","../src/state/surgery.ts","../src/state/floats.ts","../src/state/reducer.ts","../src/state/history.ts","../src/machines/dashfoo-machine.ts","../src/machines/drag-dock-machine.ts","../src/model/serialize.ts","../src/model/stack.ts"],"sourcesContent":["/** In `lib/` because both the parse boundary and `normalize` need it, and\n * importing it from either would close a module cycle. */\nconst clampSelected = (length: number, selected: number): number => {\n if (length === 0) {\n return 0;\n }\n\n const base = Number.isFinite(selected) ? Math.trunc(selected) : 0;\n if (base < 0) {\n return 0;\n }\n if (base > length - 1) {\n return length - 1;\n }\n return base;\n};\n\nexport { clampSelected };\n","import { z } from \"zod\";\n\nimport { clampSelected } from \"../lib/clamp-selected\";\n\n/** Weights are relative shares of a row, not percentages. */\nconst DEFAULT_WEIGHT = 1;\n\ntype JsonValue = string | number | boolean | null | Array<JsonValue> | { [key: string]: JsonValue };\n\nconst jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(z.string(), jsonValueSchema),\n ]),\n);\n\nconst edgeSchema = z.enum([\"top\", \"bottom\", \"left\", \"right\"]);\nconst unitSchema = z.enum([\"px\", \"%\", \"em\", \"rem\", \"vh\", \"vw\"]);\nconst orientationSchema = z.enum([\"row\", \"column\"]);\n\nconst dimensionSchema = z.object({\n unit: unitSchema,\n value: z.number(),\n});\n\nconst snapSchema = z.object({\n divisions: z.union([z.number().positive(), z.literal(\"panels\")]).optional(),\n step: z.number().min(0).optional(),\n threshold: z.number().positive().optional(),\n});\n\nconst tabNodeSchema = z.object({\n component: z.string(),\n config: jsonValueSchema.optional(),\n enableClose: z.boolean().optional(),\n enableDrag: z.boolean().optional(),\n enableRename: z.boolean().optional(),\n id: z.string(),\n name: z.string(),\n type: z.literal(\"tab\"),\n});\n\n/**\n * Kept pre-transform so `node-attrs` can `.pick()` from it: a pipe has no\n * `.pick`, and `.partial()` over a defaulted field still fills the default in.\n */\nconst tabsetNodeObjectSchema = z.object({\n children: z.array(tabNodeSchema),\n enableClose: z.boolean().optional(),\n enableMaximize: z.boolean().optional(),\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n name: z.string().optional(),\n selected: z.number().int(),\n type: z.literal(\"tabset\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\nconst tabsetNodeSchema = tabsetNodeObjectSchema.transform((tabset) => ({\n ...tabset,\n selected: clampSelected(tabset.children.length, tabset.selected),\n}));\n\n/** The getter's explicit return type is required: without it, TS7023. */\nconst rowNodeSchema = z.object({\n get children(): z.ZodArray<z.ZodUnion<[typeof rowNodeSchema, typeof tabsetNodeSchema]>> {\n return z.array(z.union([rowNodeSchema, tabsetNodeSchema]));\n },\n id: z.string(),\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n type: z.literal(\"row\"),\n weight: z.number().default(DEFAULT_WEIGHT),\n});\n\ntype RowNode = z.infer<typeof rowNodeSchema>;\ntype RowNodeInput = z.input<typeof rowNodeSchema>;\n\nconst geometrySchema = z.object({\n height: z.number(),\n left: z.number(),\n top: z.number(),\n width: z.number(),\n});\n\nconst floatNodeSchema = z.object({\n geometry: geometrySchema,\n id: z.string(),\n layout: rowNodeSchema,\n\n minimized: z.boolean().optional(),\n name: z.string().optional(),\n type: z.literal(\"float\"),\n});\n\nconst globalAttributesSchema = z.object({\n enableSplitDock: z.boolean().optional(),\n enableSplitResize: z.boolean().optional(),\n snap: snapSchema.optional(),\n splitterSize: z.number().optional(),\n tabEnableClose: z.boolean().optional(),\n tabEnableDrag: z.boolean().optional(),\n tabEnableRename: z.boolean().optional(),\n tabLocation: z.enum([\"top\", \"bottom\"]).optional(),\n tabSetEnableMaximize: z.boolean().optional(),\n tabSetEnableTabStrip: z.boolean().optional(),\n tabSetMinSize: z.number().optional(),\n});\n\nconst dashfooSchema = z.object({\n activeTabsetId: z.string().optional(),\n floats: z.array(floatNodeSchema).default(() => []),\n global: globalAttributesSchema,\n layout: rowNodeSchema,\n maximizedTabsetId: z.string().optional(),\n version: z.literal(1),\n});\n\ntype Json = JsonValue;\ntype Edge = z.infer<typeof edgeSchema>;\ntype Unit = z.infer<typeof unitSchema>;\ntype Orientation = z.infer<typeof orientationSchema>;\ntype Dimension = z.infer<typeof dimensionSchema>;\ntype SnapConfig = z.infer<typeof snapSchema>;\ntype TabNode = z.infer<typeof tabNodeSchema>;\ntype TabsetNode = z.infer<typeof tabsetNodeSchema>;\ntype Geometry = z.infer<typeof geometrySchema>;\ntype FloatNode = z.infer<typeof floatNodeSchema>;\ntype GlobalAttributes = z.infer<typeof globalAttributesSchema>;\ntype Dashfoo = z.infer<typeof dashfooSchema>;\n/** The loose shape `dashfooSchema` accepts: `weight` and `floats` may be omitted. */\ntype DashfooInput = z.input<typeof dashfooSchema>;\ntype Node = RowNode | TabsetNode | TabNode;\n\nexport {\n dashfooSchema,\n DEFAULT_WEIGHT,\n dimensionSchema,\n edgeSchema,\n floatNodeSchema,\n geometrySchema,\n globalAttributesSchema,\n jsonValueSchema,\n orientationSchema,\n rowNodeSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n tabsetNodeSchema,\n unitSchema,\n};\n\nexport type {\n Dashfoo,\n DashfooInput,\n Dimension,\n Edge,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n Node,\n Orientation,\n RowNode,\n RowNodeInput,\n SnapConfig,\n TabNode,\n TabsetNode,\n Unit,\n};\n","import { z } from \"zod\";\n\nimport {\n dimensionSchema,\n orientationSchema,\n snapSchema,\n tabNodeSchema,\n tabsetNodeObjectSchema,\n} from \"../model/schema\";\n\nconst mutableTabAttrsSchema = tabNodeSchema\n .pick({\n config: true,\n enableClose: true,\n enableDrag: true,\n enableRename: true,\n name: true,\n })\n .partial();\n\n/** `weight` is re-declared, not picked: `.partial()` over a defaulted field still injects the default. */\nconst mutableTabsetAttrsSchema = tabsetNodeObjectSchema\n .pick({\n enableClose: true,\n enableMaximize: true,\n max: true,\n min: true,\n selected: true,\n })\n .extend({ weight: z.number() })\n .partial();\n\nconst mutableRowAttrsSchema = z\n .object({\n max: dimensionSchema.optional(),\n min: dimensionSchema.optional(),\n orientation: orientationSchema,\n snap: snapSchema.optional(),\n weight: z.number(),\n })\n .partial();\n\n/**\n * Merged, not a union: a union of all-optional members matches its first member\n * and strips the rest. The reducer enforces which keys a given node accepts.\n */\nconst mutableNodeAttrsSchema = mutableTabAttrsSchema\n .extend(mutableTabsetAttrsSchema.shape)\n .extend(mutableRowAttrsSchema.shape);\n\nexport {\n mutableNodeAttrsSchema,\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n};\n","import { z } from \"zod\";\n\nimport { geometrySchema, globalAttributesSchema, tabNodeSchema } from \"../model/schema\";\n\nimport { mutableNodeAttrsSchema } from \"./node-attrs\";\n\nconst dockLocationSchema = z.enum([\n \"center\",\n \"split-bottom\",\n \"split-left\",\n \"split-right\",\n \"split-top\",\n]);\n\nconst splitWeightsSchema = z.array(z.number());\n\nconst actionSchema = z.discriminatedUnion(\"type\", [\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n tab: tabNodeSchema,\n targetId: z.string(),\n type: z.literal(\"addNode\"),\n }),\n z.object({\n index: z.number().int().optional(),\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveNode\"),\n }),\n // No `index`: a tabset docks beside or merges into its target, so there is no\n // slot in a tab strip to land at.\n z.object({\n location: dockLocationSchema,\n sourceId: z.string(),\n targetId: z.string(),\n type: z.literal(\"moveTabset\"),\n }),\n z.object({ index: z.number().int(), tabsetId: z.string(), type: z.literal(\"selectTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"setActiveTabset\") }),\n z.object({ tabsetId: z.string().nullable(), type: z.literal(\"setMaximizedTabset\") }),\n z.object({ name: z.string(), tabId: z.string(), type: z.literal(\"renameTab\") }),\n z.object({ tabId: z.string(), type: z.literal(\"deleteTab\") }),\n z.object({ tabsetId: z.string(), type: z.literal(\"deleteTabset\") }),\n z.object({\n rowId: z.string(),\n type: z.literal(\"adjustSplit\"),\n weights: splitWeightsSchema,\n }),\n z.object({\n attrs: mutableNodeAttrsSchema,\n nodeId: z.string(),\n type: z.literal(\"updateNodeAttributes\"),\n }),\n z.object({ attrs: globalAttributesSchema.partial(), type: z.literal(\"updateGlobalAttributes\") }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabId: z.string(),\n type: z.literal(\"floatTab\"),\n }),\n\n z.object({\n floatId: z.string().optional(),\n geometry: geometrySchema.optional(),\n tabsetId: z.string(),\n type: z.literal(\"floatTabset\"),\n }),\n\n z.object({\n floatId: z.string(),\n location: dockLocationSchema.optional(),\n targetId: z.string().optional(),\n type: z.literal(\"dockFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n geometry: geometrySchema,\n type: z.literal(\"moveFloat\"),\n }),\n\n z.object({\n floatId: z.string(),\n minimized: z.boolean(),\n type: z.literal(\"setFloatMinimized\"),\n }),\n\n z.object({\n floatId: z.string(),\n name: z.string(),\n type: z.literal(\"renameFloat\"),\n }),\n]);\n\ntype DockLocation = z.infer<typeof dockLocationSchema>;\ntype MutableNodeAttrs = z.infer<typeof mutableNodeAttrsSchema>;\ntype Action = z.infer<typeof actionSchema>;\n\ntype DropIntent = { index?: number; location: DockLocation; targetId: string };\n\nexport { actionSchema, dockLocationSchema };\nexport type { Action, DockLocation, DropIntent, MutableNodeAttrs };\n","const createNodeId = (prefix = \"node\"): string => `${prefix}-${crypto.randomUUID()}`;\n\nconst createTabId = (): string => createNodeId(\"tab\");\n\nexport { createNodeId, createTabId };\n","import type { Dashfoo, FloatNode, RowNode, TabNode, TabsetNode } from \"./schema\";\n\ntype TabContainer = TabsetNode;\ntype TabLocation = { container: TabContainer; index: number; tab: TabNode };\n\nconst collectRoots = (model: Dashfoo): Array<RowNode> => [\n model.layout,\n ...model.floats.map((float) => float.layout),\n];\n\nconst findFloat = (model: Dashfoo, floatId: string): FloatNode | undefined =>\n model.floats.find((float) => float.id === floatId);\n\ntype AttributedNode = RowNode | TabNode | TabsetNode;\n\ntype Visit = {\n index: number;\n node: AttributedNode;\n parent: RowNode | TabsetNode | undefined;\n};\n\n/**\n * Depth-first pre-order; a defined `visit` result stops the walk. With unique\n * ids the order is immaterial, but a duplicate-id model (which the builder and\n * the parser both warn about) resolves to whichever copy this reaches first.\n */\nconst walk = <T>(\n row: RowNode,\n visit: (found: Visit) => T | undefined,\n parent?: RowNode,\n index = -1,\n): T | undefined => {\n const atRoot = visit({ index, node: row, parent });\n if (atRoot !== undefined) {\n return atRoot;\n }\n for (const [childIndex, child] of row.children.entries()) {\n if (child.type === \"row\") {\n const inRow = walk(child, visit, row, childIndex);\n if (inRow !== undefined) {\n return inRow;\n }\n continue;\n }\n const atTabset = visit({ index: childIndex, node: child, parent: row });\n if (atTabset !== undefined) {\n return atTabset;\n }\n for (const [tabIndex, tab] of child.children.entries()) {\n const atTab = visit({ index: tabIndex, node: tab, parent: child });\n if (atTab !== undefined) {\n return atTab;\n }\n }\n }\n return undefined;\n};\n\ntype Located<N extends AttributedNode> = {\n index: number;\n node: N;\n parent: RowNode | TabsetNode | undefined;\n};\n\nconst isRow = (node: AttributedNode): node is RowNode => node.type === \"row\";\nconst isTab = (node: AttributedNode): node is TabNode => node.type === \"tab\";\nconst isTabset = (node: AttributedNode): node is TabsetNode => node.type === \"tabset\";\n\n/** Predicate-first, so an id shared across node kinds resolves the same way here as anywhere else. */\nconst locate = <N extends AttributedNode>(\n model: Dashfoo,\n id: string,\n is: (node: AttributedNode) => node is N,\n): Located<N> | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ index, node, parent }) =>\n node.id === id && is(node) ? { index, node, parent } : undefined,\n );\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst collectTabsetsInRow = (row: RowNode, acc: Array<TabsetNode>): void => {\n walk(row, ({ node }) => {\n if (node.type === \"tabset\") {\n acc.push(node);\n }\n return undefined;\n });\n};\n\nconst collectTabsets = (model: Dashfoo): Array<TabsetNode> => {\n const acc: Array<TabsetNode> = [];\n for (const root of collectRoots(model)) {\n collectTabsetsInRow(root, acc);\n }\n return acc;\n};\n\nconst getFirstTabset = (model: Dashfoo): TabsetNode | undefined => collectTabsets(model)[0];\n\nconst findTabset = (model: Dashfoo, tabsetId: string): TabsetNode | undefined =>\n locate(model, tabsetId, isTabset)?.node;\n\nconst findTab = (model: Dashfoo, tabId: string): TabLocation | undefined => {\n const found = locate(model, tabId, isTab);\n return found?.parent?.type === \"tabset\"\n ? { container: found.parent, index: found.index, tab: found.node }\n : undefined;\n};\n\nconst findRow = (model: Dashfoo, id: string): RowNode | undefined => locate(model, id, isRow)?.node;\n\nconst findAttributedNode = (model: Dashfoo, id: string): AttributedNode | undefined => {\n for (const root of collectRoots(model)) {\n const found = walk(root, ({ node }) => (node.id === id ? node : undefined));\n if (found) {\n return found;\n }\n }\n return undefined;\n};\n\nconst findRootContaining = (model: Dashfoo, nodeId: string): RowNode | undefined => {\n for (const root of collectRoots(model)) {\n const hit = walk(root, ({ node }) => (node.id === nodeId ? true : undefined));\n if (hit) {\n return root;\n }\n }\n return undefined;\n};\n\nconst findTabsetParent = (\n model: Dashfoo,\n tabsetId: string,\n): { index: number; parent: RowNode } | undefined => {\n const found = locate(model, tabsetId, isTabset);\n return found?.parent?.type === \"row\" ? { index: found.index, parent: found.parent } : undefined;\n};\n\nconst collectIdsInRow = (row: RowNode, acc: Array<string>): void => {\n walk(row, ({ node }) => {\n acc.push(node.id);\n return undefined;\n });\n};\n\nconst findDuplicateIds = (model: Dashfoo): Array<string> => {\n const ids: Array<string> = [];\n for (const float of model.floats) {\n ids.push(float.id);\n }\n for (const root of collectRoots(model)) {\n collectIdsInRow(root, ids);\n }\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const id of ids) {\n if (seen.has(id)) {\n duplicates.add(id);\n }\n seen.add(id);\n }\n return [...duplicates];\n};\n\nexport {\n collectRoots,\n collectTabsets,\n collectTabsetsInRow,\n findAttributedNode,\n findDuplicateIds,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n findTabsetParent,\n getFirstTabset,\n};\nexport type { AttributedNode, TabContainer, TabLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\n\nimport { createNodeId } from \"./ids\";\nimport { DEFAULT_WEIGHT } from \"./schema\";\nimport type {\n Dashfoo,\n Dimension,\n FloatNode,\n Geometry,\n GlobalAttributes,\n Json,\n RowNode,\n SnapConfig,\n TabNode,\n TabsetNode,\n} from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst toDimension = (value: number | Dimension): Dimension =>\n typeof value === \"number\" ? { unit: \"px\", value } : value;\n\ntype TabOptions = {\n config?: Json;\n enableClose?: boolean;\n enableDrag?: boolean;\n enableRename?: boolean;\n id?: string;\n};\n\nconst tab = (component: string, name: string, options: TabOptions = {}): TabNode => ({\n component,\n name,\n type: \"tab\",\n ...options,\n id: options.id ?? component,\n});\n\ntype TabsetOptions = {\n enableClose?: boolean;\n enableMaximize?: boolean;\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n name?: string;\n selected?: number;\n weight?: number;\n};\n\nconst tabset = (children: Array<TabNode>, options: TabsetOptions = {}): TabsetNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"tabset\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"tabset\"),\n selected: clampSelected(children.length, options.selected ?? 0),\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n};\n\ntype RowOptions = {\n id?: string;\n max?: number | Dimension;\n min?: number | Dimension;\n orientation?: RowNode[\"orientation\"];\n snap?: SnapConfig;\n weight?: number;\n};\n\nconst row = (children: RowNode[\"children\"], options: RowOptions = {}): RowNode => {\n const { max, min, ...rest } = options;\n return {\n children,\n type: \"row\",\n ...rest,\n ...(max === undefined ? {} : { max: toDimension(max) }),\n ...(min === undefined ? {} : { min: toDimension(min) }),\n id: options.id ?? createNodeId(\"row\"),\n orientation: options.orientation ?? \"row\",\n weight: options.weight ?? DEFAULT_WEIGHT,\n };\n};\n\ntype FloatOptions = {\n id?: string;\n name?: string;\n};\n\nconst floatNode = (layout: RowNode, geometry: Geometry, options: FloatOptions = {}): FloatNode => ({\n geometry,\n layout,\n type: \"float\",\n ...options,\n id: options.id ?? createNodeId(\"float\"),\n});\n\ntype ModelOptions = {\n activeTabsetId?: string;\n floats?: Array<FloatNode>;\n global?: GlobalAttributes;\n maximizedTabsetId?: string;\n};\n\nconst model = (layout: RowNode, options: ModelOptions = {}): Dashfoo => {\n const built: Dashfoo = {\n layout,\n version: 1,\n ...options,\n floats: options.floats ?? [],\n global: options.global ?? {},\n };\n const duplicates = findDuplicateIds(built);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(\n `[dashfoo] builder produced duplicate node ids: ${duplicates.join(\", \")}. Pass explicit ids when reusing a component`,\n );\n }\n return built;\n};\n\nexport { floatNode, model, row, tab, tabset };\nexport type { FloatOptions, ModelOptions, RowOptions, TabOptions, TabsetOptions };\n","const assertNever = (value: never): never => {\n throw new Error(`Unhandled variant: ${JSON.stringify(value)}`);\n};\n\nexport { assertNever };\n","import { assertNever } from \"../lib/assert-never\";\nimport type { Edge } from \"../model/schema\";\nimport type { DockLocation } from \"../state/actions\";\n\ntype Point = { x: number; y: number };\ntype Rect = { height: number; width: number; x: number; y: number };\ntype BandOptions = { bandFraction?: number };\ntype DockZone = { location: DockLocation; points: Array<Point> };\n\nconst DEFAULT_BAND_FRACTION = 0.22;\n\nconst edgeDistances = (\n pointer: Point,\n rect: Rect,\n): { bottom: number; left: number; right: number; top: number } => {\n const fx = (pointer.x - rect.x) / rect.width;\n const fy = (pointer.y - rect.y) / rect.height;\n return { bottom: 1 - fy, left: fx, right: 1 - fx, top: fy };\n};\n\nconst closestEdge = (d: { bottom: number; left: number; right: number; top: number }): Edge => {\n const min = Math.min(d.left, d.right, d.top, d.bottom);\n if (min === d.left) {\n return \"left\";\n }\n if (min === d.right) {\n return \"right\";\n }\n if (min === d.top) {\n return \"top\";\n }\n return \"bottom\";\n};\n\nconst splitEdge = (location: DockLocation): Edge | undefined => {\n switch (location) {\n case \"center\": {\n return undefined;\n }\n case \"split-bottom\": {\n return \"bottom\";\n }\n case \"split-left\": {\n return \"left\";\n }\n case \"split-right\": {\n return \"right\";\n }\n case \"split-top\": {\n return \"top\";\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nconst resolveDockTarget = (pointer: Point, rect: Rect, opts?: BandOptions): DockLocation => {\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n\n if (rect.width <= 0 || rect.height <= 0) {\n return \"center\";\n }\n const distances = edgeDistances(pointer, rect);\n const min = Math.min(distances.left, distances.right, distances.top, distances.bottom);\n\n if (min > band) {\n return \"center\";\n }\n return `split-${closestEdge(distances)}`;\n};\n\nconst dockZonePolygons = (rect: Rect, opts?: BandOptions): Array<DockZone> => {\n const { height: h, width: w, x, y } = rect;\n const nw: Point = { x, y };\n const ne: Point = { x: x + w, y };\n const se: Point = { x: x + w, y: y + h };\n const sw: Point = { x, y: y + h };\n if (w <= 0 || h <= 0) {\n return [{ location: \"center\", points: [nw, ne, se, sw] }];\n }\n const band = opts?.bandFraction ?? DEFAULT_BAND_FRACTION;\n const bx = band * w;\n const by = band * h;\n const innerNw: Point = { x: x + bx, y: y + by };\n const innerNe: Point = { x: x + w - bx, y: y + by };\n const innerSe: Point = { x: x + w - bx, y: y + h - by };\n const innerSw: Point = { x: x + bx, y: y + h - by };\n return [\n { location: \"center\", points: [innerNw, innerNe, innerSe, innerSw] },\n { location: \"split-left\", points: [nw, innerNw, innerSw, sw] },\n { location: \"split-right\", points: [ne, se, innerSe, innerNe] },\n { location: \"split-top\", points: [nw, ne, innerNe, innerNw] },\n { location: \"split-bottom\", points: [sw, innerSw, innerSe, se] },\n ];\n};\n\nconst zoneRect = (rect: Rect, location: DockLocation): Rect => {\n const halfW = rect.width / 2;\n const halfH = rect.height / 2;\n switch (location) {\n case \"split-bottom\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y + halfH };\n }\n case \"split-left\": {\n return { height: rect.height, width: halfW, x: rect.x, y: rect.y };\n }\n case \"split-right\": {\n return { height: rect.height, width: halfW, x: rect.x + halfW, y: rect.y };\n }\n case \"split-top\": {\n return { height: halfH, width: rect.width, x: rect.x, y: rect.y };\n }\n case \"center\": {\n return rect;\n }\n default: {\n return assertNever(location);\n }\n }\n};\n\nexport { dockZonePolygons, resolveDockTarget, splitEdge, zoneRect };\nexport type { BandOptions, DockZone, Point, Rect };\n","import type { SnapConfig } from \"../model/schema\";\n\nconst DEFAULT_SNAP_THRESHOLD = 4;\n\nconst TARGET_PRECISION = 1e6;\n\nconst addMultiples = (targets: Set<number>, increment: number): void => {\n if (increment <= 0) {\n return;\n }\n for (let position = increment; position < 100; position += increment) {\n const rounded = Math.round(position * TARGET_PRECISION) / TARGET_PRECISION;\n if (rounded < 100) {\n targets.add(rounded);\n }\n }\n};\n\nconst resolveSnapTargets = (config: SnapConfig, panelCount: number): Array<number> => {\n const targets = new Set<number>();\n if (config.step !== undefined && config.step > 0) {\n addMultiples(targets, config.step);\n }\n if (config.divisions !== undefined) {\n const divisions = config.divisions === \"panels\" ? panelCount : config.divisions;\n if (divisions >= 2) {\n addMultiples(targets, 100 / divisions);\n }\n }\n return [...targets].toSorted((a, b) => a - b);\n};\n\ntype SnapGrid = { targets: Array<number>; threshold: number };\n\nconst resolveSnapGrid = (config: SnapConfig | null, panelCount: number): SnapGrid => ({\n targets: config === null ? [] : resolveSnapTargets(config, panelCount),\n threshold: config?.threshold ?? DEFAULT_SNAP_THRESHOLD,\n});\n\nconst snapEnabled = (grid: SnapGrid): boolean => grid.targets.length > 0;\n\nconst nearestTarget = (position: number, targets: Array<number>): number | undefined =>\n targets.reduce<number | undefined>((best, target) => {\n if (best === undefined || Math.abs(target - position) < Math.abs(best - position)) {\n return target;\n }\n return best;\n }, undefined);\n\ntype SnapResult = { sizes: Array<number>; snapped: boolean };\n\nconst snapSizes = (sizes: Array<number>, boundaryIndex: number, grid: SnapGrid): SnapResult => {\n const { targets, threshold } = grid;\n const left = sizes[boundaryIndex];\n const right = sizes[boundaryIndex + 1];\n if (boundaryIndex < 0 || left === undefined || right === undefined || targets.length === 0) {\n return { sizes, snapped: false };\n }\n\n let position = 0;\n for (let index = 0; index <= boundaryIndex; index++) {\n position += sizes[index] ?? 0;\n }\n\n const target = nearestTarget(position, targets);\n if (target === undefined || Math.abs(target - position) > threshold) {\n return { sizes, snapped: false };\n }\n\n const delta = target - position;\n if (left + delta < 0 || right - delta < 0) {\n return { sizes, snapped: false };\n }\n\n const next = [...sizes];\n next[boundaryIndex] = left + delta;\n next[boundaryIndex + 1] = right - delta;\n return { sizes: next, snapped: true };\n};\n\ntype SnapDecision =\n | { kind: \"inactive\" }\n | { kind: \"clear\" }\n | { kind: \"engage\"; sizes: Array<number> };\n\nconst decideSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): SnapDecision => {\n if (boundaryIndex === null || !snapEnabled(grid)) {\n return { kind: \"inactive\" };\n }\n const { sizes: snappedSizes, snapped } = snapSizes(sizes, boundaryIndex, grid);\n return snapped ? { kind: \"engage\", sizes: snappedSizes } : { kind: \"clear\" };\n};\n\nconst settleSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n grid: SnapGrid,\n): Array<number> => {\n const decision = decideSnap(sizes, boundaryIndex, grid);\n return decision.kind === \"engage\" ? decision.sizes : sizes;\n};\n\nexport {\n DEFAULT_SNAP_THRESHOLD,\n decideSnap,\n resolveSnapGrid,\n resolveSnapTargets,\n settleSnap,\n snapEnabled,\n snapSizes,\n};\nexport type { SnapDecision, SnapGrid, SnapResult };\n","import type { Dashfoo, FloatNode, RowNode } from \"./schema\";\n\ntype RowChild = RowNode[\"children\"][number];\n\n/**\n * The survivor takes over the collapsed row's slot, so it has to take the slot's\n * sizing too: dropping it widens a pinned sidebar, permanently, since this runs\n * on every persist. `snap` is row-only, so it travels only to a row survivor.\n */\nconst inheritSlot = (row: RowNode, survivor: RowChild): RowChild => {\n const sized: RowChild = {\n ...survivor,\n weight: row.weight,\n ...(row.min === undefined ? {} : { min: row.min }),\n ...(row.max === undefined ? {} : { max: row.max }),\n };\n\n if (sized.type === \"row\" && row.snap !== undefined) {\n return { ...sized, snap: row.snap };\n }\n return sized;\n};\n\n/** Records the id of every tabset it keeps, in document order. */\nconst normalizeRowChildren = (\n children: RowNode[\"children\"],\n keptTabsetIds: Array<string>,\n): RowNode[\"children\"] => {\n const out: RowNode[\"children\"] = [];\n\n for (const child of children) {\n if (child.type === \"tabset\") {\n if (child.children.length > 0) {\n out.push(child);\n keptTabsetIds.push(child.id);\n }\n continue;\n }\n\n // A recorded id implies a survivor, which keeps its ancestor rows alive, so\n // a dropped row never leaves ids behind.\n const grandchildren = normalizeRowChildren(child.children, keptTabsetIds);\n if (grandchildren.length === 0) {\n continue;\n }\n if (grandchildren.length === 1) {\n const only = grandchildren[0];\n if (only !== undefined) {\n out.push(inheritSlot(child, only));\n }\n continue;\n }\n out.push({ ...child, children: grandchildren });\n }\n\n return out;\n};\n\nconst normalizeLayout = (root: RowNode, keptTabsetIds: Array<string>): RowNode => {\n let children = normalizeRowChildren(root.children, keptTabsetIds);\n let orientation = root.orientation;\n\n let inner = children[0];\n while (children.length === 1 && inner?.type === \"row\") {\n children = inner.children;\n orientation = inner.orientation;\n inner = children[0];\n }\n\n return { ...root, children, orientation };\n};\n\nconst normalize = (model: Dashfoo): Dashfoo => {\n const mainTabsetIds: Array<string> = [];\n const layout = normalizeLayout(model.layout, mainTabsetIds);\n\n const floats: Array<FloatNode> = [];\n const floatTabsetIds: Array<string> = [];\n for (const float of model.floats) {\n const ownTabsetIds: Array<string> = [];\n const floatLayout = normalizeLayout(float.layout, ownTabsetIds);\n if (floatLayout.children.length > 0) {\n floats.push({ ...float, layout: floatLayout });\n floatTabsetIds.push(...ownTabsetIds);\n }\n }\n\n const mainIds = new Set(mainTabsetIds);\n const liveIds = new Set([...mainTabsetIds, ...floatTabsetIds]);\n const firstTabsetId = mainTabsetIds[0] ?? floatTabsetIds[0];\n\n const activeTabsetId =\n model.activeTabsetId !== undefined && liveIds.has(model.activeTabsetId)\n ? model.activeTabsetId\n : firstTabsetId;\n\n // Main layout only: floats opt out of maximize, so an id that moved into one\n // would render twice, in the main area and inside the float.\n const maximizedTabsetId =\n model.maximizedTabsetId !== undefined && mainIds.has(model.maximizedTabsetId)\n ? model.maximizedTabsetId\n : undefined;\n\n return { ...model, activeTabsetId, floats, layout, maximizedTabsetId };\n};\n\nexport { normalize };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, Orientation, RowNode, TabNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport type { TabContainer } from \"../model/tree\";\nimport { findTabset, findTabsetParent } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\n\n/** The four locations that produce a split. `center` merges instead, so it is not one of them. */\ntype SplitLocation = Exclude<DockLocation, \"center\">;\n\nconst removeTabsetReturning = (model: Dashfoo, tabsetId: string): TabsetNode | undefined => {\n const found = findTabsetParent(model, tabsetId);\n if (!found) {\n return undefined;\n }\n const [removed] = found.parent.children.splice(found.index, 1);\n return removed?.type === \"tabset\" ? removed : undefined;\n};\n\n/** Total, so a sixth `DockLocation` is a compile error here rather than a wrong default. */\nconst SPLIT_PLACEMENT = {\n \"split-bottom\": { before: false, orientation: \"column\" },\n \"split-left\": { before: true, orientation: \"row\" },\n \"split-right\": { before: false, orientation: \"row\" },\n \"split-top\": { before: true, orientation: \"column\" },\n} as const satisfies Record<SplitLocation, { before: boolean; orientation: Orientation }>;\n\nconst placeBesideTarget = (\n draft: Dashfoo,\n placed: TabsetNode,\n targetId: string,\n location: SplitLocation,\n): boolean => {\n const targetTabset = findTabset(draft, targetId);\n const found = findTabsetParent(draft, targetId);\n if (!targetTabset || !found) {\n return false;\n }\n\n const { before, orientation } = SPLIT_PLACEMENT[location];\n\n if (found.parent.orientation === orientation) {\n const half = targetTabset.weight / 2;\n targetTabset.weight = half;\n placed.weight = half;\n found.parent.children.splice(before ? found.index : found.index + 1, 0, placed);\n } else {\n const newRow: RowNode = {\n children: before ? [placed, targetTabset] : [targetTabset, placed],\n id: createNodeId(\"row\"),\n orientation,\n type: \"row\",\n weight: targetTabset.weight,\n };\n targetTabset.weight = 50;\n placed.weight = 50;\n found.parent.children.splice(found.index, 1, newRow);\n }\n\n draft.activeTabsetId = placed.id;\n return true;\n};\n\ntype DropTarget = { id: string; index?: number; location: DockLocation };\n\nconst insertTab = (draft: Dashfoo, tab: TabNode, target: DropTarget): boolean => {\n const { id: targetId, index, location } = target;\n const targetTabset = findTabset(draft, targetId);\n if (!targetTabset) {\n return false;\n }\n\n if (location === \"center\") {\n const at = Math.min(\n Math.max(index ?? targetTabset.children.length, 0),\n targetTabset.children.length,\n );\n targetTabset.children.splice(at, 0, tab);\n targetTabset.selected = at;\n return true;\n }\n\n const newTabset: TabsetNode = {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, newTabset, targetId, location);\n};\n\n/** Re-clamps here rather than leaving the whole tree to be re-walked afterwards. */\nconst detachTab = (container: TabContainer, index: number): TabNode | undefined => {\n const removed = container.children.splice(index, 1).at(0);\n container.selected = clampSelected(container.children.length, container.selected);\n return removed;\n};\n\nconst mergeTabsInto = (target: TabsetNode, tabs: Array<TabNode>, selectedOffset: number): void => {\n const mergeStart = target.children.length;\n target.children.push(...tabs);\n target.selected = mergeStart + selectedOffset;\n};\n\nconst wrapTabInLayout = (tab: TabNode): RowNode => ({\n children: [\n {\n children: [tab],\n id: createNodeId(\"tabset\"),\n selected: 0,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n },\n ],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nconst wrapTabsetInLayout = (tabset: TabsetNode): RowNode => ({\n children: [tabset],\n id: createNodeId(\"row\"),\n orientation: \"row\",\n type: \"row\",\n weight: DEFAULT_WEIGHT,\n});\n\nexport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n wrapTabsetInLayout,\n};\nexport type { DropTarget, SplitLocation };\n","import { clampSelected } from \"../lib/clamp-selected\";\nimport { createNodeId } from \"../model/ids\";\nimport type { Dashfoo, FloatNode, Geometry, RowNode, TabsetNode } from \"../model/schema\";\nimport { DEFAULT_WEIGHT } from \"../model/schema\";\nimport { collectTabsetsInRow } from \"../model/tree\";\n\nimport type { DockLocation } from \"./actions\";\nimport {\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabsetInLayout,\n} from \"./surgery\";\n\nconst DEFAULT_FLOAT_GEOMETRY: Geometry = { height: 360, left: 80, top: 80, width: 480 };\n\nconst uniqueFloatName = (base: string, floats: Array<FloatNode>): string => {\n const used = new Set(floats.map((float) => float.name));\n if (!used.has(base)) {\n return base;\n }\n let index = 1;\n while (used.has(`${base} ${index}`)) {\n index += 1;\n }\n return `${base} ${index}`;\n};\n\nconst pushFloat = (\n draft: Dashfoo,\n layout: RowNode,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): void => {\n const float: FloatNode = {\n geometry: geometry ?? DEFAULT_FLOAT_GEOMETRY,\n id: floatId ?? createNodeId(\"float\"),\n layout,\n name: uniqueFloatName(\"Panel\", draft.floats),\n type: \"float\",\n };\n draft.floats = [...draft.floats, float];\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(layout, tabsets);\n const first = tabsets.at(0);\n if (first) {\n draft.activeTabsetId = first.id;\n }\n};\n\nconst floatTabsetById = (\n draft: Dashfoo,\n tabsetId: string,\n geometry: Geometry | undefined,\n floatId: string | undefined,\n): boolean => {\n const detached = removeTabsetReturning(draft, tabsetId);\n if (!detached) {\n return false;\n }\n pushFloat(draft, wrapTabsetInLayout(detached), geometry, floatId);\n return true;\n};\n\nconst resolveMainTarget = (\n draft: Dashfoo,\n targetId: string | undefined,\n): TabsetNode | undefined => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(draft.layout, mainTabsets);\n if (targetId !== undefined) {\n const explicit = mainTabsets.find((tabset) => tabset.id === targetId);\n if (explicit) {\n return explicit;\n }\n }\n if (draft.activeTabsetId !== undefined) {\n const active = mainTabsets.find((tabset) => tabset.id === draft.activeTabsetId);\n if (active) {\n return active;\n }\n }\n return mainTabsets[0];\n};\n\nconst dockFloat = (\n draft: Dashfoo,\n floatId: string,\n targetId: string | undefined,\n location: DockLocation | undefined,\n): boolean => {\n const index = draft.floats.findIndex((float) => float.id === floatId);\n const float = draft.floats.at(index);\n if (index === -1 || !float) {\n return false;\n }\n\n const tabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(float.layout, tabsets);\n const tabs = tabsets.flatMap((tabset) => tabset.children);\n if (tabs.length === 0) {\n return false;\n }\n\n const leadTabset = tabsets.at(0);\n const selectedOffset = leadTabset\n ? clampSelected(leadTabset.children.length, leadTabset.selected)\n : 0;\n\n // Resolved before the float leaves `draft.floats`: nothing is removed until\n // there is somewhere for its tabs to land.\n const target = resolveMainTarget(draft, targetId);\n draft.floats.splice(index, 1);\n\n if (!target) {\n draft.layout = float.layout;\n draft.activeTabsetId = leadTabset?.id;\n return true;\n }\n\n if (location === \"center\") {\n mergeTabsInto(target, tabs, selectedOffset);\n draft.activeTabsetId = target.id;\n return true;\n }\n\n const placed: TabsetNode =\n tabsets.length === 1 && leadTabset\n ? leadTabset\n : {\n children: tabs,\n id: createNodeId(\"tabset\"),\n selected: selectedOffset,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n return placeBesideTarget(draft, placed, target.id, location ?? \"split-right\");\n};\n\nexport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName };\n","import { assertNever } from \"../lib/assert-never\";\nimport { clampSelected } from \"../lib/clamp-selected\";\nimport { normalize } from \"../model/invariants\";\nimport type { Dashfoo, Geometry, GlobalAttributes } from \"../model/schema\";\nimport type { AttributedNode } from \"../model/tree\";\nimport { findAttributedNode, findFloat, findRow, findTab, findTabset } from \"../model/tree\";\n\nimport type { Action, MutableNodeAttrs } from \"./actions\";\nimport { dockFloat, floatTabsetById, pushFloat, uniqueFloatName } from \"./floats\";\nimport {\n mutableRowAttrsSchema,\n mutableTabAttrsSchema,\n mutableTabsetAttrsSchema,\n} from \"./node-attrs\";\nimport {\n detachTab,\n insertTab,\n mergeTabsInto,\n placeBesideTarget,\n removeTabsetReturning,\n wrapTabInLayout,\n} from \"./surgery\";\n\nconst parseNodeAttrs = (node: AttributedNode, attrs: MutableNodeAttrs): MutableNodeAttrs => {\n switch (node.type) {\n case \"row\": {\n return mutableRowAttrsSchema.parse(attrs);\n }\n case \"tab\": {\n return mutableTabAttrsSchema.parse(attrs);\n }\n case \"tabset\": {\n const parsed = mutableTabsetAttrsSchema.parse(attrs);\n return parsed.selected === undefined\n ? parsed\n : { ...parsed, selected: clampSelected(node.children.length, parsed.selected) };\n }\n default: {\n return assertNever(node);\n }\n }\n};\n\nconst sameGeometry = (a: Geometry, b: Geometry): boolean =>\n a.height === b.height && a.left === b.left && a.top === b.top && a.width === b.width;\n\nconst alreadyApplied = (\n target: AttributedNode | GlobalAttributes,\n attrs: MutableNodeAttrs | Partial<GlobalAttributes>,\n): boolean => {\n const current = new Map<string, unknown>(Object.entries(target));\n return Object.entries(attrs).every(([key, value]) => Object.is(current.get(key), value));\n};\n\n/** Reports whether it changed anything, so `history.dispatch` can skip a no-op. */\nconst applyAction = (draft: Dashfoo, action: Action): boolean => {\n switch (action.type) {\n case \"addNode\": {\n return insertTab(draft, action.tab, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"adjustSplit\": {\n const row = findRow(draft, action.rowId);\n if (!row) {\n return false;\n }\n let changed = false;\n for (let index = 0; index < action.weights.length; index++) {\n const child = row.children.at(index);\n const weight = action.weights[index];\n if (!child || weight === undefined || child.weight === weight) {\n continue;\n }\n child.weight = weight;\n changed = true;\n }\n return changed;\n }\n case \"deleteTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n detachTab(location.container, location.index);\n return true;\n }\n case \"deleteTabset\": {\n return removeTabsetReturning(draft, action.tabsetId) !== undefined;\n }\n case \"dockFloat\": {\n return dockFloat(draft, action.floatId, action.targetId, action.location);\n }\n case \"floatTab\": {\n const location = findTab(draft, action.tabId);\n if (!location) {\n return false;\n }\n const removed = detachTab(location.container, location.index);\n if (!removed) {\n return false;\n }\n pushFloat(draft, wrapTabInLayout(removed), action.geometry, action.floatId);\n return true;\n }\n case \"floatTabset\": {\n return floatTabsetById(draft, action.tabsetId, action.geometry, action.floatId);\n }\n case \"moveFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float || sameGeometry(float.geometry, action.geometry)) {\n return false;\n }\n float.geometry = action.geometry;\n return true;\n }\n case \"moveNode\": {\n const source = findTab(draft, action.sourceId);\n // Resolved before the tab leaves its container: nothing else holds it.\n if (!source || !findTabset(draft, action.targetId)) {\n return false;\n }\n\n const removed = detachTab(source.container, source.index);\n if (!removed) {\n return false;\n }\n return insertTab(draft, removed, {\n id: action.targetId,\n index: action.index,\n location: action.location,\n });\n }\n case \"moveTabset\": {\n if (action.sourceId === action.targetId) {\n return false;\n }\n const source = findTabset(draft, action.sourceId);\n const target = findTabset(draft, action.targetId);\n if (!source || !target) {\n return false;\n }\n if (action.location === \"center\") {\n mergeTabsInto(\n target,\n source.children,\n clampSelected(source.children.length, source.selected),\n );\n removeTabsetReturning(draft, action.sourceId);\n return true;\n }\n\n const detached = removeTabsetReturning(draft, action.sourceId);\n return detached\n ? placeBesideTarget(draft, detached, action.targetId, action.location)\n : false;\n }\n case \"renameFloat\": {\n const float = findFloat(draft, action.floatId);\n if (!float) {\n return false;\n }\n const others = draft.floats.filter((other) => other.id !== action.floatId);\n const name = uniqueFloatName(action.name, others);\n if (float.name === name) {\n return false;\n }\n float.name = name;\n return true;\n }\n case \"renameTab\": {\n const location = findTab(draft, action.tabId);\n if (!location || location.tab.name === action.name) {\n return false;\n }\n location.tab.name = action.name;\n return true;\n }\n case \"selectTab\": {\n const tabset = findTabset(draft, action.tabsetId);\n if (!tabset) {\n return false;\n }\n const selected = clampSelected(tabset.children.length, action.index);\n if (tabset.selected === selected) {\n return false;\n }\n tabset.selected = selected;\n return true;\n }\n case \"setActiveTabset\": {\n if (draft.activeTabsetId === action.tabsetId || !findTabset(draft, action.tabsetId)) {\n return false;\n }\n draft.activeTabsetId = action.tabsetId;\n return true;\n }\n case \"setFloatMinimized\": {\n const float = findFloat(draft, action.floatId);\n if (!float || (float.minimized ?? false) === action.minimized) {\n return false;\n }\n float.minimized = action.minimized;\n return true;\n }\n case \"setMaximizedTabset\": {\n const next = action.tabsetId ?? undefined;\n if (draft.maximizedTabsetId === next) {\n return false;\n }\n draft.maximizedTabsetId = next;\n return true;\n }\n case \"updateGlobalAttributes\": {\n if (alreadyApplied(draft.global, action.attrs)) {\n return false;\n }\n Object.assign(draft.global, action.attrs);\n return true;\n }\n case \"updateNodeAttributes\": {\n const node = findAttributedNode(draft, action.nodeId);\n if (!node) {\n return false;\n }\n const parsed = parseNodeAttrs(node, action.attrs);\n if (alreadyApplied(node, parsed)) {\n return false;\n }\n Object.assign(node, parsed);\n return true;\n }\n default: {\n return assertNever(action);\n }\n }\n};\n\n/** Identity-equal output means \"no edit\". A rejected action skips `normalize`, so\n * pass a model that has already been through it. */\nconst reducer = (model: Dashfoo, action: Action): Dashfoo => {\n const draft = structuredClone(model);\n if (!applyAction(draft, action)) {\n return model;\n }\n return normalize(draft);\n};\n\nexport { reducer };\n","import type { Dashfoo } from \"../model/schema\";\n\nimport type { Action } from \"./actions\";\nimport { reducer } from \"./reducer\";\n\ntype History = {\n future: Array<Dashfoo>;\n past: Array<Dashfoo>;\n present: Dashfoo;\n};\n\nconst HISTORY_LIMIT = 100;\n\nconst createHistory = (present: Dashfoo): History => ({\n future: [],\n past: [],\n present,\n});\n\nconst canUndo = (history: History): boolean => history.past.length > 0;\nconst canRedo = (history: History): boolean => history.future.length > 0;\n\n/**\n * An action that changed nothing is not an edit: recording it would spend an\n * undo slot and clear a redo stack the user just built. Not coalescing (ADR\n * 0002): two distinct edits are still two entries.\n */\nconst dispatch = (history: History, action: Action): History => {\n const present = reducer(history.present, action);\n if (Object.is(present, history.present)) {\n return history;\n }\n return { future: [], past: [...history.past, history.present].slice(-HISTORY_LIMIT), present };\n};\n\nconst undo = (history: History): History => {\n const previous = history.past.at(-1);\n if (previous === undefined) {\n return history;\n }\n return {\n future: [history.present, ...history.future],\n past: history.past.slice(0, -1),\n present: previous,\n };\n};\n\nconst redo = (history: History): History => {\n const [next, ...rest] = history.future;\n if (next === undefined) {\n return history;\n }\n return {\n future: rest,\n past: [...history.past, history.present].slice(-HISTORY_LIMIT),\n present: next,\n };\n};\n\nexport { canRedo, canUndo, createHistory, dispatch, HISTORY_LIMIT, redo, undo };\nexport type { History };\n","import { assign, setup } from \"xstate\";\n\nimport type { Dashfoo } from \"../model/schema\";\nimport type { Action } from \"../state/actions\";\nimport type { History } from \"../state/history\";\nimport { createHistory, dispatch, redo, undo } from \"../state/history\";\n\ntype DashfooContext = { history: History };\n\ntype DashfooEvent =\n | { action: Action; type: \"DISPATCH\" }\n | { model: Dashfoo; type: \"SET_MODEL\" }\n | { type: \"REDO\" }\n | { type: \"UNDO\" };\n\ntype DashfooMachineInput = { model: Dashfoo };\n\nconst dashfooMachine = setup({\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DashfooContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DashfooEvent,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n input: {} as DashfooMachineInput,\n },\n}).createMachine({\n context: ({ input }) => ({ history: createHistory(input.model) }),\n id: \"dashfoo\",\n initial: \"ready\",\n states: {\n ready: {\n on: {\n DISPATCH: {\n actions: assign({\n history: ({ context, event }) => dispatch(context.history, event.action),\n }),\n },\n REDO: {\n actions: assign({ history: ({ context }) => redo(context.history) }),\n },\n SET_MODEL: {\n actions: assign({ history: ({ event }) => createHistory(event.model) }),\n },\n UNDO: {\n actions: assign({ history: ({ context }) => undo(context.history) }),\n },\n },\n },\n },\n});\n\nexport { dashfooMachine };\n","import { assign, emit, setup } from \"xstate\";\n\nimport type { TabNode } from \"../model/schema\";\nimport type { Action, DropIntent } from \"../state/actions\";\n\ntype DragSubject =\n | { id: string; kind: \"tab\" | \"tabset\" }\n | { id: string; kind: \"external\"; tab: TabNode };\n\n/** `scope` names whoever resolved the intent, echoed back on `COMMIT` so the host can route the action. */\ntype DropResolution = { intent: DropIntent; scope: string };\n\n/** One value, so a drop target without a subject is unrepresentable. See ADR 0002. */\ntype DragState =\n | { drop: DropResolution | null; kind: \"dragging\"; subject: DragSubject }\n | { kind: \"idle\" };\n\ntype DragContext = { drag: DragState };\n\ntype DragEvent =\n | { drop: DropResolution | null; type: \"OVER\" }\n | { subject: DragSubject; type: \"START\" }\n | { type: \"CANCEL\" }\n | { type: \"DROP\" };\n\ntype DragEmitted = { action: Action; scope: string; type: \"COMMIT\" };\n\n/** One definition of both \"is this drop valid\" and \"what does it do\", so the guard and the emit agree. */\nconst dropAction = (drag: DragState): { action: Action; scope: string } | null => {\n if (drag.kind !== \"dragging\" || drag.drop === null) {\n return null;\n }\n const { intent, scope } = drag.drop;\n const { subject } = drag;\n\n if (subject.kind === \"external\") {\n return {\n action: {\n index: intent.index,\n location: intent.location,\n tab: subject.tab,\n targetId: intent.targetId,\n type: \"addNode\",\n },\n scope,\n };\n }\n if (subject.kind === \"tabset\") {\n return {\n action: {\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveTabset\",\n },\n scope,\n };\n }\n return {\n action: {\n index: intent.index,\n location: intent.location,\n sourceId: subject.id,\n targetId: intent.targetId,\n type: \"moveNode\",\n },\n scope,\n };\n};\n\nconst dragDockMachine = setup({\n guards: {\n hasValidDrop: ({ context }) => dropAction(context.drag) !== null,\n },\n types: {\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n context: {} as DragContext,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n emitted: {} as DragEmitted,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- XState's documented phantom-type API; the values are compile-time only.\n events: {} as DragEvent,\n },\n}).createMachine({\n context: { drag: { kind: \"idle\" } },\n id: \"dragDock\",\n initial: \"idle\",\n states: {\n dragging: {\n on: {\n CANCEL: { target: \"idle\" },\n DROP: [\n {\n actions: emit(({ context }) => {\n const resolved = dropAction(context.drag);\n if (resolved === null) {\n throw new Error(\"drop requires a subject and a resolved drop target\");\n }\n return { action: resolved.action, scope: resolved.scope, type: \"COMMIT\" };\n }),\n guard: \"hasValidDrop\",\n target: \"idle\",\n },\n { target: \"idle\" },\n ],\n OVER: {\n actions: assign({\n drag: ({ context, event }) =>\n context.drag.kind === \"dragging\"\n ? { ...context.drag, drop: event.drop }\n : context.drag,\n }),\n },\n },\n },\n idle: {\n entry: assign({ drag: { kind: \"idle\" } }),\n on: {\n START: {\n actions: assign({\n drag: ({ event }) => ({ drop: null, kind: \"dragging\", subject: event.subject }),\n }),\n target: \"dragging\",\n },\n },\n },\n },\n});\n\nexport { dragDockMachine, dropAction };\nexport type { DragState, DragSubject, DropResolution };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo } from \"./schema\";\nimport { dashfooSchema } from \"./schema\";\nimport { findDuplicateIds } from \"./tree\";\n\nconst parseModel = (value: unknown): Dashfoo => {\n const model = normalize(dashfooSchema.parse(value));\n const duplicates = findDuplicateIds(model);\n if (duplicates.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(`[dashfoo] duplicate node ids in the loaded layout: ${duplicates.join(\", \")}`);\n }\n return model;\n};\n\nconst toJSON = (model: Dashfoo): string => JSON.stringify(model);\n\nconst fromJSON = (json: string): Dashfoo => parseModel(JSON.parse(json));\n\nexport { fromJSON, parseModel, toJSON };\n","import { normalize } from \"./invariants\";\nimport type { Dashfoo, Orientation, TabsetNode } from \"./schema\";\nimport { collectTabsetsInRow } from \"./tree\";\n\nconst stackModel = (model: Dashfoo, orientation: Orientation = \"column\"): Dashfoo => {\n const mainTabsets: Array<TabsetNode> = [];\n collectTabsetsInRow(model.layout, mainTabsets);\n const children: Array<TabsetNode> = [];\n for (const tabset of mainTabsets) {\n children.push({ ...tabset, weight: 1 });\n }\n\n return normalize({\n ...model,\n layout: {\n children,\n id: model.layout.id,\n orientation,\n type: \"row\",\n weight: model.layout.weight,\n },\n maximizedTabsetId: undefined,\n });\n};\n\nexport { stackModel };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dashfoo/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Headless docking-layout engine: model, actions, reducer, serialization, geometry, and the XState actor system. No React.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Pedro Filho <pedro@filho.me>",
|