diff options
| author | Josh Kingsley <josh@joshkingsley.me> | 2025-11-24 15:46:22 +0200 |
|---|---|---|
| committer | Josh Kingsley <josh@joshkingsley.me> | 2025-11-24 15:46:22 +0200 |
| commit | d724cc0bf6ff6d351319e6fb00f5184a04e16ac0 (patch) | |
| tree | cb43253479df5db8f4844e17e68a48ea5a212df4 /packages/web/src/doc/index.ts | |
| parent | 7c966e105cd9f65853de1aba0ecce63aa56aca0b (diff) | |
chore: improve dev tasks
Diffstat (limited to 'packages/web/src/doc/index.ts')
| -rw-r--r-- | packages/web/src/doc/index.ts | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/packages/web/src/doc/index.ts b/packages/web/src/doc/index.ts deleted file mode 100644 index ae221f0..0000000 --- a/packages/web/src/doc/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Immutable, produce } from "immer"; - -export type Doc = Immutable<{ ops: Op[] }>; - -export type Op = CreateGrid | Subdivide; - -export type CreateGrid = Immutable<{ - type: "createGrid"; - gridId: string; - rows: number; - baseCellsPerRow: number; -}>; - -export function createGrid(): CreateGrid { - return { - type: "createGrid", - gridId: crypto.randomUUID(), - rows: 4, - baseCellsPerRow: 16, - }; -} - -export type Subdivide = Immutable<{ - type: "subdivide"; - gridId: string; - rowIndex: number; - startCellIndex: number; - endCellIndex: number; - subdivisions: number; -}>; - -export function subdivide( - gridId: string, - rowIndex: number, - startCellIndex: number, - endCellIndex: number, - subdivisions: number, -): Subdivide { - return { - type: "subdivide", - gridId, - rowIndex, - startCellIndex, - endCellIndex, - subdivisions, - }; -} - -export function defaultDoc(): Doc { - const ops = [createGrid()]; - return { ops }; -} - -export function apply(doc: Doc, ...ops: Op[]): Doc { - return produce(doc, (doc) => { - doc.ops.push(...ops); - }); -} - -export type DocIndex = Immutable<{ - opsByType: Map<Op["type"], Op[]>; -}>; - -export function indexDoc(doc: Doc): DocIndex { - const opsByType = new Map(); - - for (const op of doc.ops) { - opsByType.set(op.type, [...(opsByType.get(op.type) ?? []), op]); - } - - return { opsByType }; -} - -export function getOpsByType<T extends Op["type"]>( - index: DocIndex, - type: T, -): Extract<Op, { type: T }>[] { - return (index.opsByType.get(type) ?? []) as Extract<Op, { type: T }>[]; -} - -export type Grid = Immutable<{ id: string; rows: Row[] }>; - -export type Row = Immutable<{ index: number; cells: Cell[] }>; - -export type Cell = Immutable<{}>; - -export function realizeGrids(doc: Doc): Grid[] { - const index = indexDoc(doc); - const createGridOps = getOpsByType(index, "createGrid"); - return createGridOps.map((op) => realizeGrid(doc, index, op)); -} - -function realizeGrid(doc: Doc, index: DocIndex, createOp: CreateGrid): Grid { - const rows = []; - - for (let rowIndex = 0; rowIndex < createOp.rows; rowIndex++) { - let cells: Cell[] = []; - - for (let cellIndex = 0; cellIndex < createOp.baseCellsPerRow; cellIndex++) { - cells.push({ index: cellIndex }); - } - - const subdivideOps = doc.ops.filter( - (op) => - op.type === "subdivide" && - op.gridId === createOp.gridId && - op.rowIndex === rowIndex, - ) as Subdivide[]; - - subdivideOps.forEach((op) => { - cells = [ - ...cells.slice(0, op.startCellIndex), - ...Array.from({ length: op.subdivisions }, () => ({})), - ...cells.slice(op.endCellIndex + 1), - ]; - }); - - rows.push({ index: rowIndex, cells }); - } - - return { - id: createOp.gridId, - rows, - }; -} |
