feat(logic): add array sizing-policy helpers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user