Files
suaveplan/packages/foundation/data/templates/src/engine/ParseState.ts
2026-05-27 23:47:53 +01:00

88 lines
2.2 KiB
TypeScript

import type { ParseState } from "../types/index.js";
/**
* Create a new, empty parse state.
*
* @param maxDepth - Maximum recursive nesting depth (default 10).
*/
export function createParseState(maxDepth = 10): ParseState {
return {
counters: new Map(),
depth: 0,
maxDepth,
cache: new Map(),
custom: new Map(),
};
}
/**
* Deep-clone a parse state.
*
* Counter, cache, and custom maps are each cloned independently so
* mutations to the clone do not affect the original.
*/
export function cloneParseState(state: ParseState): ParseState {
return {
counters: new Map(state.counters),
depth: state.depth,
maxDepth: state.maxDepth,
cache: new Map(state.cache),
custom: new Map(state.custom),
};
}
/**
* Increment nesting depth in-place.
* Called by the engine before recursing into a nested template.
*/
export function incrementDepth(state: ParseState): void {
state.depth++;
}
/**
* Decrement nesting depth in-place.
* Called by the engine after returning from a nested template.
*/
export function decrementDepth(state: ParseState): void {
state.depth--;
}
/**
* Get the current value of a named counter and advance it.
*
* If the counter has never been set, it is initialised to `initialValue - 1`
* so that the first call returns exactly `initialValue`.
*
* @param state - The active parse state.
* @param name - Counter name.
* @param initialValue - Value returned on the first call (default 1).
*/
export function getCounter(
state: ParseState,
name: string,
initialValue = 1
): number {
const current = state.counters.get(name) ?? initialValue - 1;
const next = current + 1;
state.counters.set(name, next);
return next;
}
/**
* Reset a named counter to an explicit value.
*
* @param state - The active parse state.
* @param name - Counter name.
* @param value - New stored value (default 1, so the next read returns 2).
*/
export function resetCounter(state: ParseState, name: string, value = 1): void {
state.counters.set(name, value);
}
/**
* Clear **all** named counters, resetting the map to empty.
*/
export function clearCounters(state: ParseState): void {
state.counters.clear();
}