UNPKG

@eristack/spreadsheet-operator

Version:

Headless spreadsheet keyboard operator — active-grid scope, cell navigation, Excel-like Enter/Tab editing

1 lines • 34.7 kB
{"version":3,"sources":["../src/index.ts","../src/core/types.ts","../src/core/address.ts","../src/core/navigation.ts","../src/core/keymap.ts","../src/core/reduce.ts","../src/core/create-operator.ts"],"sourcesContent":["export type {\n ArrowInEdit,\n CellAddress,\n CellDescriptor,\n CellNavKind,\n EnterMove,\n GridDescriptor,\n GridId,\n MoveDirection,\n NavDirection,\n OperatorAction,\n OperatorContext,\n OperatorEffect,\n OperatorKeyEvent,\n ResolvedSpreadsheetOperatorConfig,\n SpreadsheetCommitEvent,\n SpreadsheetOperatorConfig,\n SpreadsheetOperatorListener,\n SpreadsheetOperatorState,\n TabDirection,\n WrapPolicy,\n} from \"./core/types.js\";\nexport {\n DEFAULT_EDITABLE_KINDS,\n DEFAULT_NAVIGABLE_KINDS,\n} from \"./core/types.js\";\nexport {\n addressKey,\n cellKey,\n clampAddress,\n compareRaster,\n inBounds,\n sameAddress,\n} from \"./core/address.js\";\nexport {\n getNextEditableAddress,\n isEditable,\n isKind,\n isNavigable,\n kindAt,\n listNavigableAddresses,\n moveActiveAddress,\n resolveConfig,\n tabActiveAddress,\n} from \"./core/navigation.js\";\nexport { keyEventToAction } from \"./core/keymap.js\";\nexport { reduceOperator } from \"./core/reduce.js\";\nexport {\n createSpreadsheetOperator,\n type SpreadsheetOperator,\n} from \"./core/create-operator.js\";\n","export type GridId = string;\n\nexport type CellAddress = {\n readonly row: number;\n readonly col: number;\n};\n\nexport type CellNavKind = \"editable\" | \"select\" | \"display\" | \"readonly\";\n\nexport type CellDescriptor = {\n readonly kind: CellNavKind;\n readonly id?: string;\n readonly fieldKey?: string;\n};\n\nexport type GridDescriptor = {\n readonly id: GridId;\n readonly rowCount: number;\n readonly colCount: number;\n cellAt: (address: CellAddress) => CellDescriptor;\n};\n\nexport type SpreadsheetOperatorState =\n | { readonly mode: \"inactive\" }\n | { readonly mode: \"active\"; readonly gridId: GridId; readonly address: CellAddress }\n | {\n readonly mode: \"editing\";\n readonly gridId: GridId;\n readonly address: CellAddress;\n readonly seed?: string;\n };\n\nexport type WrapPolicy = \"wrap\" | \"stop\";\nexport type EnterMove = \"down\" | \"right\" | \"none\";\nexport type ArrowInEdit = \"caret\" | \"leave\";\n\nexport type MoveDirection = \"up\" | \"down\" | \"left\" | \"right\";\nexport type TabDirection = \"next\" | \"prev\";\nexport type NavDirection = MoveDirection | TabDirection;\n\nexport type SpreadsheetOperatorConfig = {\n /** Tab wrap. Default `wrap`. */\n readonly wrap?: WrapPolicy;\n /** Arrow wrap at edges. Default `stop`. */\n readonly arrowWrap?: WrapPolicy;\n /** After Enter commit. Default `down`. */\n readonly enterMove?: EnterMove;\n /** Printable key on an active cell starts edit. Default `true`. */\n readonly typeToEdit?: boolean;\n /** Kinds arrows/Tab land on. Default `editable` + `select` (skip `readonly`/`display`). */\n readonly navigableKinds?: readonly CellNavKind[];\n /** Kinds Enter/F2/type can edit. Default `editable` + `select`. */\n readonly editableKinds?: readonly CellNavKind[];\n /** Arrows while editing. Default `caret` (leave to the input). */\n readonly arrowInEdit?: ArrowInEdit;\n};\n\nexport type ResolvedSpreadsheetOperatorConfig = {\n readonly wrap: WrapPolicy;\n readonly arrowWrap: WrapPolicy;\n readonly enterMove: EnterMove;\n readonly typeToEdit: boolean;\n readonly navigableKinds: readonly CellNavKind[];\n readonly editableKinds: readonly CellNavKind[];\n readonly arrowInEdit: ArrowInEdit;\n};\n\nexport const DEFAULT_NAVIGABLE_KINDS: readonly CellNavKind[] = [\"editable\", \"select\"];\nexport const DEFAULT_EDITABLE_KINDS: readonly CellNavKind[] = [\"editable\", \"select\"];\n\nexport type OperatorAction =\n | { readonly type: \"activate\"; readonly gridId: GridId; readonly address: CellAddress }\n | { readonly type: \"deactivate\" }\n | { readonly type: \"move\"; readonly direction: MoveDirection }\n | { readonly type: \"tab\"; readonly shift?: boolean }\n | { readonly type: \"enter\" }\n | { readonly type: \"escape\" }\n | { readonly type: \"f2\" }\n | { readonly type: \"type\"; readonly char: string }\n | { readonly type: \"commit\" }\n | { readonly type: \"cancel\" };\n\nexport type OperatorEffect =\n | {\n readonly type: \"commit\";\n readonly gridId: GridId;\n readonly address: CellAddress;\n readonly fieldKey?: string;\n readonly phase: \"commit\";\n }\n | {\n readonly type: \"cancel\";\n readonly gridId: GridId;\n readonly address: CellAddress;\n readonly phase: \"cancel\";\n }\n | {\n readonly type: \"startEdit\";\n readonly gridId: GridId;\n readonly address: CellAddress;\n readonly seed?: string;\n };\n\nexport type SpreadsheetCommitEvent = {\n readonly gridId: GridId;\n readonly address: CellAddress;\n readonly fieldKey?: string;\n readonly value: string;\n readonly phase: \"commit\";\n};\n\nexport type OperatorKeyEvent = {\n readonly key: string;\n readonly shiftKey?: boolean;\n readonly altKey?: boolean;\n readonly ctrlKey?: boolean;\n readonly metaKey?: boolean;\n readonly isComposing?: boolean;\n};\n\nexport type OperatorContext = {\n readonly grids: ReadonlyMap<GridId, GridDescriptor>;\n readonly config: ResolvedSpreadsheetOperatorConfig;\n};\n\nexport type SpreadsheetOperatorListener = (\n state: SpreadsheetOperatorState,\n effects: readonly OperatorEffect[],\n) => void;\n","import type { CellAddress, GridDescriptor } from \"./types.js\";\n\nexport function sameAddress(a: CellAddress, b: CellAddress): boolean {\n return a.row === b.row && a.col === b.col;\n}\n\nexport function addressKey(address: CellAddress): string {\n return `${address.row}:${address.col}`;\n}\n\nexport function cellKey(gridId: string, address: CellAddress): string {\n return `${gridId}:${address.row}:${address.col}`;\n}\n\nexport function inBounds(address: CellAddress, grid: GridDescriptor): boolean {\n return (\n address.row >= 0 &&\n address.col >= 0 &&\n address.row < grid.rowCount &&\n address.col < grid.colCount\n );\n}\n\nexport function clampAddress(address: CellAddress, grid: GridDescriptor): CellAddress {\n if (grid.rowCount < 1 || grid.colCount < 1) {\n return { row: 0, col: 0 };\n }\n return {\n row: Math.min(Math.max(0, address.row), grid.rowCount - 1),\n col: Math.min(Math.max(0, address.col), grid.colCount - 1),\n };\n}\n\nexport function compareRaster(a: CellAddress, b: CellAddress): number {\n if (a.row !== b.row) return a.row - b.row;\n return a.col - b.col;\n}\n","import { clampAddress, compareRaster, inBounds, sameAddress } from \"./address.js\";\nimport type {\n CellAddress,\n CellNavKind,\n GridDescriptor,\n MoveDirection,\n NavDirection,\n ResolvedSpreadsheetOperatorConfig,\n SpreadsheetOperatorConfig,\n TabDirection,\n} from \"./types.js\";\nimport {\n DEFAULT_EDITABLE_KINDS,\n DEFAULT_NAVIGABLE_KINDS,\n} from \"./types.js\";\n\nexport function resolveConfig(\n config: SpreadsheetOperatorConfig = {},\n): ResolvedSpreadsheetOperatorConfig {\n return {\n wrap: config.wrap ?? \"wrap\",\n arrowWrap: config.arrowWrap ?? \"stop\",\n enterMove: config.enterMove ?? \"down\",\n typeToEdit: config.typeToEdit ?? true,\n navigableKinds: config.navigableKinds ?? DEFAULT_NAVIGABLE_KINDS,\n editableKinds: config.editableKinds ?? DEFAULT_EDITABLE_KINDS,\n arrowInEdit: config.arrowInEdit ?? \"caret\",\n };\n}\n\nexport function kindAt(grid: GridDescriptor, address: CellAddress): CellNavKind | undefined {\n if (!inBounds(address, grid)) return undefined;\n return grid.cellAt(address).kind;\n}\n\nexport function isKind(\n kind: CellNavKind | undefined,\n allowed: readonly CellNavKind[],\n): boolean {\n return kind !== undefined && allowed.includes(kind);\n}\n\nexport function isNavigable(\n grid: GridDescriptor,\n address: CellAddress,\n config: ResolvedSpreadsheetOperatorConfig,\n): boolean {\n return isKind(kindAt(grid, address), config.navigableKinds);\n}\n\nexport function isEditable(\n grid: GridDescriptor,\n address: CellAddress,\n config: ResolvedSpreadsheetOperatorConfig,\n): boolean {\n return isKind(kindAt(grid, address), config.editableKinds);\n}\n\nexport function listNavigableAddresses(\n grid: GridDescriptor,\n config: ResolvedSpreadsheetOperatorConfig,\n): CellAddress[] {\n const out: CellAddress[] = [];\n for (let row = 0; row < grid.rowCount; row += 1) {\n for (let col = 0; col < grid.colCount; col += 1) {\n const address = { row, col };\n if (isNavigable(grid, address, config)) out.push(address);\n }\n }\n return out;\n}\n\nfunction step(address: CellAddress, direction: MoveDirection): CellAddress {\n switch (direction) {\n case \"up\":\n return { row: address.row - 1, col: address.col };\n case \"down\":\n return { row: address.row + 1, col: address.col };\n case \"left\":\n return { row: address.row, col: address.col - 1 };\n case \"right\":\n return { row: address.row, col: address.col + 1 };\n }\n}\n\nfunction wrapArrowStart(\n address: CellAddress,\n direction: MoveDirection,\n grid: GridDescriptor,\n): CellAddress {\n switch (direction) {\n case \"up\":\n return { row: grid.rowCount - 1, col: address.col };\n case \"down\":\n return { row: 0, col: address.col };\n case \"left\":\n return { row: address.row, col: grid.colCount - 1 };\n case \"right\":\n return { row: address.row, col: 0 };\n }\n}\n\nexport function moveActiveAddress(\n grid: GridDescriptor,\n from: CellAddress,\n direction: MoveDirection,\n config: ResolvedSpreadsheetOperatorConfig,\n): CellAddress {\n if (grid.rowCount < 1 || grid.colCount < 1) return from;\n const origin = clampAddress(from, grid);\n let cursor = origin;\n const limit = Math.max(grid.rowCount, grid.colCount) + 1;\n for (let i = 0; i < limit; i += 1) {\n const next = step(cursor, direction);\n if (!inBounds(next, grid)) {\n if (config.arrowWrap === \"stop\") return origin;\n cursor = wrapArrowStart(origin, direction, grid);\n } else {\n cursor = next;\n }\n if (sameAddress(cursor, origin)) return origin;\n if (isNavigable(grid, cursor, config)) return cursor;\n }\n return origin;\n}\n\nfunction nextAfterRaster(\n list: CellAddress[],\n from: CellAddress,\n direction: TabDirection,\n): CellAddress | undefined {\n if (direction === \"next\") {\n return list.find((cell) => compareRaster(cell, from) > 0);\n }\n for (let i = list.length - 1; i >= 0; i -= 1) {\n const cell = list[i];\n if (cell && compareRaster(cell, from) < 0) return cell;\n }\n return undefined;\n}\n\nexport function tabActiveAddress(\n grid: GridDescriptor,\n from: CellAddress,\n direction: TabDirection,\n config: ResolvedSpreadsheetOperatorConfig,\n): CellAddress {\n const list = listNavigableAddresses(grid, config);\n if (list.length === 0) return from;\n const idx = list.findIndex((cell) => sameAddress(cell, from));\n if (idx === -1) {\n const found = nextAfterRaster(list, from, direction);\n if (found) return found;\n if (config.wrap === \"wrap\") {\n return direction === \"next\" ? (list[0] ?? from) : (list[list.length - 1] ?? from);\n }\n return from;\n }\n const delta = direction === \"next\" ? 1 : -1;\n const nextIdx = idx + delta;\n if (nextIdx >= 0 && nextIdx < list.length) {\n return list[nextIdx] ?? from;\n }\n if (config.wrap === \"wrap\") {\n return direction === \"next\" ? (list[0] ?? from) : (list[list.length - 1] ?? from);\n }\n return from;\n}\n\nexport function getNextEditableAddress(\n grid: GridDescriptor,\n from: CellAddress,\n direction: NavDirection,\n config: SpreadsheetOperatorConfig = {},\n): CellAddress | null {\n const resolved = resolveConfig(config);\n const origin = clampAddress(from, grid);\n if (direction === \"next\" || direction === \"prev\") {\n const next = tabActiveAddress(grid, origin, direction, resolved);\n return sameAddress(next, origin) && !isNavigable(grid, origin, resolved)\n ? null\n : next;\n }\n const next = moveActiveAddress(grid, origin, direction, resolved);\n if (sameAddress(next, origin) && !isNavigable(grid, origin, resolved)) {\n return isNavigable(grid, next, resolved) ? next : null;\n }\n return next;\n}\n","import type { MoveDirection } from \"./types.js\";\nimport type {\n OperatorAction,\n OperatorKeyEvent,\n ResolvedSpreadsheetOperatorConfig,\n SpreadsheetOperatorState,\n} from \"./types.js\";\n\nconst ARROWS: Record<string, MoveDirection> = {\n ArrowUp: \"up\",\n ArrowDown: \"down\",\n ArrowLeft: \"left\",\n ArrowRight: \"right\",\n};\n\nfunction isPrintable(key: string): boolean {\n return key.length === 1;\n}\n\nexport function keyEventToAction(\n state: SpreadsheetOperatorState,\n event: OperatorKeyEvent,\n config: ResolvedSpreadsheetOperatorConfig,\n): OperatorAction | undefined {\n if (event.isComposing) return undefined;\n if (event.ctrlKey || event.metaKey || event.altKey) return undefined;\n\n const arrow = ARROWS[event.key];\n if (arrow) {\n if (state.mode === \"inactive\") return undefined;\n if (state.mode === \"editing\" && config.arrowInEdit === \"caret\") return undefined;\n return { type: \"move\", direction: arrow };\n }\n\n if (event.key === \"Tab\") {\n if (state.mode === \"inactive\") return undefined;\n return { type: \"tab\", shift: event.shiftKey === true };\n }\n\n if (event.key === \"Enter\") {\n if (state.mode === \"inactive\") return undefined;\n return { type: \"enter\" };\n }\n\n if (event.key === \"Escape\") {\n if (state.mode === \"inactive\") return undefined;\n return { type: \"escape\" };\n }\n\n if (event.key === \"F2\") {\n if (state.mode !== \"active\") return undefined;\n return { type: \"f2\" };\n }\n\n if (state.mode === \"active\" && config.typeToEdit && isPrintable(event.key)) {\n return { type: \"type\", char: event.key };\n }\n\n return undefined;\n}\n","import { clampAddress, sameAddress } from \"./address.js\";\nimport { isEditable, moveActiveAddress, tabActiveAddress } from \"./navigation.js\";\nimport type {\n CellAddress,\n GridDescriptor,\n GridId,\n OperatorAction,\n OperatorContext,\n OperatorEffect,\n SpreadsheetOperatorState,\n} from \"./types.js\";\n\nfunction fieldKeyAt(grid: GridDescriptor, address: CellAddress): string | undefined {\n const cell = grid.cellAt(address);\n return cell.fieldKey ?? cell.id;\n}\n\nfunction commitEffect(\n gridId: GridId,\n address: CellAddress,\n ctx: OperatorContext,\n): OperatorEffect {\n const grid = ctx.grids.get(gridId);\n return {\n type: \"commit\",\n gridId,\n address,\n fieldKey: grid ? fieldKeyAt(grid, address) : undefined,\n phase: \"commit\",\n };\n}\n\nfunction cancelEffect(gridId: GridId, address: CellAddress): OperatorEffect {\n return { type: \"cancel\", gridId, address, phase: \"cancel\" };\n}\n\nfunction startEditEffect(\n gridId: GridId,\n address: CellAddress,\n seed?: string,\n): OperatorEffect {\n return { type: \"startEdit\", gridId, address, seed };\n}\n\nfunction gridOf(\n ctx: OperatorContext,\n gridId: GridId,\n): GridDescriptor | undefined {\n return ctx.grids.get(gridId);\n}\n\nfunction editingOf(\n state: SpreadsheetOperatorState,\n): Extract<SpreadsheetOperatorState, { mode: \"editing\" }> | undefined {\n return state.mode === \"editing\" ? state : undefined;\n}\n\nfunction positionedOf(\n state: SpreadsheetOperatorState,\n): Extract<SpreadsheetOperatorState, { mode: \"active\" | \"editing\" }> | undefined {\n return state.mode === \"inactive\" ? undefined : state;\n}\n\nfunction commitIfEditing(\n state: SpreadsheetOperatorState,\n ctx: OperatorContext,\n): OperatorEffect[] {\n const editing = editingOf(state);\n if (!editing) return [];\n return [commitEffect(editing.gridId, editing.address, ctx)];\n}\n\nfunction enterMoveAddress(\n grid: GridDescriptor,\n from: CellAddress,\n ctx: OperatorContext,\n): CellAddress {\n if (ctx.config.enterMove === \"none\") return from;\n const direction = ctx.config.enterMove === \"right\" ? \"right\" : \"down\";\n return moveActiveAddress(grid, from, direction, ctx.config);\n}\n\nexport function reduceOperator(\n state: SpreadsheetOperatorState,\n action: OperatorAction,\n ctx: OperatorContext,\n): { state: SpreadsheetOperatorState; effects: OperatorEffect[] } {\n switch (action.type) {\n case \"activate\": {\n const grid = gridOf(ctx, action.gridId);\n if (!grid || grid.rowCount < 1 || grid.colCount < 1) {\n return { state, effects: [] };\n }\n const address = clampAddress(action.address, grid);\n const effects = commitIfEditing(state, ctx);\n const next: SpreadsheetOperatorState = {\n mode: \"active\",\n gridId: action.gridId,\n address,\n };\n if (\n state.mode === \"active\" &&\n state.gridId === next.gridId &&\n sameAddress(state.address, next.address) &&\n effects.length === 0\n ) {\n return { state, effects: [] };\n }\n return { state: next, effects };\n }\n case \"deactivate\": {\n if (state.mode === \"inactive\") return { state, effects: [] };\n return { state: { mode: \"inactive\" }, effects: commitIfEditing(state, ctx) };\n }\n case \"move\": {\n const pos = positionedOf(state);\n if (!pos) return { state, effects: [] };\n if (state.mode === \"editing\" && ctx.config.arrowInEdit === \"caret\") {\n return { state, effects: [] };\n }\n const grid = gridOf(ctx, pos.gridId);\n if (!grid) return { state, effects: [] };\n const effects = commitIfEditing(state, ctx);\n const address = moveActiveAddress(grid, pos.address, action.direction, ctx.config);\n return {\n state: { mode: \"active\", gridId: pos.gridId, address },\n effects,\n };\n }\n case \"tab\": {\n const pos = positionedOf(state);\n if (!pos) return { state, effects: [] };\n const grid = gridOf(ctx, pos.gridId);\n if (!grid) return { state, effects: [] };\n const effects = commitIfEditing(state, ctx);\n const address = tabActiveAddress(\n grid,\n pos.address,\n action.shift ? \"prev\" : \"next\",\n ctx.config,\n );\n return {\n state: { mode: \"active\", gridId: pos.gridId, address },\n effects,\n };\n }\n case \"enter\": {\n if (state.mode === \"inactive\") return { state, effects: [] };\n const grid = gridOf(ctx, state.gridId);\n if (!grid) return { state, effects: [] };\n if (state.mode === \"active\") {\n if (!isEditable(grid, state.address, ctx.config)) {\n return { state, effects: [] };\n }\n return {\n state: { mode: \"editing\", gridId: state.gridId, address: state.address },\n effects: [startEditEffect(state.gridId, state.address)],\n };\n }\n const address = enterMoveAddress(grid, state.address, ctx);\n return {\n state: { mode: \"active\", gridId: state.gridId, address },\n effects: [commitEffect(state.gridId, state.address, ctx)],\n };\n }\n case \"escape\": {\n if (state.mode === \"inactive\") return { state, effects: [] };\n if (state.mode === \"editing\") {\n return {\n state: { mode: \"active\", gridId: state.gridId, address: state.address },\n effects: [cancelEffect(state.gridId, state.address)],\n };\n }\n return { state: { mode: \"inactive\" }, effects: [] };\n }\n case \"f2\": {\n if (state.mode !== \"active\") return { state, effects: [] };\n const grid = gridOf(ctx, state.gridId);\n if (!grid || !isEditable(grid, state.address, ctx.config)) {\n return { state, effects: [] };\n }\n return {\n state: { mode: \"editing\", gridId: state.gridId, address: state.address },\n effects: [startEditEffect(state.gridId, state.address)],\n };\n }\n case \"type\": {\n if (!ctx.config.typeToEdit) return { state, effects: [] };\n if (state.mode !== \"active\") return { state, effects: [] };\n const grid = gridOf(ctx, state.gridId);\n if (!grid || !isEditable(grid, state.address, ctx.config)) {\n return { state, effects: [] };\n }\n return {\n state: {\n mode: \"editing\",\n gridId: state.gridId,\n address: state.address,\n seed: action.char,\n },\n effects: [startEditEffect(state.gridId, state.address, action.char)],\n };\n }\n case \"commit\": {\n if (state.mode !== \"editing\") return { state, effects: [] };\n return {\n state: { mode: \"active\", gridId: state.gridId, address: state.address },\n effects: [commitEffect(state.gridId, state.address, ctx)],\n };\n }\n case \"cancel\": {\n if (state.mode !== \"editing\") return { state, effects: [] };\n return {\n state: { mode: \"active\", gridId: state.gridId, address: state.address },\n effects: [cancelEffect(state.gridId, state.address)],\n };\n }\n }\n}\n","import { keyEventToAction } from \"./keymap.js\";\nimport { resolveConfig } from \"./navigation.js\";\nimport { reduceOperator } from \"./reduce.js\";\nimport type {\n GridDescriptor,\n GridId,\n OperatorAction,\n OperatorEffect,\n OperatorKeyEvent,\n SpreadsheetOperatorConfig,\n SpreadsheetOperatorListener,\n SpreadsheetOperatorState,\n} from \"./types.js\";\n\nexport type SpreadsheetOperator = {\n getState(): SpreadsheetOperatorState;\n dispatch(action: OperatorAction): {\n state: SpreadsheetOperatorState;\n effects: readonly OperatorEffect[];\n };\n handleKeyDown(event: OperatorKeyEvent): boolean;\n registerGrid(descriptor: GridDescriptor): void;\n unregisterGrid(gridId: GridId): void;\n getGrid(gridId: GridId): GridDescriptor | undefined;\n subscribe(listener: SpreadsheetOperatorListener): () => void;\n};\n\nexport function createSpreadsheetOperator(\n config: SpreadsheetOperatorConfig = {},\n): SpreadsheetOperator {\n const resolved = resolveConfig(config);\n let state: SpreadsheetOperatorState = { mode: \"inactive\" };\n const grids = new Map<GridId, GridDescriptor>();\n const listeners = new Set<SpreadsheetOperatorListener>();\n\n function notify(effects: readonly OperatorEffect[]): void {\n for (const listener of listeners) listener(state, effects);\n }\n\n function dispatch(action: OperatorAction): {\n state: SpreadsheetOperatorState;\n effects: readonly OperatorEffect[];\n } {\n const result = reduceOperator(state, action, { grids, config: resolved });\n if (result.state === state && result.effects.length === 0) {\n return result;\n }\n state = result.state;\n notify(result.effects);\n return result;\n }\n\n return {\n getState() {\n return state;\n },\n dispatch,\n handleKeyDown(event) {\n const action = keyEventToAction(state, event, resolved);\n if (!action) return false;\n const before = state;\n const result = dispatch(action);\n return result.state !== before || result.effects.length > 0;\n },\n registerGrid(descriptor) {\n grids.set(descriptor.id, descriptor);\n },\n unregisterGrid(gridId) {\n const active = state.mode !== \"inactive\" && state.gridId === gridId;\n if (active) dispatch({ type: \"deactivate\" });\n grids.delete(gridId);\n },\n getGrid(gridId) {\n return grids.get(gridId);\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n"],"mappings":"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","names":["next"]}