refactor(words): extract table factories to extensions/table (F2.3b)

Second atomic checkpoint of F2.3. Moves table factory functions
(createTable, createTableRow, createTableCell), predicate functions
(isWordsTableCellVerticalAlign, isWordsTableCellTone), and value-set
constants (WORDS_TABLE_CELL_VERTICAL_ALIGNS, WORDS_TABLE_CELL_TONES)
from engine/document.ts to extensions/table/factories.ts.

engine/document.ts now re-exports the moved symbols so existing
imports keep working unchanged. The factories module imports its
back-references (createText, WordsInline) from engine/document — the
extension may depend on the engine core but the engine core only
depends on the extension via re-export indirection (no functional
dependency).

extensions/table/index.ts barrel updated to expose types (F2.3a) +
factories (F2.3b) as the table extension's public surface. Document
header notes which pieces have been migrated and which are still
pending (serializers, render, path, normalize, operations, registry
wire-up).

Verification:
- 143/143 tests pass in src/uix/soma/components/words
- 0 new TypeScript errors
- No engine behaviour change (symbol relocation only)

F2.3 progress: a + b done. Pending: c (serialize-html), d
(serialize-markdown), e (render), f (path), g (normalize), h
(operations — largest), i (registry wire-up), j (verify).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent a82c422b05
commit a0afa44da4

