@dashfoo/core 0.5.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +159 -67
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +178 -80
- 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":["/**\n * Lives in `lib/` rather than beside `normalize`, because both the parse\n * boundary (`tabsetNodeSchema`) and the tree walker that `normalize` uses need\n * it, and importing it from either one would close a module cycle.\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\nexport { clampSelected };\n","import { z } from \"zod\";\n\nimport { clampSelected } from \"../lib/clamp-selected\";\n\n/**\n * Weights are relative shares, and every reader that rendered one already\n * treated a missing weight as a single share (`row-view` summed `weight ?? 1`),\n * so filling it in at the boundary changes nothing on screen. The one place that\n * read a missing weight as a percentage was `placeBesideTarget`, which is why\n * docking beside an unweighted target halved it to `50` and left its unweighted\n * siblings rendering as a sliver of the row.\n */\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 * The pre-transform object, kept separate so `node-attrs` can `.pick()` mutable\n * keys off it. Picking from the transformed schema is impossible (a pipe has no\n * `.pick`), and picking `weight` with its default attached would inject that\n * default: `.partial()` over a defaulted field still fills it in, which would\n * rewrite a tabset's weight on every unrelated attribute update.\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\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\ntype RowNodeInput = {\n children: Array<RowNodeInput | z.input<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, RowNodeInput> = 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().default(DEFAULT_WEIGHT),\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 // A getter, not a literal: zod hands the same array instance to every parse of\n // a float-less model, and `dockFloat` splices its float list in place.\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/**\n * `weight` is re-declared instead of picked: `.partial()` over the schema's\n * defaulted `weight` still injects the default, so `{ name: \"x\" }` would arrive\n * at the reducer carrying a weight and silently resize the tabset.\n */\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 * One all-optional object carrying every mutable key of every node kind, not a\n * union of the three: a union whose members are all fully optional matches on\n * its first member and strips the keys the others own, which erased every\n * tabset and row attribute at the parse boundary. The four keys that two kinds\n * share (`enableClose`, `max`, `min`, `weight`) declare the same type on both\n * sides, so merging widens nothing. Which keys are legal for a given node is\n * enforced by the reducer against that node's own schema.\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 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 };\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 { 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 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 dockLocationFor = (target: DockTarget): DockLocation => {\n switch (target.kind) {\n case \"split\": {\n return `split-${target.edge}`;\n }\n case \"tab\": {\n return \"center\";\n }\n default: {\n return assertNever(target);\n }\n }\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): 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 assertNever(location);\n }\n }\n};\n\nexport { dockLocationFor, dockZonePolygons, resolveDockTarget, splitEdge, 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\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 config: SnapConfig | null,\n): SnapDecision => {\n if (boundaryIndex === null || config === null || !snapEnabled(config)) {\n return { kind: \"inactive\" };\n }\n const { sizes: snappedSizes, snapped } = snapSizes(sizes, boundaryIndex, config);\n return snapped ? { kind: \"engage\", sizes: snappedSizes } : { kind: \"clear\" };\n};\n\nconst settleSnap = (\n sizes: Array<number>,\n boundaryIndex: number | null,\n config: SnapConfig | null,\n): Array<number> => {\n const decision = decideSnap(sizes, boundaryIndex, config);\n return decision.kind === \"engage\" ? decision.sizes : sizes;\n};\n\nexport {\n DEFAULT_SNAP_THRESHOLD,\n decideSnap,\n resolveSnapTargets,\n settleSnap,\n snapEnabled,\n snapSizes,\n};\nexport type { SnapDecision, SnapResult };\n","import type { Dashfoo, FloatNode, RowNode } from \"./schema\";\nimport { collectTabsets } from \"./tree\";\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 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(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 floats: Array<FloatNode> = [];\n for (const float of model.floats) {\n const floatLayout = normalizeLayout(float.layout);\n if (rowContainsTabset(floatLayout)) {\n floats.push({ ...float, layout: floatLayout });\n }\n }\n\n const withRoots: Dashfoo = { ...model, floats, layout };\n\n const tabsets = collectTabsets(withRoots);\n const tabsetIds = new Set(tabsets.map((tabset) => tabset.id));\n const firstTabsetId = tabsets[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 { normalize };\n","import { splitEdge } from \"../geometry/geometry\";\nimport { 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 { 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 splitPlacement = (location: DockLocation): { before: boolean; orientation: Orientation } => {\n const edge = splitEdge(location);\n return {\n before: edge === \"left\" || edge === \"top\",\n orientation: edge === \"left\" || edge === \"right\" ? \"row\" : \"column\",\n };\n};\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 { before, orientation } = splitPlacement(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 // The wrapping row takes over the slot the target held, so it inherits the\n // target's weight while the two halves split its interior evenly.\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};\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 // `index` is caller-supplied and only validated as an integer. Splice pins\n // an out-of-range one to an end of the strip, so `selected` has to be\n // pinned the same way or it points past the tab it was meant to follow.\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;\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 placeBesideTarget(draft, newTabset, targetId, location);\n};\n\n/**\n * Removing a tab can leave `selected` past the end of the strip, so every\n * detach re-clamps its container rather than leaving the whole tree to be\n * re-walked afterwards.\n */\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 removeTabset,\n removeTabsetReturning,\n wrapTabInLayout,\n wrapTabsetInLayout,\n};\nexport type { DropTarget };\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, 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 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 : {\n children: tabs,\n id: createNodeId(\"tabset\"),\n selected: selectedOffset,\n type: \"tabset\",\n weight: DEFAULT_WEIGHT,\n };\n placeBesideTarget(draft, placed, target.id, where);\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 } from \"../model/schema\";\nimport type { AttributedNode } from \"../model/tree\";\nimport {\n findAttributedNode,\n findFloat,\n findRootContaining,\n findRow,\n findTab,\n findTabset,\n} 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 removeTabset,\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 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 detachTab(location.container, location.index);\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 = detachTab(location.container, location.index);\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 = detachTab(source.container, source.index);\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 const sourceRoot = findRootContaining(draft, action.sourceId);\n const detached = sourceRoot ? removeTabsetReturning(sourceRoot, action.sourceId) : undefined;\n if (detached) {\n placeBesideTarget(draft, detached, action.targetId, action.location);\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 = clampSelected(tabset.children.length, 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, parseNodeAttrs(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 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 };\nexport type { DashfooContext, DashfooEvent, DashfooMachineInput };\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: {\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": "0.
|
|
3
|
+
"version": "1.0.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>",
|