feat(logic): array local init + sizing enforcement in localstate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,9 +11,15 @@
|
|||||||
|
|
||||||
import { writable, type Readable, type Writable } from './store';
|
import { writable, type Readable, type Writable } from './store';
|
||||||
import type { SignalValue, SignalMeta, StateVar } from './types';
|
import type { SignalValue, SignalMeta, StateVar } from './types';
|
||||||
|
import { parseInitialArray, applySizing, type ArrVal } from './arraypolicy';
|
||||||
|
|
||||||
const valueStores = new Map<string, Writable<SignalValue>>();
|
const valueStores = new Map<string, Writable<SignalValue>>();
|
||||||
const metaStores = new Map<string, Writable<SignalMeta | null>>();
|
const metaStores = new Map<string, Writable<SignalMeta | null>>();
|
||||||
|
const decls = new Map<string, StateVar>();
|
||||||
|
|
||||||
|
export function declaredVar(name: string): StateVar | undefined {
|
||||||
|
return decls.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
const DEFAULT_VALUE: SignalValue = { value: null, quality: 'unknown', ts: null };
|
const DEFAULT_VALUE: SignalValue = { value: null, quality: 'unknown', ts: null };
|
||||||
|
|
||||||
@@ -42,6 +48,8 @@ function coerce(v: StateVar): any {
|
|||||||
return v.initial === 'true' || v.initial === '1';
|
return v.initial === 'true' || v.initial === '1';
|
||||||
case 'string':
|
case 'string':
|
||||||
return v.initial;
|
return v.initial;
|
||||||
|
case 'array':
|
||||||
|
return parseInitialArray(v);
|
||||||
default: {
|
default: {
|
||||||
const n = parseFloat(v.initial);
|
const n = parseFloat(v.initial);
|
||||||
return isNaN(n) ? 0 : n;
|
return isNaN(n) ? 0 : n;
|
||||||
@@ -53,6 +61,7 @@ function coerce(v: StateVar): any {
|
|||||||
// publishes metadata. Call this whenever a panel is loaded.
|
// publishes metadata. Call this whenever a panel is loaded.
|
||||||
export function initLocalState(vars: StateVar[] | undefined): void {
|
export function initLocalState(vars: StateVar[] | undefined): void {
|
||||||
for (const v of vars ?? []) {
|
for (const v of vars ?? []) {
|
||||||
|
decls.set(v.name, v);
|
||||||
valueW(v.name).set({
|
valueW(v.name).set({
|
||||||
value: coerce(v),
|
value: coerce(v),
|
||||||
quality: 'good',
|
quality: 'good',
|
||||||
@@ -64,6 +73,9 @@ export function initLocalState(vars: StateVar[] | undefined): void {
|
|||||||
displayLow: v.low ?? 0,
|
displayLow: v.low ?? 0,
|
||||||
displayHigh: v.high ?? 100,
|
displayHigh: v.high ?? 100,
|
||||||
writable: true,
|
writable: true,
|
||||||
|
elem: v.elem,
|
||||||
|
sizing: v.sizing,
|
||||||
|
capacity: v.capacity,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +89,11 @@ export function getLocalMetaStore(name: string): Readable<SignalMeta | null> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeLocalState updates a local variable's live value in place.
|
// writeLocalState updates a local variable's live value in place.
|
||||||
|
// When the declared variable is an array type, the written value is passed
|
||||||
|
// through applySizing to enforce the declared sizing policy.
|
||||||
export function writeLocalState(name: string, value: any): void {
|
export function writeLocalState(name: string, value: any): void {
|
||||||
valueW(name).set({ value, quality: 'good', ts: new Date().toISOString() });
|
const sv = decls.get(name);
|
||||||
|
let v = value;
|
||||||
|
if (sv?.type === 'array' && Array.isArray(value)) v = applySizing(value as ArrVal[], sv);
|
||||||
|
valueW(name).set({ value: v, quality: 'good', ts: new Date().toISOString() });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ export interface SignalMeta {
|
|||||||
description?: string;
|
description?: string;
|
||||||
properties?: Record<string, string>;
|
properties?: Record<string, string>;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
|
// array-local extra fields (present when type === 'array'):
|
||||||
|
elem?: 'number' | 'bool' | 'array';
|
||||||
|
sizing?: 'dynamic' | 'capped' | 'fixed';
|
||||||
|
capacity?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A single widget in an interface
|
// A single widget in an interface
|
||||||
|
|||||||
Reference in New Issue
Block a user