export type ConvertErrorCode = | 'malformed-directive' | 'malformed-pipe-table' | 'not-a-string' | 'not-an-adf-document' | 'unknown-directive-name' | 'unmappable-html' | 'unspellable-whitespace' | 'unsupported-document-version' | 'unsupported-nesting-depth' | 'unsupported-node-shape' export type ConvertErrorPath = readonly (number | string)[] export type SourcePosition = { line: number; offset: number } export type ConvertFault = { code: ConvertErrorCode message: string } export type ConvertError = ConvertFault & { path: ConvertErrorPath; position?: SourcePosition } export type ParseError = ConvertError & { position: SourcePosition } export type Result = { error: E; ok: false } | { ok: true; value: T } export function failure(code: ConvertErrorCode, message: string, path: ConvertErrorPath): Result { return { error: { code, message, path }, ok: false } } export function faulted(fault: ConvertFault, path: ConvertErrorPath): Result { return failure(fault.code, fault.message, path) } export function positioned(result: Result, position: SourcePosition): Result { if (result.ok) return result return { error: { ...result.error, position: result.error.position ?? position }, ok: false } } export function success(value: T): { ok: true; value: T } { return { ok: true, value } } // Past the longest string or array, measured on Firefox 155, Node 24 and Bun 1.4: SpiderMonkey throws the first, V8 the next two, JavaScriptCore the last. const engineLimitThrows = ['InternalError: allocation size overflow', 'RangeError: Invalid array length', 'RangeError: Invalid string length', 'RangeError: Out of memory'] // Any string concatenation can throw one, so this wraps a whole conversion. export function withinEngineLimits(convert: () => Result): Result { try { return convert() } catch (error) { // A stack overflow is a bug (docs/decisions.md §Nothing recurses unbounded), so it stays a throw. if (!(error instanceof Error) || !engineLimitThrows.includes(`${error.name}: ${error.message}`)) throw error return failure('unsupported-node-shape', `the output would be longer than the longest string or array this JavaScript engine builds (${error.message})`, []) } }