@orkestrel/table 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/src/core/index.cjs +228 -196
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +237 -382
- package/dist/src/core/index.d.ts +237 -382
- package/dist/src/core/index.js +226 -191
- package/dist/src/core/index.js.map +1 -0
- package/package.json +20 -15
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["#emitter","#event","#gate","#rows","#read","#write","#keys","#schema","#emitter","#gate","#read","#write","#clamp","#validate","#operands","#emitter","#gate","#rows","#readPage","#writePage","#readLimit","#writeLimit","#normalize","#schema","#emitter","#gate","#read","#write","#settle","#prepare","#validate","#failKey","#same","#keys","#schema","#emitter","#gate","#read","#write","#require","#emitter","#schema","#comparators","#matchers","#initialLimit","#rows","#sort","#filter","#selection","#expansion","#pagination","#limit","#gate","#keys","#selected","#expanded","#page","#orderStore","#filterStore","#clamp","#rowStore","#settle","#filtered","#destroyed"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/cloners.ts","../../../src/core/parsers.ts","../../../src/core/tables/KeyManager.ts","../../../src/core/tables/ExpansionManager.ts","../../../src/core/tables/FilterManager.ts","../../../src/core/tables/PaginationManager.ts","../../../src/core/tables/RowManager.ts","../../../src/core/tables/SelectionManager.ts","../../../src/core/tables/SortManager.ts","../../../src/core/Table.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { ColumnCell } from './types.js'\n\n/** Lists every column cell, in the order declared by the public contract. */\nexport const COLUMN_CELLS: readonly ColumnCell[] = Object.freeze([\n\t'text',\n\t'number',\n\t'flag',\n\t'choice',\n])\n\n/** Names the maximum number of columns one schema may declare. */\nexport const COLUMN_LIMIT = 256\n\n/** Names the maximum number of choices one `choice` column may offer. */\nexport const CHOICE_LIMIT = 1024\n\n/** Names the maximum length, in UTF-16 code units, of a schema name or column key. */\nexport const NAME_LIMIT = 128\n\n/** Names the maximum length, in UTF-16 code units, of any single retained string. */\nexport const STRING_LIMIT = 65536\n\n/** Names the maximum total length, in UTF-16 code units, of every string one schema retains. */\nexport const TEXT_LIMIT = 1048576\n\n/** Names the maximum total number of records, arrays, and leaves one schema retains. */\nexport const NODE_LIMIT = 16384\n","import type { JSONRecord } from '@orkestrel/contract'\nimport type { TableErrorCode } from './types.js'\n\n/** Represents an error raised by the table domain. */\nexport class TableError extends Error {\n\t/** Holds the machine-readable reason for this failure. */\n\treadonly code: TableErrorCode\n\n\t/** Holds structured values that locate or explain this failure. */\n\treadonly context?: JSONRecord\n\n\t/**\n\t * Creates a table error.\n\t *\n\t * @param code - The machine-readable reason.\n\t * @param message - The human-readable failure text.\n\t * @param context - Optional structured failure details.\n\t */\n\tconstructor(code: TableErrorCode, message: string, context?: JSONRecord) {\n\t\tsuper(message)\n\t\tthis.name = 'TableError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Determines whether an unknown value is a table error.\n *\n * @param input - The value to inspect.\n * @returns True if the value is a {@link TableError} instance; false otherwise.\n */\nexport function isTableError(input: unknown): input is TableError {\n\treturn input instanceof TableError\n}\n","import type { JSONPrimitive, JSONRecord, JSONValue } from '@orkestrel/contract'\nimport type {\n\tCellComparator,\n\tCellMatcher,\n\tTableCell,\n\tTableColumn,\n\tTableFilter,\n\tTableKey,\n\tTableOrder,\n\tTableRow,\n\tTableSchema,\n\tTableTerm,\n} from './types.js'\nimport {\n\tattempt,\n\tcloneJSONRecord,\n\tisArray,\n\tisBoolean,\n\tisContractError,\n\tisFiniteNumber,\n\tisRecord,\n\tisString,\n\treadArrayEntries,\n} from '@orkestrel/contract'\nimport {\n\tCHOICE_LIMIT,\n\tCOLUMN_LIMIT,\n\tNAME_LIMIT,\n\tNODE_LIMIT,\n\tSTRING_LIMIT,\n\tTEXT_LIMIT,\n} from './constants.js'\nimport { TableError } from './errors.js'\n\n/**\n * Finds one column by key.\n *\n * @param schema - The schema whose columns to search.\n * @param key - The column key to find.\n * @returns The declared column, or `undefined` when no column has that key.\n */\nexport function extractColumn(schema: TableSchema, key: string): TableColumn | undefined {\n\treturn schema.columns.find((column) => column.key === key)\n}\n\n/**\n * Reads one row's declared identity.\n *\n * @param schema - The schema that names the identity column.\n * @param row - The row whose identity to read.\n * @returns The non-empty string identity, or `undefined` when it is unusable.\n */\nexport function extractKey(schema: TableSchema, row: TableRow): TableKey | undefined {\n\tif (!Object.hasOwn(row, schema.key)) return undefined\n\tconst key = row[schema.key]\n\treturn isString(key) && key.length > 0 ? key : undefined\n}\n\n/**\n * Computes one atomic 0/1/N membership change over known keys.\n *\n * @param known - Every key the caller may change.\n * @param current - The current key set.\n * @param input - Every known key, one key, or a key list.\n * @param include - Decide the next membership from each key's membership at that step.\n * @returns `undefined` when any requested key is unknown, the current set for a no-op, or the next\n * set when membership changes.\n */\nexport function computeKeys(\n\tknown: readonly TableKey[],\n\tcurrent: ReadonlySet<TableKey>,\n\tinput: TableKey | readonly TableKey[] | undefined,\n\tinclude: (included: boolean) => boolean,\n): ReadonlySet<TableKey> | undefined {\n\tconst requested = input === undefined ? known : Array.isArray(input) ? input : [input]\n\tconst population = new Set(known)\n\tif (requested.some((key) => !population.has(key))) return undefined\n\n\tconst next = new Set(current)\n\tfor (const key of requested) {\n\t\tif (include(next.has(key))) next.add(key)\n\t\telse next.delete(key)\n\t}\n\n\tconst changed = next.size !== current.size || [...next].some((key) => !current.has(key))\n\treturn changed ? next : current\n}\n\n/**\n * Merges lens terms into a column-keyed list, replacing the entry that names the same column.\n *\n * @param current - The list as it stands.\n * @param requested - The terms to write, in the order they are written.\n * @returns A frozen list holding one owned entry per column, in the order the columns first\n * appeared.\n */\nexport function mergeTerms<Term extends TableTerm>(\n\tcurrent: readonly Term[],\n\trequested: readonly Term[],\n): readonly Term[] {\n\tconst next = [...current]\n\tfor (const term of requested) {\n\t\tconst owned = Object.freeze({ ...term })\n\t\tconst index = next.findIndex((candidate) => candidate.column === term.column)\n\t\tif (index === -1) next.push(owned)\n\t\telse next[index] = owned\n\t}\n\n\treturn Object.freeze(next)\n}\n\n/**\n * Removes every lens term naming one of the given columns.\n *\n * @param current - The list as it stands.\n * @param columns - The column keys to drop.\n * @returns A frozen list holding the entries no named column matched, in their original order.\n */\nexport function removeTerms<Term extends TableTerm>(\n\tcurrent: readonly Term[],\n\tcolumns: readonly string[],\n): readonly Term[] {\n\tconst removed = new Set(columns)\n\treturn Object.freeze(current.filter((term) => !removed.has(term.column)))\n}\n\n/**\n * Checks whether two lens lists hold the same terms in the same order.\n *\n * @param left - The first list.\n * @param right - The second list.\n * @param equal - Decide whether two terms naming one column carry the same operands.\n * @returns True if the lists are the same length and every position names the same column and\n * carries the same operands; false otherwise.\n */\nexport function matchesTerms<Term extends TableTerm>(\n\tleft: readonly Term[],\n\tright: readonly Term[],\n\tequal: (left: Term, right: Term) => boolean,\n): boolean {\n\treturn (\n\t\tleft.length === right.length &&\n\t\tleft.every((term, index) => {\n\t\t\tconst other = right[index]\n\t\t\treturn other !== undefined && term.column === other.column && equal(term, other)\n\t\t})\n\t)\n}\n\n/**\n * Checks whether a value has the shape required by one column cell.\n *\n * @param column - The column that owns the cell.\n * @param value - The unknown value to inspect.\n * @returns True if the column can hold the value; false otherwise.\n */\nexport function matchesCell(column: TableColumn, value: unknown): value is TableCell {\n\tif (isString(value) && value.length > STRING_LIMIT) return false\n\n\tswitch (column.cell) {\n\t\tcase 'text':\n\t\t\treturn isString(value)\n\t\tcase 'number':\n\t\t\treturn isFiniteNumber(value)\n\t\tcase 'flag':\n\t\t\treturn isBoolean(value)\n\t\tcase 'choice':\n\t\t\treturn isString(value) && column.choices.some((choice) => choice.value === value)\n\t}\n}\n\n/**\n * Compares two cells in ascending order according to one column.\n *\n * @param column - The column that fixes the comparison.\n * @param left - The first cell, or absence.\n * @param right - The second cell, or absence.\n * @returns A negative number, positive number, or zero in sort-comparator form.\n */\nexport function compareCells(\n\tcolumn: TableColumn,\n\tleft: TableCell | undefined,\n\tright: TableCell | undefined,\n): number {\n\tif (left === undefined) return right === undefined ? 0 : -1\n\tif (right === undefined) return 1\n\n\tswitch (column.cell) {\n\t\tcase 'text':\n\t\t\tif (!isString(left) || !isString(right)) return 0\n\t\t\treturn left < right ? -1 : left > right ? 1 : 0\n\t\tcase 'number':\n\t\t\tif (!isFiniteNumber(left) || !isFiniteNumber(right)) return 0\n\t\t\treturn left - right\n\t\tcase 'flag':\n\t\t\tif (!isBoolean(left) || !isBoolean(right)) return 0\n\t\t\treturn left === right ? 0 : left ? 1 : -1\n\t\tcase 'choice': {\n\t\t\tif (!isString(left) || !isString(right)) return 0\n\t\t\tconst leftIndex = column.choices.findIndex((choice) => choice.value === left)\n\t\t\tconst rightIndex = column.choices.findIndex((choice) => choice.value === right)\n\t\t\treturn leftIndex - rightIndex\n\t\t}\n\t}\n}\n\n/**\n * Checks whether one column admits a filter and all its operands.\n *\n * @param column - The column that fixes the accepted operators and cell shapes.\n * @param filter - The filter to inspect.\n * @returns True if the filter belongs to the column and the column can apply it; false otherwise.\n */\nexport function admitsFilter(column: TableColumn, filter: TableFilter): boolean {\n\tif (filter.column !== column.key) return false\n\n\tswitch (filter.operator) {\n\t\tcase 'contains':\n\t\t\treturn (\n\t\t\t\t(column.cell === 'text' || column.cell === 'choice') && filter.text.length <= STRING_LIMIT\n\t\t\t)\n\t\tcase 'between':\n\t\t\treturn (\n\t\t\t\t(column.cell === 'text' || column.cell === 'number') &&\n\t\t\t\tmatchesCell(column, filter.minimum) &&\n\t\t\t\tmatchesCell(column, filter.maximum)\n\t\t\t)\n\t\tcase 'equals':\n\t\t\treturn matchesCell(column, filter.value)\n\t}\n}\n\n/**\n * Tests one cell against a filter according to its column.\n *\n * @param column - The column that fixes the accepted operators.\n * @param cell - The cell to test, or absence.\n * @param filter - The filter to apply.\n * @returns True if the filter accepts the cell; false otherwise.\n */\nexport function matchesFilter(\n\tcolumn: TableColumn,\n\tcell: TableCell | undefined,\n\tfilter: TableFilter,\n): boolean {\n\tif (cell === undefined || !admitsFilter(column, filter) || !matchesCell(column, cell))\n\t\treturn false\n\n\tswitch (filter.operator) {\n\t\tcase 'contains':\n\t\t\treturn isString(cell) && cell.includes(filter.text)\n\t\tcase 'between':\n\t\t\treturn (\n\t\t\t\tcompareCells(column, cell, filter.minimum) >= 0 &&\n\t\t\t\tcompareCells(column, cell, filter.maximum) <= 0\n\t\t\t)\n\t\tcase 'equals':\n\t\t\treturn cell === filter.value\n\t}\n}\n\n/**\n * Keeps the rows accepted by every filter.\n *\n * @param schema - The schema that declares the filtered columns.\n * @param rows - The rows to filter.\n * @param filters - The filters to apply with and-only composition.\n * @param matchers - Optional per-column replacements for the default matcher.\n * @returns A frozen copy of the accepted rows in their original order.\n */\nexport function filterRows(\n\tschema: TableSchema,\n\trows: readonly TableRow[],\n\tfilters: readonly TableFilter[],\n\tmatchers?: Readonly<Record<string, CellMatcher>>,\n): readonly TableRow[] {\n\treturn Object.freeze(\n\t\trows.filter((row) =>\n\t\t\tfilters.every((filter) => {\n\t\t\t\tconst column = extractColumn(schema, filter.column)\n\t\t\t\tif (column === undefined) return false\n\t\t\t\tconst matcher =\n\t\t\t\t\tmatchers !== undefined && Object.hasOwn(matchers, column.key)\n\t\t\t\t\t\t? matchers[column.key]\n\t\t\t\t\t\t: undefined\n\t\t\t\tconst cell = Object.hasOwn(row, column.key) ? row[column.key] : undefined\n\t\t\t\treturn matcher === undefined ? matchesFilter(column, cell, filter) : matcher(cell, filter)\n\t\t\t}),\n\t\t),\n\t)\n}\n\n/**\n * Orders rows stably by a sequence of terms.\n *\n * @param schema - The schema that declares the sorted columns.\n * @param rows - The rows to order.\n * @param orders - The ordered sort terms.\n * @param comparators - Optional per-column replacements for the default comparator.\n * @returns A frozen sorted copy that leaves the input untouched.\n */\nexport function sortRows(\n\tschema: TableSchema,\n\trows: readonly TableRow[],\n\torders: readonly TableOrder[],\n\tcomparators?: Readonly<Record<string, CellComparator>>,\n): readonly TableRow[] {\n\tconst indexed = rows.map((row, index) => ({ row, index }))\n\n\tindexed.sort((left, right) => {\n\t\tfor (const order of orders) {\n\t\t\tconst column = extractColumn(schema, order.column)\n\t\t\tif (column === undefined) continue\n\t\t\tconst comparator =\n\t\t\t\tcomparators !== undefined && Object.hasOwn(comparators, column.key)\n\t\t\t\t\t? comparators[column.key]\n\t\t\t\t\t: undefined\n\t\t\tconst leftCell = Object.hasOwn(left.row, column.key) ? left.row[column.key] : undefined\n\t\t\tconst rightCell = Object.hasOwn(right.row, column.key) ? right.row[column.key] : undefined\n\t\t\tconst compared =\n\t\t\t\tcomparator === undefined\n\t\t\t\t\t? compareCells(column, leftCell, rightCell)\n\t\t\t\t\t: comparator(leftCell, rightCell)\n\t\t\tif (compared !== 0 && !Number.isNaN(compared)) {\n\t\t\t\treturn order.direction === 'ascending' ? compared : -compared\n\t\t\t}\n\t\t}\n\n\t\treturn left.index - right.index\n\t})\n\n\treturn Object.freeze(indexed.map((entry) => entry.row))\n}\n\n/**\n * Audits a structurally valid schema for domain and budget faults.\n *\n * @param schema - The table schema to audit.\n * @returns Frozen human-readable diagnostics, or an empty list when the schema is sound.\n */\nexport function auditTable(schema: TableSchema): readonly string[] {\n\tconst faults: string[] = []\n\tconst columns = new Set<string>()\n\tlet choiceExceeded: string | undefined\n\tlet nameExceeded = schema.name !== undefined && schema.name.length > NAME_LIMIT\n\n\tif (schema.columns.length > COLUMN_LIMIT) {\n\t\tfaults.push(`schema declares more than ${COLUMN_LIMIT} columns`)\n\t}\n\n\tconst columnCount = Math.min(schema.columns.length, COLUMN_LIMIT + 1)\n\tfor (let index = 0; index < columnCount; index += 1) {\n\t\tconst column = schema.columns[index]\n\t\tif (column === undefined) continue\n\t\tif (column.key.length > NAME_LIMIT) nameExceeded = true\n\t\tif (\n\t\t\tchoiceExceeded === undefined &&\n\t\t\tcolumn.cell === 'choice' &&\n\t\t\tcolumn.choices.length > CHOICE_LIMIT\n\t\t) {\n\t\t\tchoiceExceeded = column.key\n\t\t}\n\t}\n\n\tif (choiceExceeded !== undefined) {\n\t\tfaults.push(`column \"${choiceExceeded}\" offers more than ${CHOICE_LIMIT} choices`)\n\t}\n\tif (nameExceeded) faults.push(`schema contains a name longer than ${NAME_LIMIT}`)\n\n\tconst pending: unknown[] = [schema]\n\tconst metadata: boolean[] = [false]\n\tlet position = 0\n\tlet stringExceeded = false\n\tlet textExceeded = false\n\tlet nodeExceeded = false\n\tlet text = 0\n\n\twhile (position < pending.length) {\n\t\tconst node = pending[position]\n\t\tconst inMeta = metadata[position] === true\n\t\tposition += 1\n\n\t\tif (isString(node)) {\n\t\t\tif (node.length > STRING_LIMIT) stringExceeded = true\n\t\t\ttext = Math.min(TEXT_LIMIT + 1, text + node.length)\n\t\t\tif (text > TEXT_LIMIT) textExceeded = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isArray(node)) {\n\t\t\tconst read = readArrayEntries(node)\n\t\t\tif (!read.success || !read.value.dense) continue\n\t\t\tfor (const entry of read.value.entries) {\n\t\t\t\tif (pending.length >= NODE_LIMIT) {\n\t\t\t\t\tnodeExceeded = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tpending.push(entry)\n\t\t\t\tmetadata.push(inMeta)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif (!isRecord(node)) continue\n\t\tconst keys = attempt(() => Object.keys(node))\n\t\tif (!keys.success) continue\n\n\t\tfor (const key of keys.value) {\n\t\t\tif (inMeta) {\n\t\t\t\tif (key.length > STRING_LIMIT) stringExceeded = true\n\t\t\t\ttext = Math.min(TEXT_LIMIT + 1, text + key.length)\n\t\t\t\tif (text > TEXT_LIMIT) textExceeded = true\n\t\t\t}\n\n\t\t\tconst value = attempt(() => node[key])\n\t\t\tif (!value.success || value.value === undefined) continue\n\t\t\tif (pending.length >= NODE_LIMIT) {\n\t\t\t\tnodeExceeded = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpending.push(value.value)\n\t\t\tmetadata.push(inMeta || key === 'meta')\n\t\t}\n\t}\n\n\tif (stringExceeded) faults.push(`schema contains a string longer than ${STRING_LIMIT}`)\n\tif (textExceeded) faults.push(`schema retains more than ${TEXT_LIMIT} string code units`)\n\tif (nodeExceeded) faults.push(`schema retains more than ${NODE_LIMIT} nodes`)\n\n\tfor (let index = 0; index < columnCount; index += 1) {\n\t\tconst column = schema.columns[index]\n\t\tif (column === undefined) continue\n\t\tif (!nodeExceeded && column.meta !== undefined) {\n\t\t\tconst owned = attempt(() => cloneJSONRecord(column.meta))\n\t\t\tif (!owned.success) {\n\t\t\t\tfaults.push(`column \"${column.key}\" has metadata that cannot be owned`)\n\t\t\t}\n\t\t}\n\t\tif (column.key.length === 0) faults.push('column \"\" has an empty key')\n\t\tif (columns.has(column.key)) {\n\t\t\tfaults.push(`column \"${column.key}\" is declared more than once`)\n\t\t}\n\t\tcolumns.add(column.key)\n\n\t\tif (column.cell === 'choice') {\n\t\t\tconst choices = new Set<string>()\n\t\t\tconst choiceCount = Math.min(column.choices.length, CHOICE_LIMIT + 1)\n\t\t\tfor (let choiceIndex = 0; choiceIndex < choiceCount; choiceIndex += 1) {\n\t\t\t\tconst choice = column.choices[choiceIndex]\n\t\t\t\tif (choice === undefined) continue\n\t\t\t\tif (choices.has(choice.value)) {\n\t\t\t\t\tfaults.push(`column \"${column.key}\" offers choice \"${choice.value}\" more than once`)\n\t\t\t\t}\n\t\t\t\tchoices.add(choice.value)\n\t\t\t}\n\t\t\tif (column.choices.length === 0) {\n\t\t\t\tfaults.push(`column \"${column.key}\" offers no choices`)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst key = extractColumn(schema, schema.key)\n\tif (key === undefined) {\n\t\tfaults.push(`schema key \"${schema.key}\" names no declared column`)\n\t} else if (key.cell === 'number' || key.cell === 'flag') {\n\t\tfaults.push(`schema key \"${schema.key}\" names a ${key.cell} column, which holds no identity`)\n\t}\n\n\treturn Object.freeze(faults)\n}\n\n/**\n * Projects a schema into declaration-ordered JSON.\n *\n * @param schema - The schema to project.\n * @returns A deeply owned JSON record with absent members omitted.\n * @throws A {@link TableError} coded `SCHEMA` when metadata cannot be owned.\n */\nexport function serializeTable(schema: TableSchema): JSONRecord {\n\tconst output: Record<string, JSONValue> = {}\n\tif (schema.name !== undefined) output.name = schema.name\n\tif (schema.label !== undefined) output.label = schema.label\n\tif (schema.help !== undefined) output.help = schema.help\n\toutput.key = schema.key\n\toutput.columns = schema.columns.map((column): JSONRecord => {\n\t\tconst entry: Record<string, JSONValue> = { cell: column.cell, key: column.key }\n\t\tif (column.label !== undefined) entry.label = column.label\n\t\tif (column.help !== undefined) entry.help = column.help\n\t\tif (column.hidden !== undefined) entry.hidden = column.hidden\n\t\tif (column.meta !== undefined) entry.meta = column.meta\n\t\tif (column.cell === 'choice') {\n\t\t\tentry.choices = column.choices.map((choice): JSONRecord => {\n\t\t\t\tconst option: Record<string, JSONValue> = {\n\t\t\t\t\tvalue: choice.value,\n\t\t\t\t\tlabel: choice.label,\n\t\t\t\t}\n\t\t\t\tif (choice.help !== undefined) option.help = choice.help\n\t\t\t\treturn option\n\t\t\t})\n\t\t}\n\t\treturn entry\n\t})\n\n\ttry {\n\t\treturn cloneJSONRecord(output)\n\t} catch (error) {\n\t\tif (!isContractError(error)) throw error\n\t\tthrow new TableError('SCHEMA', 'schema contains metadata that cannot be owned')\n\t}\n}\n\n/**\n * Projects rows into schema-column-ordered JSON.\n *\n * @param schema - The schema that fixes cell order.\n * @param rows - The rows to project.\n * @returns A frozen list of owned JSON records with absent cells omitted.\n */\nexport function serializeRows(\n\tschema: TableSchema,\n\trows: readonly TableRow[],\n): readonly JSONRecord[] {\n\tconst output: JSONRecord[] = []\n\n\tfor (const row of rows) {\n\t\tconst entry: Record<string, JSONPrimitive> = {}\n\t\tfor (const column of schema.columns) {\n\t\t\tif (!Object.hasOwn(row, column.key)) continue\n\t\t\tconst value = row[column.key]\n\t\t\tif (value === undefined) continue\n\t\t\tObject.defineProperty(entry, column.key, {\n\t\t\t\tvalue,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t\twritable: true,\n\t\t\t})\n\t\t}\n\t\toutput.push(cloneJSONRecord(entry))\n\t}\n\n\treturn Object.freeze(output)\n}\n","import type {\n\tColumnCell,\n\tColumnChoice,\n\tTableCell,\n\tTableColumn,\n\tTableRow,\n\tTableSchema,\n} from './types.js'\nimport {\n\tarrayOf,\n\tattempt,\n\tcloneJSONRecord,\n\tisBoolean,\n\tisBoundedJSONRecord,\n\tisFiniteNumber,\n\tisRecord,\n\tisString,\n\trecordOf,\n\tunionOf,\n} from '@orkestrel/contract'\nimport { COLUMN_CELLS } from './constants.js'\nimport { auditTable } from './helpers.js'\n\n/**\n * Determines whether an unknown value has a table cell shape.\n *\n * @param input - The value to inspect.\n * @returns True if the value is a string, finite number, or boolean; false otherwise.\n */\nexport function isTableCell(input: unknown): input is TableCell {\n\treturn unionOf(isString, isFiniteNumber, isBoolean)(input)\n}\n\n/**\n * Determines whether an unknown value is a record of table cells.\n *\n * @param input - The value to inspect.\n * @returns True if every own key is a string and every value is a table cell; false otherwise.\n */\nexport function isTableRow(input: unknown): input is TableRow {\n\tconst outcome = attempt(() => {\n\t\tif (!isRecord(input)) return false\n\t\treturn Reflect.ownKeys(input).every(\n\t\t\t(key) => isString(key) && Object.hasOwn(input, key) && isTableCell(input[key]),\n\t\t)\n\t})\n\n\treturn outcome.success && outcome.value\n}\n\n/**\n * Determines whether an unknown value is a declared column cell.\n *\n * @param input - The value to inspect.\n * @returns True if the value is a declared column cell; false otherwise.\n */\nexport function isColumnCell(input: unknown): input is ColumnCell {\n\treturn COLUMN_CELLS.some((cell) => cell === input)\n}\n\n/**\n * Determines whether an unknown value is one exact column choice record.\n *\n * @param input - The value to inspect.\n * @returns True if the value is a column choice; false otherwise.\n */\nexport function isColumnChoice(input: unknown): input is ColumnChoice {\n\tconst outcome = attempt(() => {\n\t\tif (!isRecord(input) || !Reflect.ownKeys(input).every((key) => isString(key))) return false\n\t\treturn recordOf({ value: isString, label: isString, help: isString }, ['help'])(input)\n\t})\n\n\treturn outcome.success && outcome.value\n}\n\n/**\n * Determines whether an unknown value is one exact discriminated table column.\n *\n * @param input - The value to inspect.\n * @returns True if the value is a structurally valid table column; false otherwise.\n */\nexport function isTableColumn(input: unknown): input is TableColumn {\n\tconst outcome = attempt(() => {\n\t\tif (!isRecord(input) || !Object.hasOwn(input, 'cell') || !Object.hasOwn(input, 'key')) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst cell = input.cell\n\t\tif (!isColumnCell(cell)) return false\n\n\t\tconst exact = Reflect.ownKeys(input).every((key) => {\n\t\t\tif (!isString(key)) return false\n\t\t\tif (['cell', 'key', 'label', 'help', 'hidden', 'meta'].includes(key)) return true\n\t\t\treturn cell === 'choice' && key === 'choices'\n\t\t})\n\t\tif (!exact) return false\n\n\t\tconst key = input.key\n\t\tconst hasLabel = Object.hasOwn(input, 'label')\n\t\tconst label = hasLabel ? input.label : undefined\n\t\tconst hasHelp = Object.hasOwn(input, 'help')\n\t\tconst help = hasHelp ? input.help : undefined\n\t\tconst hasHidden = Object.hasOwn(input, 'hidden')\n\t\tconst hidden = hasHidden ? input.hidden : undefined\n\t\tconst hasMeta = Object.hasOwn(input, 'meta')\n\t\tconst meta = hasMeta ? input.meta : undefined\n\t\tif (hasMeta) {\n\t\t\tif (!isBoundedJSONRecord(meta)) return false\n\t\t\tconst owned = attempt(() => cloneJSONRecord(meta))\n\t\t\tif (!owned.success) return false\n\t\t}\n\n\t\tif (\n\t\t\t!isString(key) ||\n\t\t\t(hasLabel && !isString(label)) ||\n\t\t\t(hasHelp && !isString(help)) ||\n\t\t\t(hasHidden && !isBoolean(hidden))\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (cell !== 'choice') return !Object.hasOwn(input, 'choices')\n\t\treturn Object.hasOwn(input, 'choices') && arrayOf(isColumnChoice)(input.choices)\n\t})\n\n\treturn outcome.success && outcome.value\n}\n\n/**\n * Determines whether an unknown value has one exact structural table-schema shape.\n *\n * @param input - The value to inspect.\n * @returns True if the value has the exact structure of a table schema; false otherwise.\n */\nexport function isStructuralTableSchema(input: unknown): input is TableSchema {\n\tconst outcome = attempt(() => {\n\t\tif (!isRecord(input) || !Reflect.ownKeys(input).every((key) => isString(key))) return false\n\t\treturn recordOf(\n\t\t\t{\n\t\t\t\tname: isString,\n\t\t\t\tlabel: isString,\n\t\t\t\thelp: isString,\n\t\t\t\tkey: isString,\n\t\t\t\tcolumns: arrayOf(isTableColumn),\n\t\t\t},\n\t\t\t['name', 'label', 'help'],\n\t\t)(input)\n\t})\n\n\treturn outcome.success && outcome.value\n}\n\n/**\n * Determines whether an unknown value is one semantically sound table schema.\n *\n * @param input - The value to inspect.\n * @returns True if the value has valid structure, domain relationships, and\n * budgets; false otherwise.\n */\nexport function isTableSchema(input: unknown): input is TableSchema {\n\tconst outcome = attempt(() => isStructuralTableSchema(input) && auditTable(input).length === 0)\n\treturn outcome.success && outcome.value\n}\n","import type { JSONRecord } from '@orkestrel/contract'\nimport type { TableRow, TableSchema } from './types.js'\nimport { cloneJSONRecord, isContractError } from '@orkestrel/contract'\nimport { TableError } from './errors.js'\n\n/**\n * Clones one row into an owned frozen snapshot.\n *\n * @param row - The row to own.\n * @returns A frozen copy of the row's cells.\n */\nexport function cloneRow(row: TableRow): TableRow {\n\treturn Object.freeze({ ...row })\n}\n\n/**\n * Clones a table schema into an owned frozen snapshot.\n *\n * @param schema - The schema to own.\n * @returns A frozen schema with every nested column, choice, list, and metadata record owned.\n */\nexport function cloneSchema(schema: TableSchema): TableSchema {\n\treturn Object.freeze({\n\t\t...schema,\n\t\tcolumns: Object.freeze(\n\t\t\tschema.columns.map((column) => {\n\t\t\t\tlet meta: { meta?: JSONRecord } = {}\n\n\t\t\t\tif (column.meta !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmeta = { meta: cloneJSONRecord(column.meta) }\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (!isContractError(error)) throw error\n\t\t\t\t\t\tthrow new TableError(\n\t\t\t\t\t\t\t'SCHEMA',\n\t\t\t\t\t\t\t`column \"${column.key}\" has metadata that cannot be owned`,\n\t\t\t\t\t\t\t{ column: column.key },\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (column.cell === 'choice') {\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t...column,\n\t\t\t\t\t\t...meta,\n\t\t\t\t\t\tchoices: Object.freeze(column.choices.map((choice) => Object.freeze({ ...choice }))),\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn Object.freeze({ ...column, ...meta })\n\t\t\t}),\n\t\t),\n\t})\n}\n","import type { TableCell, TableRow, TableSchema } from './types.js'\nimport {\n\tattempt,\n\tisArray,\n\tisRecord,\n\tisString,\n\tparseNumber,\n\treadArrayEntries,\n} from '@orkestrel/contract'\nimport { cloneRow } from './cloners.js'\nimport { STRING_LIMIT } from './constants.js'\nimport { extractColumn, extractKey, matchesCell, serializeTable } from './helpers.js'\nimport { isTableSchema } from './validators.js'\n\n/**\n * Parses unknown wire data into an owned, semantically sound table schema.\n *\n * @param input - The unknown schema value to parse.\n * @returns An owned table schema, or `undefined` on refusal.\n */\nexport function parseTable(input: unknown): TableSchema | undefined {\n\tconst outcome = attempt(() => {\n\t\tif (!isTableSchema(input)) return undefined\n\t\tconst projected = serializeTable(input)\n\t\treturn isTableSchema(projected) ? projected : undefined\n\t})\n\n\treturn outcome.success ? outcome.value : undefined\n}\n\n/**\n * Parses unknown wire rows against one table schema.\n *\n * @param schema - The schema that declares the accepted keys and cell shapes.\n * @param input - The unknown row-list value to parse.\n * @returns Frozen owned rows, or `undefined` when any row is refused.\n */\nexport function parseRows(schema: TableSchema, input: unknown): readonly TableRow[] | undefined {\n\tconst outcome = attempt(() => {\n\t\tif (!isTableSchema(schema) || !isArray(input)) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst read = readArrayEntries(input)\n\t\tif (!read.success || !read.value.dense) return undefined\n\n\t\tconst keys = new Set<string>()\n\t\tconst rows: TableRow[] = []\n\n\t\tfor (const candidate of read.value.entries) {\n\t\t\tif (!isRecord(candidate)) return undefined\n\t\t\tconst row: Record<string, TableCell> = {}\n\n\t\t\tfor (const key of Reflect.ownKeys(candidate)) {\n\t\t\t\tif (!isString(key) || !Object.hasOwn(candidate, key)) return undefined\n\t\t\t\tconst column = extractColumn(schema, key)\n\t\t\t\tif (column === undefined) return undefined\n\t\t\t\tconst inputCell = candidate[key]\n\t\t\t\tlet cell: unknown = inputCell\n\n\t\t\t\tif (column.cell === 'number' && isString(inputCell)) {\n\t\t\t\t\tif (inputCell.length > STRING_LIMIT) return undefined\n\t\t\t\t\tcell = parseNumber(inputCell)\n\t\t\t\t} else if (column.cell === 'flag' && inputCell === 'true') {\n\t\t\t\t\tcell = true\n\t\t\t\t} else if (column.cell === 'flag' && inputCell === 'false') {\n\t\t\t\t\tcell = false\n\t\t\t\t}\n\n\t\t\t\tif (!matchesCell(column, cell)) return undefined\n\t\t\t\tObject.defineProperty(row, key, {\n\t\t\t\t\tvalue: cell,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst owned = cloneRow(row)\n\t\t\tconst key = extractKey(schema, owned)\n\t\t\tif (key === undefined || keys.has(key)) return undefined\n\t\t\tkeys.add(key)\n\t\t\trows.push(owned)\n\t\t}\n\n\t\treturn Object.freeze(rows)\n\t})\n\n\treturn outcome.success ? outcome.value : undefined\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { TableEventMap, TableKey } from '../types.js'\nimport { computeKeys } from '../helpers.js'\n\n/** Manages the key set one table axis holds, and the event it announces when that set moves. */\nexport class KeyManager {\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #event: 'select' | 'expand'\n\treadonly #gate: () => void\n\treadonly #rows: () => readonly TableKey[]\n\treadonly #read: () => ReadonlySet<TableKey>\n\treadonly #write: (keys: ReadonlySet<TableKey>) => void\n\n\t/**\n\t * Creates a key-set shell over one table's private store.\n\t *\n\t * @param emitter - The table's event emitter.\n\t * @param event - The event this axis announces when its key set moves.\n\t * @param gate - The table lifecycle gate.\n\t * @param rows - A read of every row key.\n\t * @param read - A read of the held keys.\n\t * @param write - The held-key commit boundary.\n\t */\n\tconstructor(\n\t\temitter: Emitter<TableEventMap>,\n\t\tevent: 'select' | 'expand',\n\t\tgate: () => void,\n\t\trows: () => readonly TableKey[],\n\t\tread: () => ReadonlySet<TableKey>,\n\t\twrite: (keys: ReadonlySet<TableKey>) => void,\n\t) {\n\t\tthis.#emitter = emitter\n\t\tthis.#event = event\n\t\tthis.#gate = gate\n\t\tthis.#rows = rows\n\t\tthis.#read = read\n\t\tthis.#write = write\n\t}\n\n\t/** Returns the keys held right now. */\n\tget keys(): ReadonlySet<TableKey> {\n\t\treturn new Set(this.#read())\n\t}\n\n\t/**\n\t * Applies one atomic 0/1/N membership change, announcing it only when the set moves.\n\t *\n\t * @param input - Every known key, one key, or a key list.\n\t * @param include - Decides the next membership from each key's membership at that step.\n\t * @returns `undefined` for the no-argument form, `false` when any requested key names no row\n\t * the table holds, and `true` otherwise.\n\t */\n\tchange(\n\t\tinput: TableKey | readonly TableKey[] | undefined,\n\t\tinclude: (included: boolean) => boolean,\n\t): void | boolean {\n\t\tthis.#gate()\n\t\tconst previous = this.#read()\n\t\tconst next = computeKeys(this.#rows(), previous, input, include)\n\t\tif (next === undefined) return false\n\t\tif (next !== previous) {\n\t\t\tthis.#write(next)\n\t\t\tthis.#emitter.emit(this.#event, new Set(next))\n\t\t}\n\n\t\treturn input === undefined ? undefined : true\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { ExpansionManagerInterface, TableEventMap, TableKey } from '../types.js'\nimport { KeyManager } from './KeyManager.js'\n\n/** Manages the keys of the rows somebody has opened. */\nexport class ExpansionManager implements ExpansionManagerInterface {\n\treadonly #keys: KeyManager\n\n\t/**\n\t * Creates an expansion manager over one table's private stores.\n\t *\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param rows - A read of every row key.\n\t * @param read - A read of the expanded keys.\n\t * @param write - The expanded-key commit boundary.\n\t */\n\tconstructor(\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\trows: () => readonly TableKey[],\n\t\tread: () => ReadonlySet<TableKey>,\n\t\twrite: (keys: ReadonlySet<TableKey>) => void,\n\t) {\n\t\tthis.#keys = new KeyManager(emitter, 'expand', gate, rows, read, write)\n\t}\n\n\t/** Returns the keys of the rows opened right now. */\n\tget keys(): ReadonlySet<TableKey> {\n\t\treturn this.#keys.keys\n\t}\n\n\t/** Opens every row the table holds. */\n\texpand(): void\n\t/** Opens one row. */\n\texpand(key: TableKey): boolean\n\t/** Opens several rows. */\n\texpand(keys: readonly TableKey[]): boolean\n\t/** Opens one or more rows. */\n\texpand(input?: TableKey | readonly TableKey[]): void | boolean {\n\t\treturn this.#keys.change(input, () => true)\n\t}\n\n\t/** Closes every row. */\n\tclear(): void\n\t/** Closes one row. */\n\tclear(key: TableKey): boolean\n\t/** Closes several rows. */\n\tclear(keys: readonly TableKey[]): boolean\n\t/** Closes one or more rows. */\n\tclear(input?: TableKey | readonly TableKey[]): void | boolean {\n\t\treturn this.#keys.change(input, () => false)\n\t}\n\n\t/** Opens one row or closes it when already open. */\n\ttoggle(key: TableKey): boolean\n\t/** Turns several rows around independently. */\n\ttoggle(keys: readonly TableKey[]): boolean\n\t/** Turns one or more rows around independently. */\n\ttoggle(input: TableKey | readonly TableKey[]): boolean {\n\t\treturn this.#keys.change(input, (included) => !included) === true\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { FilterManagerInterface, TableEventMap, TableFilter, TableSchema } from '../types.js'\nimport { TableError } from '../errors.js'\nimport { admitsFilter, extractColumn, matchesTerms, mergeTerms, removeTerms } from '../helpers.js'\n\n/** Manages the filters one table applies with and-only composition. */\nexport class FilterManager implements FilterManagerInterface {\n\treadonly #schema: TableSchema\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #gate: () => void\n\treadonly #read: () => readonly TableFilter[]\n\treadonly #write: (filters: readonly TableFilter[]) => void\n\treadonly #clamp: () => number | undefined\n\n\t/**\n\t * Creates a filter manager over one table's private filter store.\n\t *\n\t * @param schema - The table schema.\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param read - A read of the current filters.\n\t * @param write - The filter commit boundary.\n\t * @param clamp - The pagination clamp commit after a filter commit.\n\t */\n\tconstructor(\n\t\tschema: TableSchema,\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\tread: () => readonly TableFilter[],\n\t\twrite: (filters: readonly TableFilter[]) => void,\n\t\tclamp: () => number | undefined,\n\t) {\n\t\tthis.#schema = schema\n\t\tthis.#emitter = emitter\n\t\tthis.#gate = gate\n\t\tthis.#read = read\n\t\tthis.#write = write\n\t\tthis.#clamp = clamp\n\t}\n\n\t/** Finds one column's filter. */\n\tfilter(column: string): TableFilter | undefined {\n\t\tconst filter = this.#read().find((candidate) => candidate.column === column)\n\t\treturn filter === undefined ? undefined : Object.freeze({ ...filter })\n\t}\n\n\t/** Reads every filter as an owned frozen snapshot. */\n\tfilters(): readonly TableFilter[] {\n\t\treturn Object.freeze(this.#read().map((filter) => Object.freeze({ ...filter })))\n\t}\n\n\t/** Filters several columns. */\n\tset(filters: readonly TableFilter[]): void\n\t/** Filters one column. */\n\tset(filter: TableFilter): void\n\t/** Filters one column or several. */\n\tset(input: TableFilter | readonly TableFilter[]): void {\n\t\tthis.#gate()\n\t\tconst requested = Array.isArray(input) ? input : [input]\n\t\tfor (const filter of requested) this.#validate(filter)\n\n\t\tconst next = mergeTerms(this.#read(), requested)\n\t\tif (matchesTerms(next, this.#read(), (filter, other) => this.#operands(filter, other))) return\n\t\tthis.#write(next)\n\t\tconst page = this.#clamp()\n\t\tthis.#emitter.emit('filter', this.filters())\n\t\tif (page !== undefined) this.#emitter.emit('paginate', page)\n\t}\n\n\t/** Stops filtering by every column. */\n\tremove(): void\n\t/** Stops filtering by one column. */\n\tremove(column: string): boolean\n\t/** Stops filtering by several columns. */\n\tremove(columns: readonly string[]): boolean\n\t/** Stops filtering by one or more columns. */\n\tremove(input?: string | readonly string[]): void | boolean {\n\t\tthis.#gate()\n\t\tconst columns =\n\t\t\tinput === undefined\n\t\t\t\t? this.#schema.columns.map((column) => column.key)\n\t\t\t\t: Array.isArray(input)\n\t\t\t\t\t? input\n\t\t\t\t\t: [input]\n\t\tfor (const column of columns) {\n\t\t\tif (extractColumn(this.#schema, column) === undefined) return false\n\t\t}\n\n\t\tconst next = removeTerms(this.#read(), columns)\n\t\tif (next.length !== this.#read().length) {\n\t\t\tthis.#write(next)\n\t\t\tconst page = this.#clamp()\n\t\t\tthis.#emitter.emit('filter', this.filters())\n\t\t\tif (page !== undefined) this.#emitter.emit('paginate', page)\n\t\t}\n\n\t\treturn input === undefined ? undefined : true\n\t}\n\n\t#validate(filter: TableFilter): void {\n\t\tconst column = extractColumn(this.#schema, filter.column)\n\t\tif (column === undefined) {\n\t\t\tthrow new TableError('COLUMN', `The schema declares no column named \"${filter.column}\"`, {\n\t\t\t\tcolumn: filter.column,\n\t\t\t})\n\t\t}\n\n\t\tif (!admitsFilter(column, filter)) {\n\t\t\tthrow new TableError('CELL', `Column \"${filter.column}\" cannot apply that filter`, {\n\t\t\t\tcolumn: filter.column,\n\t\t\t})\n\t\t}\n\t}\n\n\t#operands(left: TableFilter, right: TableFilter): boolean {\n\t\tif (left.operator !== right.operator) return false\n\t\tif (left.operator === 'contains' && right.operator === 'contains') {\n\t\t\treturn left.text === right.text\n\t\t}\n\t\tif (left.operator === 'between' && right.operator === 'between') {\n\t\t\treturn left.minimum === right.minimum && left.maximum === right.maximum\n\t\t}\n\t\treturn left.operator === 'equals' && right.operator === 'equals' && left.value === right.value\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { PaginationManagerInterface, TableEventMap } from '../types.js'\n\n/** Manages the page arithmetic over one table's filtered rows. */\nexport class PaginationManager implements PaginationManagerInterface {\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #gate: () => void\n\treadonly #rows: () => number\n\treadonly #readPage: () => number\n\treadonly #writePage: (page: number) => void\n\treadonly #readLimit: () => number | undefined\n\treadonly #writeLimit: (limit: number | undefined) => void\n\n\t/**\n\t * Creates a pagination manager over one table's private stores.\n\t *\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param rows - A read of the filtered row count.\n\t * @param readPage - A read of the current page.\n\t * @param writePage - The page commit boundary.\n\t * @param readLimit - A read of the current page size.\n\t * @param writeLimit - The page-size commit boundary.\n\t */\n\tconstructor(\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\trows: () => number,\n\t\treadPage: () => number,\n\t\twritePage: (page: number) => void,\n\t\treadLimit: () => number | undefined,\n\t\twriteLimit: (limit: number | undefined) => void,\n\t) {\n\t\tthis.#emitter = emitter\n\t\tthis.#gate = gate\n\t\tthis.#rows = rows\n\t\tthis.#readPage = readPage\n\t\tthis.#writePage = writePage\n\t\tthis.#readLimit = readLimit\n\t\tthis.#writeLimit = writeLimit\n\n\t\tconst limit = this.#readLimit()\n\t\tif (limit !== undefined) this.#writeLimit(this.#normalize(limit))\n\t}\n\n\t/** Returns the page shown, counted from one. */\n\tget page(): number {\n\t\treturn this.#readLimit() === undefined ? 1 : this.#readPage()\n\t}\n\n\t/** Returns the number of rows one page holds. */\n\tget limit(): number | undefined {\n\t\treturn this.#readLimit()\n\t}\n\n\t/** Returns the number of filtered rows skipped before this page. */\n\tget offset(): number {\n\t\tconst limit = this.#readLimit()\n\t\treturn limit === undefined ? 0 : (this.#readPage() - 1) * limit\n\t}\n\n\t/** Returns the number of pages filled by the filtered rows. */\n\tget count(): number {\n\t\tconst limit = this.#readLimit()\n\t\treturn limit === undefined ? 1 : Math.max(1, Math.ceil(this.#rows() / limit))\n\t}\n\n\t/** Shows another page, clamped to the pages that exist. */\n\tmove(page: number): void {\n\t\tthis.#gate()\n\t\tconst next =\n\t\t\tthis.#readLimit() === undefined || Number.isNaN(page)\n\t\t\t\t? 1\n\t\t\t\t: Math.min(this.count, Math.max(1, Math.trunc(page)))\n\t\tif (next === this.#readPage()) return\n\t\tthis.#writePage(next)\n\t\tthis.#emitter.emit('paginate', next)\n\t}\n\n\t/** Changes the page size while keeping the first row previously shown. */\n\tresize(limit?: number): void {\n\t\tthis.#gate()\n\t\tconst previous = this.#readLimit()\n\t\tconst nextLimit = limit === undefined ? undefined : this.#normalize(limit)\n\t\tif (previous === nextLimit) return\n\n\t\tconst anchor = previous === undefined ? 0 : (this.#readPage() - 1) * previous\n\t\tthis.#writeLimit(nextLimit)\n\t\tconst nextPage =\n\t\t\tnextLimit === undefined\n\t\t\t\t? 1\n\t\t\t\t: Math.min(Math.max(1, Math.floor(anchor / nextLimit) + 1), this.count)\n\t\tthis.#writePage(nextPage)\n\t\tthis.#emitter.emit('paginate', nextPage)\n\t}\n\n\t#normalize(value: number): number {\n\t\treturn Number.isFinite(value) ? Math.max(1, Math.trunc(value)) : 1\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type {\n\tRowManagerInterface,\n\tTableEventMap,\n\tTableKey,\n\tTableRow,\n\tTableSchema,\n} from '../types.js'\nimport { cloneRow } from '../cloners.js'\nimport { TableError } from '../errors.js'\nimport { extractColumn, extractKey, matchesCell } from '../helpers.js'\nimport { isTableRow } from '../validators.js'\n\n/** Manages the rows one table holds in its own order. */\nexport class RowManager implements RowManagerInterface {\n\treadonly #schema: TableSchema\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #gate: () => void\n\treadonly #read: () => readonly TableRow[]\n\treadonly #write: (rows: readonly TableRow[]) => void\n\treadonly #settle: (removed: readonly TableKey[], announce: () => void) => void\n\n\t/**\n\t * Creates a row manager over one table's private row store.\n\t *\n\t * @param schema - The table schema.\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param read - A read of the current rows.\n\t * @param write - The row commit boundary.\n\t * @param settle - Commit dependent state, then order row and dependent announcements.\n\t * @param rows - Rows to seed without announcements.\n\t */\n\tconstructor(\n\t\tschema: TableSchema,\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\tread: () => readonly TableRow[],\n\t\twrite: (rows: readonly TableRow[]) => void,\n\t\tsettle: (removed: readonly TableKey[], announce: () => void) => void,\n\t\trows: readonly TableRow[] = [],\n\t) {\n\t\tthis.#schema = schema\n\t\tthis.#emitter = emitter\n\t\tthis.#gate = gate\n\t\tthis.#read = read\n\t\tthis.#write = write\n\t\tthis.#settle = settle\n\n\t\tconst seeded = this.#prepare(rows, new Set())\n\t\tif (seeded.length > 0) this.#write(Object.freeze(seeded))\n\t}\n\n\t/** Finds one row by key as an owned frozen snapshot. */\n\trow(key: TableKey): TableRow | undefined {\n\t\tconst row = this.#read().find((candidate) => extractKey(this.#schema, candidate) === key)\n\t\treturn row === undefined ? undefined : cloneRow(row)\n\t}\n\n\t/** Reads every row as owned frozen snapshots in table order. */\n\trows(): readonly TableRow[] {\n\t\treturn Object.freeze(this.#read().map((row) => cloneRow(row)))\n\t}\n\n\t/** Appends several rows. */\n\tadd(rows: readonly TableRow[]): void\n\t/** Appends one row. */\n\tadd(row: TableRow): void\n\t/** Appends one row or several. */\n\tadd(input: TableRow | readonly TableRow[]): void {\n\t\tthis.#gate()\n\t\tconst rows = Array.isArray(input) ? input : [input]\n\t\tconst keys = new Set<TableKey>()\n\t\tfor (const row of this.#read()) {\n\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\tif (key !== undefined) keys.add(key)\n\t\t}\n\t\tconst added = this.#prepare(rows, keys)\n\t\tif (added.length === 0) return\n\n\t\tthis.#write(Object.freeze([...this.#read(), ...added]))\n\t\tthis.#settle([], () => {\n\t\t\tfor (const row of added) {\n\t\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\t\tif (key !== undefined) this.#emitter.emit('write', key)\n\t\t\t}\n\t\t})\n\t}\n\n\t/** Merges several rows into the rows their keys name. */\n\tupdate(rows: readonly TableRow[]): boolean\n\t/** Merges one row into the row its key names. */\n\tupdate(row: TableRow): boolean\n\t/** Merges one row or several into the rows their keys name. */\n\tupdate(input: TableRow | readonly TableRow[]): boolean {\n\t\tthis.#gate()\n\t\tconst updates = (Array.isArray(input) ? input : [input]).map((row) => cloneRow(row))\n\t\tconst current = this.#read()\n\t\tconst locations: number[] = []\n\n\t\tfor (const update of updates) {\n\t\t\tthis.#validate(update)\n\t\t\tconst key = extractKey(this.#schema, update)\n\t\t\tif (key === undefined) this.#failKey('A row has no usable identity')\n\t\t\tconst index = current.findIndex((row) => extractKey(this.#schema, row) === key)\n\t\t\tif (index === -1) return false\n\t\t\tlocations.push(index)\n\t\t}\n\n\t\tconst next = [...current]\n\t\tconst moved: TableKey[] = []\n\t\tfor (let index = 0; index < updates.length; index += 1) {\n\t\t\tconst update = updates[index]\n\t\t\tconst location = locations[index]\n\t\t\tif (update === undefined || location === undefined) continue\n\t\t\tconst previous = next[location]\n\t\t\tif (previous === undefined) continue\n\t\t\tconst merged = cloneRow({ ...previous, ...update })\n\t\t\tif (!this.#same(previous, merged)) {\n\t\t\t\tnext[location] = merged\n\t\t\t\tconst key = extractKey(this.#schema, merged)\n\t\t\t\tif (key !== undefined) moved.push(key)\n\t\t\t}\n\t\t}\n\n\t\tif (moved.length === 0) return true\n\t\tthis.#write(Object.freeze(next))\n\t\tthis.#settle([], () => {\n\t\t\tfor (const key of moved) this.#emitter.emit('write', key)\n\t\t})\n\t\treturn true\n\t}\n\n\t/** Moves one row to a clamped index in table order. */\n\tmove(key: TableKey, index: number): boolean {\n\t\tthis.#gate()\n\t\tconst current = this.#read()\n\t\tconst origin = current.findIndex((row) => extractKey(this.#schema, row) === key)\n\t\tif (origin === -1) return false\n\t\tconst target = Math.min(\n\t\t\tcurrent.length - 1,\n\t\t\tNumber.isNaN(index) ? 0 : Math.max(0, Math.trunc(index)),\n\t\t)\n\t\tif (origin === target) return true\n\n\t\tconst row = current[origin]\n\t\tif (row === undefined) return false\n\t\tconst next = [...current]\n\t\tnext.splice(origin, 1)\n\t\tnext.splice(target, 0, row)\n\t\tthis.#write(Object.freeze(next))\n\t\tthis.#settle([], () => this.#emitter.emit('write', key))\n\t\treturn true\n\t}\n\n\t/** Removes every row. */\n\tremove(): void\n\t/** Removes one row. */\n\tremove(key: TableKey): boolean\n\t/** Removes several rows. */\n\tremove(keys: readonly TableKey[]): boolean\n\t/** Removes one or more rows. */\n\tremove(input?: TableKey | readonly TableKey[]): void | boolean {\n\t\tthis.#gate()\n\t\tconst current = this.#read()\n\t\tconst requested =\n\t\t\tinput === undefined\n\t\t\t\t? current.flatMap((row) => {\n\t\t\t\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\t\t\t\treturn key === undefined ? [] : [key]\n\t\t\t\t\t})\n\t\t\t\t: Array.isArray(input)\n\t\t\t\t\t? input\n\t\t\t\t\t: [input]\n\t\tconst keys = new Set(requested)\n\t\tconst known = new Set(\n\t\t\tcurrent.flatMap((row) => {\n\t\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\t\treturn key === undefined ? [] : [key]\n\t\t\t}),\n\t\t)\n\t\tif ([...keys].some((key) => !known.has(key))) return false\n\t\tif (keys.size === 0) return input === undefined ? undefined : true\n\n\t\tconst removed = current.flatMap((row) => {\n\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\treturn key !== undefined && keys.has(key) ? [key] : []\n\t\t})\n\t\tthis.#write(\n\t\t\tObject.freeze(\n\t\t\t\tcurrent.filter((row) => {\n\t\t\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\t\t\treturn key === undefined || !keys.has(key)\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t\tthis.#settle(removed, () => {\n\t\t\tfor (const key of removed) this.#emitter.emit('remove', key)\n\t\t})\n\t\treturn input === undefined ? undefined : true\n\t}\n\n\t#prepare(rows: readonly TableRow[], existing: Set<TableKey>): readonly TableRow[] {\n\t\tconst owned: TableRow[] = []\n\t\tfor (const row of rows) {\n\t\t\tconst snapshot = cloneRow(row)\n\t\t\tthis.#validate(snapshot)\n\t\t\tconst key = extractKey(this.#schema, snapshot)\n\t\t\tif (key === undefined) this.#failKey('A row has no usable identity')\n\t\t\tif (existing.has(key)) this.#failKey(`Row key \"${key}\" is already taken`, key)\n\t\t\texisting.add(key)\n\t\t\towned.push(snapshot)\n\t\t}\n\t\treturn owned\n\t}\n\n\t#validate(row: TableRow): void {\n\t\tif (extractKey(this.#schema, row) === undefined) this.#failKey('A row has no usable identity')\n\t\tif (!isTableRow(row)) {\n\t\t\tthrow new TableError('CELL', 'A row contains a value no table cell can hold')\n\t\t}\n\t\tfor (const key of Object.keys(row)) {\n\t\t\tconst column = extractColumn(this.#schema, key)\n\t\t\tif (column === undefined || !matchesCell(column, row[key])) {\n\t\t\t\tthrow new TableError('CELL', `Column \"${key}\" cannot hold that cell`, { column: key })\n\t\t\t}\n\t\t}\n\t}\n\n\t#failKey(message: string, key?: TableKey): never {\n\t\tif (key === undefined) throw new TableError('KEY', message)\n\t\tthrow new TableError('KEY', message, { key })\n\t}\n\n\t#same(left: TableRow, right: TableRow): boolean {\n\t\tconst leftKeys = Object.keys(left)\n\t\tconst rightKeys = Object.keys(right)\n\t\treturn (\n\t\t\tleftKeys.length === rightKeys.length &&\n\t\t\tleftKeys.every((key) => Object.hasOwn(right, key) && left[key] === right[key])\n\t\t)\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { SelectionManagerInterface, TableEventMap, TableKey } from '../types.js'\nimport { KeyManager } from './KeyManager.js'\n\n/** Manages the keys of the rows somebody has picked. */\nexport class SelectionManager implements SelectionManagerInterface {\n\treadonly #keys: KeyManager\n\n\t/**\n\t * Creates a selection manager over one table's private stores.\n\t *\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param rows - A read of every row key.\n\t * @param read - A read of the selected keys.\n\t * @param write - The selected-key commit boundary.\n\t */\n\tconstructor(\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\trows: () => readonly TableKey[],\n\t\tread: () => ReadonlySet<TableKey>,\n\t\twrite: (keys: ReadonlySet<TableKey>) => void,\n\t) {\n\t\tthis.#keys = new KeyManager(emitter, 'select', gate, rows, read, write)\n\t}\n\n\t/** Returns the keys of the rows picked right now. */\n\tget keys(): ReadonlySet<TableKey> {\n\t\treturn this.#keys.keys\n\t}\n\n\t/** Picks every row the table holds. */\n\tselect(): void\n\t/** Picks one row. */\n\tselect(key: TableKey): boolean\n\t/** Picks several rows. */\n\tselect(keys: readonly TableKey[]): boolean\n\t/** Picks one or more rows. */\n\tselect(input?: TableKey | readonly TableKey[]): void | boolean {\n\t\treturn this.#keys.change(input, () => true)\n\t}\n\n\t/** Drops every pick. */\n\tclear(): void\n\t/** Drops one pick. */\n\tclear(key: TableKey): boolean\n\t/** Drops several picks. */\n\tclear(keys: readonly TableKey[]): boolean\n\t/** Drops one or more picks. */\n\tclear(input?: TableKey | readonly TableKey[]): void | boolean {\n\t\treturn this.#keys.change(input, () => false)\n\t}\n\n\t/** Picks one row or drops it when already picked. */\n\ttoggle(key: TableKey): boolean\n\t/** Turns several rows around independently. */\n\ttoggle(keys: readonly TableKey[]): boolean\n\t/** Turns one or more rows around independently. */\n\ttoggle(input: TableKey | readonly TableKey[]): boolean {\n\t\treturn this.#keys.change(input, (included) => !included) === true\n\t}\n}\n","import type { Emitter } from '@orkestrel/emitter'\nimport type { SortManagerInterface, TableEventMap, TableOrder, TableSchema } from '../types.js'\nimport { TableError } from '../errors.js'\nimport { extractColumn, matchesTerms, mergeTerms, removeTerms } from '../helpers.js'\n\n/** Manages the ordered sort terms of one table. */\nexport class SortManager implements SortManagerInterface {\n\treadonly #schema: TableSchema\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #gate: () => void\n\treadonly #read: () => readonly TableOrder[]\n\treadonly #write: (orders: readonly TableOrder[]) => void\n\n\t/**\n\t * Creates a sort manager over one table's private term store.\n\t *\n\t * @param schema - The table schema.\n\t * @param emitter - The table's event emitter.\n\t * @param gate - The table lifecycle gate.\n\t * @param read - A read of the current terms.\n\t * @param write - The term commit boundary.\n\t */\n\tconstructor(\n\t\tschema: TableSchema,\n\t\temitter: Emitter<TableEventMap>,\n\t\tgate: () => void,\n\t\tread: () => readonly TableOrder[],\n\t\twrite: (orders: readonly TableOrder[]) => void,\n\t) {\n\t\tthis.#schema = schema\n\t\tthis.#emitter = emitter\n\t\tthis.#gate = gate\n\t\tthis.#read = read\n\t\tthis.#write = write\n\t}\n\n\t/** Finds one column's sort term. */\n\torder(column: string): TableOrder | undefined {\n\t\tconst order = this.#read().find((candidate) => candidate.column === column)\n\t\treturn order === undefined ? undefined : Object.freeze({ ...order })\n\t}\n\n\t/** Reads every sort term as an owned frozen snapshot. */\n\torders(): readonly TableOrder[] {\n\t\treturn Object.freeze(this.#read().map((order) => Object.freeze({ ...order })))\n\t}\n\n\t/** Sorts by several columns. */\n\tset(orders: readonly TableOrder[]): void\n\t/** Sorts by one column. */\n\tset(order: TableOrder): void\n\t/** Sorts by one column or several. */\n\tset(input: TableOrder | readonly TableOrder[]): void {\n\t\tthis.#gate()\n\t\tconst requested = Array.isArray(input) ? input : [input]\n\t\tfor (const order of requested) this.#require(order.column)\n\n\t\tconst next = mergeTerms(this.#read(), requested)\n\t\tif (matchesTerms(next, this.#read(), (order, other) => order.direction === other.direction)) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.#write(next)\n\t\tthis.#emitter.emit('sort', this.orders())\n\t}\n\n\t/** Stops sorting by every column. */\n\tremove(): void\n\t/** Stops sorting by one column. */\n\tremove(column: string): boolean\n\t/** Stops sorting by several columns. */\n\tremove(columns: readonly string[]): boolean\n\t/** Stops sorting by one or more columns. */\n\tremove(input?: string | readonly string[]): void | boolean {\n\t\tthis.#gate()\n\t\tconst columns =\n\t\t\tinput === undefined\n\t\t\t\t? this.#schema.columns.map((column) => column.key)\n\t\t\t\t: Array.isArray(input)\n\t\t\t\t\t? input\n\t\t\t\t\t: [input]\n\t\tfor (const column of columns) {\n\t\t\tif (extractColumn(this.#schema, column) === undefined) return false\n\t\t}\n\n\t\tconst next = removeTerms(this.#read(), columns)\n\t\tif (next.length !== this.#read().length) {\n\t\t\tthis.#write(next)\n\t\t\tthis.#emitter.emit('sort', this.orders())\n\t\t}\n\n\t\treturn input === undefined ? undefined : true\n\t}\n\n\t#require(column: string): void {\n\t\tif (extractColumn(this.#schema, column) === undefined) {\n\t\t\tthrow new TableError('COLUMN', `The schema declares no column named \"${column}\"`, { column })\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tCellComparator,\n\tCellMatcher,\n\tExpansionManagerInterface,\n\tFilterManagerInterface,\n\tPaginationManagerInterface,\n\tRowManagerInterface,\n\tSelectionManagerInterface,\n\tSortManagerInterface,\n\tTableEventMap,\n\tTableFilter,\n\tTableInterface,\n\tTableKey,\n\tTableOptions,\n\tTableOrder,\n\tTableRow,\n\tTableSchema,\n} from './types.js'\nimport { attempt } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { cloneRow, cloneSchema } from './cloners.js'\nimport { isTableError, TableError } from './errors.js'\nimport { auditTable, extractKey, filterRows, sortRows } from './helpers.js'\nimport { ExpansionManager } from './tables/ExpansionManager.js'\nimport { FilterManager } from './tables/FilterManager.js'\nimport { PaginationManager } from './tables/PaginationManager.js'\nimport { RowManager } from './tables/RowManager.js'\nimport { SelectionManager } from './tables/SelectionManager.js'\nimport { SortManager } from './tables/SortManager.js'\nimport { isStructuralTableSchema } from './validators.js'\n\n/** Holds a schema, its rows, and the lens through which they are read. */\nexport class Table implements TableInterface {\n\treadonly #emitter: Emitter<TableEventMap>\n\treadonly #schema: TableSchema\n\treadonly #comparators: Readonly<Record<string, CellComparator>> | undefined\n\treadonly #matchers: Readonly<Record<string, CellMatcher>> | undefined\n\treadonly #initialLimit: number | undefined\n\t#rowStore: readonly TableRow[] = Object.freeze([])\n\t#orderStore: readonly TableOrder[] = Object.freeze([])\n\t#filterStore: readonly TableFilter[] = Object.freeze([])\n\t#selected: ReadonlySet<TableKey> = new Set()\n\t#expanded: ReadonlySet<TableKey> = new Set()\n\t#page = 1\n\t#limit: number | undefined\n\t#destroyed = false\n\treadonly #rows: RowManager\n\treadonly #sort: SortManager\n\treadonly #filter: FilterManager\n\treadonly #selection: SelectionManager\n\treadonly #expansion: ExpansionManager\n\treadonly #pagination: PaginationManager\n\n\t/**\n\t * Opens a table against a schema.\n\t *\n\t * @param schema - The table declaration to own.\n\t * @param options - Initial rows, lens overrides, pagination, and emitter wiring.\n\t * @throws A {@link TableError} coded `SCHEMA` when the schema is unusable, `KEY` when a seeded\n\t * identity is unusable or repeated, and `CELL` when a seeded cell is invalid.\n\t */\n\tconstructor(schema: TableSchema, options?: TableOptions) {\n\t\tconst unusable = 'The schema is not a table schema'\n\t\tconst owned = isStructuralTableSchema(schema) ? attempt(() => cloneSchema(schema)) : undefined\n\t\tif (owned !== undefined && !owned.success && isTableError(owned.error)) throw owned.error\n\t\tif (owned === undefined || !owned.success) {\n\t\t\tthrow new TableError('SCHEMA', `The table schema is unusable: ${unusable}`, {\n\t\t\t\tproblems: [unusable],\n\t\t\t})\n\t\t}\n\n\t\tconst problems = isStructuralTableSchema(owned.value) ? auditTable(owned.value) : [unusable]\n\t\tif (problems.length > 0) {\n\t\t\tthrow new TableError('SCHEMA', `The table schema is unusable: ${problems.join('; ')}`, {\n\t\t\t\tproblems: [...problems],\n\t\t\t})\n\t\t}\n\n\t\tthis.#schema = owned.value\n\t\tthis.#comparators =\n\t\t\toptions?.comparators === undefined ? undefined : Object.freeze({ ...options.comparators })\n\t\tthis.#matchers =\n\t\t\toptions?.matchers === undefined ? undefined : Object.freeze({ ...options.matchers })\n\t\tthis.#limit = options?.limit\n\t\tthis.#emitter = new Emitter<TableEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\n\t\tthis.#selection = new SelectionManager(\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.#keys(),\n\t\t\t() => this.#selected,\n\t\t\t(keys) => {\n\t\t\t\tthis.#selected = keys\n\t\t\t},\n\t\t)\n\t\tthis.#expansion = new ExpansionManager(\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.#keys(),\n\t\t\t() => this.#expanded,\n\t\t\t(keys) => {\n\t\t\t\tthis.#expanded = keys\n\t\t\t},\n\t\t)\n\t\tthis.#pagination = new PaginationManager(\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.count,\n\t\t\t() => this.#page,\n\t\t\t(page) => {\n\t\t\t\tthis.#page = page\n\t\t\t},\n\t\t\t() => this.#limit,\n\t\t\t(limit) => {\n\t\t\t\tthis.#limit = limit\n\t\t\t},\n\t\t)\n\t\tthis.#initialLimit = this.#limit\n\t\tthis.#sort = new SortManager(\n\t\t\tthis.#schema,\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.#orderStore,\n\t\t\t(orders) => {\n\t\t\t\tthis.#orderStore = orders\n\t\t\t},\n\t\t)\n\t\tthis.#filter = new FilterManager(\n\t\t\tthis.#schema,\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.#filterStore,\n\t\t\t(filters) => {\n\t\t\t\tthis.#filterStore = filters\n\t\t\t},\n\t\t\t() => this.#clamp(),\n\t\t)\n\t\tthis.#rows = new RowManager(\n\t\t\tthis.#schema,\n\t\t\tthis.#emitter,\n\t\t\t() => this.#gate(),\n\t\t\t() => this.#rowStore,\n\t\t\t(rows) => {\n\t\t\t\tthis.#rowStore = rows\n\t\t\t},\n\t\t\t(removed, announce) => this.#settle(removed, announce),\n\t\t\toptions?.rows,\n\t\t)\n\t}\n\n\t/** Holds the table's event emitter. */\n\tget emitter(): EmitterInterface<TableEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t/** Holds the owned frozen schema. */\n\tget schema(): TableSchema {\n\t\treturn this.#schema\n\t}\n\n\t/** Manages the rows the table holds. */\n\tget rows(): RowManagerInterface {\n\t\treturn this.#rows\n\t}\n\n\t/** Manages the ordered sort terms. */\n\tget sort(): SortManagerInterface {\n\t\treturn this.#sort\n\t}\n\n\t/** Manages the filters applied with and-only composition. */\n\tget filter(): FilterManagerInterface {\n\t\treturn this.#filter\n\t}\n\n\t/** Manages the selected row keys. */\n\tget selection(): SelectionManagerInterface {\n\t\treturn this.#selection\n\t}\n\n\t/** Manages the expanded row keys. */\n\tget expansion(): ExpansionManagerInterface {\n\t\treturn this.#expansion\n\t}\n\n\t/** Manages the page arithmetic. */\n\tget pagination(): PaginationManagerInterface {\n\t\treturn this.#pagination\n\t}\n\n\t/** Returns the filtered, sorted, and paged rows as owned frozen snapshots. */\n\tget view(): readonly TableRow[] {\n\t\tconst ordered = sortRows(this.#schema, this.#filtered(), this.#orderStore, this.#comparators)\n\t\tconst limit = this.#limit\n\t\tconst page =\n\t\t\tlimit === undefined\n\t\t\t\t? ordered\n\t\t\t\t: ordered.slice(this.#pagination.offset, this.#pagination.offset + limit)\n\t\treturn Object.freeze(page.map((row) => cloneRow(row)))\n\t}\n\n\t/** Returns the number of rows admitted by the filters. */\n\tget count(): number {\n\t\treturn this.#filtered().length\n\t}\n\n\t/** Reports whether the table has been torn down. */\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed\n\t}\n\n\t/** Resets every moving axis to its opening state. */\n\tclear(): void {\n\t\tthis.#gate()\n\t\tconst changed =\n\t\t\tthis.#rowStore.length > 0 ||\n\t\t\tthis.#orderStore.length > 0 ||\n\t\t\tthis.#filterStore.length > 0 ||\n\t\t\tthis.#selected.size > 0 ||\n\t\t\tthis.#expanded.size > 0 ||\n\t\t\tthis.#page !== 1 ||\n\t\t\tthis.#limit !== this.#initialLimit\n\t\tif (!changed) return\n\n\t\tthis.#rowStore = Object.freeze([])\n\t\tthis.#orderStore = Object.freeze([])\n\t\tthis.#filterStore = Object.freeze([])\n\t\tthis.#selected = new Set()\n\t\tthis.#expanded = new Set()\n\t\tthis.#page = 1\n\t\tthis.#limit = this.#initialLimit\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\t/** Tears the table down while leaving every getter readable. */\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#filtered(): readonly TableRow[] {\n\t\treturn filterRows(this.#schema, this.#rowStore, this.#filterStore, this.#matchers)\n\t}\n\n\t#keys(): readonly TableKey[] {\n\t\treturn this.#rowStore.flatMap((row) => {\n\t\t\tconst key = extractKey(this.#schema, row)\n\t\t\treturn key === undefined ? [] : [key]\n\t\t})\n\t}\n\n\t#settle(removed: readonly TableKey[], announce: () => void): void {\n\t\tconst keys = new Set(removed)\n\t\tconst selected = new Set([...this.#selected].filter((key) => !keys.has(key)))\n\t\tconst expanded = new Set([...this.#expanded].filter((key) => !keys.has(key)))\n\t\tconst selectedChanged = selected.size !== this.#selected.size\n\t\tconst expandedChanged = expanded.size !== this.#expanded.size\n\n\t\tif (selectedChanged) this.#selected = selected\n\t\tif (expandedChanged) this.#expanded = expanded\n\t\tconst page = this.#clamp()\n\n\t\tannounce()\n\t\tif (selectedChanged) this.#emitter.emit('select', new Set(selected))\n\t\tif (expandedChanged) this.#emitter.emit('expand', new Set(expanded))\n\t\tif (page !== undefined) this.#emitter.emit('paginate', page)\n\t}\n\n\t#clamp(): number | undefined {\n\t\tconst page = Math.min(this.#page, this.#pagination.count)\n\t\tif (page === this.#page) return undefined\n\t\tthis.#page = page\n\t\treturn page\n\t}\n\n\t#gate(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new TableError('DESTROYED', 'The table was destroyed and cannot change')\n\t\t}\n\t}\n}\n","import type { TableInterface, TableOptions, TableSchema } from './types.js'\nimport { Table } from './Table.js'\n\n/**\n * Opens a table against a schema.\n *\n * @param schema - The table declaration to own.\n * @param options - Initial rows, lens overrides, pagination, and emitter wiring.\n * @returns A live table interface.\n * @throws A {@link TableError} coded `SCHEMA` when the schema is unusable, `KEY` when a seeded\n * identity is unusable or repeated, and `CELL` when a seeded cell is invalid.\n * @example\n * ```ts\n * const table = createTable({ key: 'id', columns: [{ cell: 'text', key: 'id' }] })\n * table.rows.add({ id: '1' })\n * ```\n */\nexport function createTable(schema: TableSchema, options?: TableOptions): TableInterface {\n\treturn new Table(schema, options)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/table",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "The @orkestrel/table package.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/orkestrel/table#readme",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"check": "tsc --noEmit --project tsconfig.json && npm run check:src",
|
|
46
46
|
"check:src": "npm run check:src:core",
|
|
47
47
|
"check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
|
|
48
|
-
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:guides",
|
|
48
|
+
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:setup && npm run test:guides",
|
|
49
49
|
"test:src": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
50
50
|
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
51
51
|
"test:policy": "vitest run --config vite.config.ts --no-cache --reporter=dot --project policy",
|
|
@@ -55,24 +55,29 @@
|
|
|
55
55
|
"build": "npm run clean && npm run build:src",
|
|
56
56
|
"build:src": "npm run build:src:core",
|
|
57
57
|
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
58
|
-
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test"
|
|
58
|
+
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release",
|
|
59
|
+
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
60
|
+
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
61
|
+
"prepack": "npm run build",
|
|
62
|
+
"test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup"
|
|
59
63
|
},
|
|
60
64
|
"dependencies": {
|
|
61
|
-
"@orkestrel/contract": "^0.0.
|
|
62
|
-
"@orkestrel/emitter": "^0.0.
|
|
65
|
+
"@orkestrel/contract": "^0.0.16",
|
|
66
|
+
"@orkestrel/emitter": "^0.0.9"
|
|
63
67
|
},
|
|
64
68
|
"devDependencies": {
|
|
65
|
-
"@microsoft/api-extractor": "^7.
|
|
66
|
-
"@orkestrel/guide": "^0.0.
|
|
67
|
-
"@orkestrel/
|
|
68
|
-
"@orkestrel/
|
|
69
|
-
"@
|
|
70
|
-
"
|
|
71
|
-
"
|
|
69
|
+
"@microsoft/api-extractor": "^7.59.0",
|
|
70
|
+
"@orkestrel/guide": "^0.0.16",
|
|
71
|
+
"@orkestrel/probe": "^0.0.11",
|
|
72
|
+
"@orkestrel/scaffold": "^0.0.61",
|
|
73
|
+
"@orkestrel/test": "^0.0.13",
|
|
74
|
+
"@types/node": "^26.4.1",
|
|
75
|
+
"oxfmt": "^0.66.0",
|
|
76
|
+
"oxlint": "^1.81.0",
|
|
72
77
|
"typescript": "^6.0.3",
|
|
73
|
-
"vite": "
|
|
74
|
-
"vite-plugin-dts": "^5.0
|
|
75
|
-
"vitest": "^4.1.
|
|
78
|
+
"vite": "^8.2.2",
|
|
79
|
+
"vite-plugin-dts": "^5.1.0",
|
|
80
|
+
"vitest": "^4.1.11"
|
|
76
81
|
},
|
|
77
82
|
"engines": {
|
|
78
83
|
"node": ">=22.12.0"
|