feat(logic): add array sizing-policy helpers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino Ferrari
2026-06-24 10:51:28 +02:00
parent 3b8c6540e1
commit 2f40a9d1a0
+54
View File
@@ -0,0 +1,54 @@
// Pure helpers for array-valued local state: parse the declared initial value
// and enforce the declared sizing policy (dynamic / capped / fixed). Shared by
// localstate.ts (write path) and logic.ts (node handlers + migration).
import type { StateVar } from './types';
export type ArrVal = number | ArrVal[];
export const ARRAY_MAX = 1_000_000;
// zeroFill builds a length-n array of zeros (flat; fixed nested init must come
// from an explicit `initial` literal).
function zeroFill(n: number): ArrVal[] {
return new Array(Math.max(0, n)).fill(0);
}
// parseInitialArray returns the starting contents of an array local.
export function parseInitialArray(sv: StateVar): ArrVal[] {
const cap = sv.capacity ?? 0;
const raw = (sv.initial ?? '').trim();
let parsed: ArrVal[] | null = null;
if (raw) {
try {
const j = JSON.parse(raw);
if (Array.isArray(j)) parsed = j as ArrVal[];
} catch { parsed = null; }
}
if (sv.sizing === 'fixed') {
if (!parsed) return zeroFill(cap);
// truncate / zero-pad to capacity
const out = parsed.slice(0, cap);
while (out.length < cap) out.push(0);
return out;
}
return parsed ?? [];
}
// applySizing returns arr clamped to the declared policy.
// dynamic → unchanged (but globally capped at ARRAY_MAX, dropping oldest)
// capped → keep at most capacity elements, dropping oldest (ring/FIFO)
// fixed → exactly capacity elements (truncate / zero-pad); never grow/shrink
export function applySizing(arr: ArrVal[], sv: StateVar): ArrVal[] {
const cap = sv.capacity ?? 0;
switch (sv.sizing) {
case 'fixed': {
const out = arr.slice(0, cap);
while (out.length < cap) out.push(0);
return out;
}
case 'capped':
return arr.length > cap ? arr.slice(arr.length - cap) : arr;
default:
return arr.length > ARRAY_MAX ? arr.slice(arr.length - ARRAY_MAX) : arr;
}
}