@ -120,16 +120,13 @@ export const WORDS_TEXT_ALIGNS = [
'right',
'justify'
] as const satisfies readonly WordsTextAlign[];
export const WORDS_TABLE_CELL_VERTICAL_ALIGNS = [
'top',
'middle',
'bottom'
] as const satisfies readonly WordsTableCellVerticalAlign[];
export const WORDS_TABLE_CELL_TONES = [
'default',
'muted',
'accent'
] as const satisfies readonly WordsTableCellTone[];
// Table cell value-set constants live in the table extension since
// F2.3b. Re-exported here for backward compat with consumers that
// import them from `engine/document`.
export {
WORDS_TABLE_CELL_VERTICAL_ALIGNS,
WORDS_TABLE_CELL_TONES
} from '../extensions/table/factories';
export function createEmptyWordsDocument(): WordsDocument {
return {
@ -192,39 +189,9 @@ export function createListItem(
};
}
export function createTable(
children: readonly WordsTableRow[] = [createTableRow()],
options: WordsTableOptions = {}
): WordsTableBlock {
return {
type: 'table',
...(options.striped ? { striped: true } : {}),
...(options.compact ? { compact: true } : {}),
children
};
}
export function createTableRow(
children: readonly WordsTableCell[] = [createTableCell()]
): WordsTableRow {
return { type: 'table-row', children };
}
export function createTableCell(
children: readonly WordsInline[] = [createText('')],
options: WordsTableCellOptions = {}
): WordsTableCell {
return {
type: 'table-cell',
...(options.header ? { header: true } : {}),
...(options.textAlign && options.textAlign !== 'left' ? { textAlign: options.textAlign } : {}),
...(options.verticalAlign && options.verticalAlign !== 'top'
? { verticalAlign: options.verticalAlign }
: {}),
...(options.tone && options.tone !== 'default' ? { tone: options.tone } : {}),
children
};
}
// Table factory functions live in the table extension since F2.3b.
// Re-exported here for backward compat — see `extensions/table/factories.ts`.
export { createTable, createTableRow, createTableCell } from '../extensions/table/factories';
export function createText(text: string, marks: readonly WordsMark[] = []): WordsText {
const normalizedMarks = normalizeMarks(marks);
@ -280,18 +247,12 @@ export function isWordsTextAlign(value: unknown): value is WordsTextAlign {
return typeof value === 'string' && (WORDS_TEXT_ALIGNS as readonly string[]).includes(value);
}
export function isWordsTableCellVerticalAlign(
value: unknown
): value is WordsTableCellVerticalAlign {
return (
typeof value === 'string' &&
(WORDS_TABLE_CELL_VERTICAL_ALIGNS as readonly string[]).includes(value)
);
}
export function isWordsTableCellTone(value: unknown): value is WordsTableCellTone {
return typeof value === 'string' && (WORDS_TABLE_CELL_TONES as readonly string[]).includes(value);
}
// Table predicates live in the table extension since F2.3b.
// Re-exported here for backward compat.
export {
isWordsTableCellVerticalAlign,
isWordsTableCellTone
} from '../extensions/table/factories';
export function normalizeWordsCodeLanguage(value: unknown): string | undefined {
if (typeof value !== 'string') return undefined;

@ -0,0 +1,85 @@
/**
* Table factories + value-set predicates.
*
* Owned by the table extension. The engine's `document.ts` re-exports
* these for backward compatibility. New code should import from the
* `extensions/table` barrel.
*
* Factories canonicalize the shape of every table node — they apply
* defaults (single empty row, single empty cell, text "left" align
* stripped when default, etc.) so the engine never has to think about
* "is this a valid table?". Predicates validate user-supplied values
* for cell tone and vertical align, used by the operations layer
* before applying commands.
*/
import { createText } from '../../engine/document';
import type { WordsInline } from '../../engine/document';
import type {
WordsTableBlock,
WordsTableCell,
WordsTableCellOptions,
WordsTableCellTone,
WordsTableCellVerticalAlign,
WordsTableOptions,
WordsTableRow
} from './types';
export const WORDS_TABLE_CELL_VERTICAL_ALIGNS = [
'top',
'middle',
'bottom'
] as const satisfies readonly WordsTableCellVerticalAlign[];
export const WORDS_TABLE_CELL_TONES = [
'default',
'muted',
'accent'
] as const satisfies readonly WordsTableCellTone[];
export function createTable(
children: readonly WordsTableRow[] = [createTableRow()],
options: WordsTableOptions = {}
): WordsTableBlock {
return {
type: 'table',
...(options.striped ? { striped: true } : {}),
...(options.compact ? { compact: true } : {}),
children
};
}
export function createTableRow(
children: readonly WordsTableCell[] = [createTableCell()]
): WordsTableRow {
return { type: 'table-row', children };
}
export function createTableCell(
children: readonly WordsInline[] = [createText('')],
options: WordsTableCellOptions = {}
): WordsTableCell {
return {
type: 'table-cell',
...(options.header ? { header: true } : {}),
...(options.textAlign && options.textAlign !== 'left' ? { textAlign: options.textAlign } : {}),
...(options.verticalAlign && options.verticalAlign !== 'top'
? { verticalAlign: options.verticalAlign }
: {}),
...(options.tone && options.tone !== 'default' ? { tone: options.tone } : {}),
children
};
}
export function isWordsTableCellVerticalAlign(
value: unknown
): value is WordsTableCellVerticalAlign {
return (
typeof value === 'string' &&
(WORDS_TABLE_CELL_VERTICAL_ALIGNS as readonly string[]).includes(value)
);
}
export function isWordsTableCellTone(value: unknown): value is WordsTableCellTone {
return typeof value === 'string' && (WORDS_TABLE_CELL_TONES as readonly string[]).includes(value);
}

@ -0,0 +1,39 @@
/**
* Table extension — public barrel.
*
* Migration in progress (F2.3). This barrel exposes the pieces already
* moved to the extension so consumers can start importing from here
* instead of `engine/document.ts`.
*
* Pieces moved so far:
* - Types (F2.3a)
* - Factories + value-set predicates (F2.3b)
*
* Pending:
* - Serializers (HTML + Markdown) (F2.3c, F2.3d)
* - Render (F2.3e)
* - Path / navigation (F2.3f)
* - Normalize (F2.3g)
* - Operations (F2.3h)
* - Registry wire-up + WordsExtension export (F2.3i)
*/
export type {
WordsTableBlock,
WordsTableCell,
WordsTableCellOptions,
WordsTableCellTone,
WordsTableCellVerticalAlign,
WordsTableOptions,
WordsTableRow
} from './types';
export {
createTable,
createTableCell,
createTableRow,
isWordsTableCellTone,
isWordsTableCellVerticalAlign,
WORDS_TABLE_CELL_TONES,
WORDS_TABLE_CELL_VERTICAL_ALIGNS
} from './factories';
Loading…
Cancel
Save

Powered by TurnKey Linux.