@kymoscope/sdk 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{importer.worker-Drm9u2Rc.js → importer.worker-CLBGjz4d.js} +1 -1
- package/dist/assets/{offscreenLineWorker-mShhnyXX.js → offscreenLineWorker-BLxay-Po.js} +2 -2
- package/dist/importers-B6rkbTwQ.js +5 -0
- package/dist/keys-KE0GTKAF.js +10 -0
- package/dist/kymoscope-embed.js +91 -90
- package/dist/kymoscope-sdk.js +86 -84
- package/dist/rules/kyr1.schema.json +135 -0
- package/dist/rules.js +2 -0
- package/dist/styles/charts.css +191 -0
- package/dist/threshold-C9it0Y7P.js +2 -0
- package/dist/types/charts/AnnotationLayer.d.ts +7 -2
- package/dist/types/charts/CameraPanel.d.ts +43 -0
- package/dist/types/charts/ChartBody.d.ts +12 -0
- package/dist/types/charts/beacon.d.ts +4 -1
- package/dist/types/charts/cameraLayout.d.ts +10 -0
- package/dist/types/charts/liveOverlay.d.ts +14 -0
- package/dist/types/charts/runtime.d.ts +12 -1
- package/dist/types/charts/useWorksheetData.d.ts +1 -5
- package/dist/types/components/GaugeChart.d.ts +2 -0
- package/dist/types/components/MultiBandCanvasChart.d.ts +4 -2
- package/dist/types/components/dashboardGridLayout.d.ts +1 -1
- package/dist/types/components/multiBandHover.d.ts +7 -0
- package/dist/types/engine/alerts.d.ts +56 -0
- package/dist/types/engine/columns.d.ts +16 -0
- package/dist/types/engine/createEngine.d.ts +60 -2
- package/dist/types/engine/derive.d.ts +1 -1
- package/dist/types/engine/errors.d.ts +1 -1
- package/dist/types/engine/liveController.d.ts +11 -1
- package/dist/types/engine/types.d.ts +41 -2
- package/dist/types/index.d.ts +26 -3
- package/dist/types/lib/annotations.d.ts +20 -0
- package/dist/types/lib/beacon.d.ts +2 -1
- package/dist/types/lib/data/columnarDataSource.d.ts +1 -0
- package/dist/types/lib/data/dataSource.d.ts +3 -0
- package/dist/types/lib/data/duckDbDataSource.d.ts +1 -0
- package/dist/types/lib/data/historyDataSource.d.ts +51 -0
- package/dist/types/lib/data/inMemoryDataSource.d.ts +1 -0
- package/dist/types/lib/data/liveDataSource.d.ts +20 -1
- package/dist/types/lib/data/pointColumns.d.ts +11 -0
- package/dist/types/lib/duckdb/duckdbInstance.d.ts +5 -0
- package/dist/types/lib/historian/blockCache.d.ts +32 -0
- package/dist/types/lib/historian/export.d.ts +31 -0
- package/dist/types/lib/historian/khd1.d.ts +41 -0
- package/dist/types/lib/historian/parquet.d.ts +21 -0
- package/dist/types/lib/historian/reader.d.ts +73 -0
- package/dist/types/lib/live/blockWire.d.ts +16 -0
- package/dist/types/lib/live/buffer.d.ts +34 -0
- package/dist/types/lib/live/cameraSender.d.ts +70 -0
- package/dist/types/lib/live/clockMap.d.ts +20 -0
- package/dist/types/lib/live/crypto.d.ts +7 -0
- package/dist/types/lib/live/publisher.d.ts +163 -0
- package/dist/types/lib/live/types.d.ts +19 -1
- package/dist/types/lib/live/videoTrack.d.ts +96 -0
- package/dist/types/lib/live/videoWire.d.ts +35 -0
- package/dist/types/lib/live/wire.d.ts +4 -0
- package/dist/types/lib/panelChartSettings.d.ts +40 -1
- package/dist/types/lib/recordings/export.d.ts +1 -0
- package/dist/types/lib/recordings/videoSource.d.ts +56 -0
- package/dist/types/lib/render/alertGlyph.d.ts +7 -0
- package/dist/types/lib/render/glSeries.d.ts +1 -1
- package/dist/types/lib/segments/align.d.ts +85 -0
- package/dist/types/lib/segments/liveAxis.d.ts +58 -0
- package/dist/types/lib/segments/rules.d.ts +77 -0
- package/dist/types/lib/workspaces/io.d.ts +6 -0
- package/dist/types/lib/yAxisTicks.d.ts +11 -0
- package/dist/types/rules/compile.d.ts +47 -0
- package/dist/types/rules/evaluator.d.ts +51 -0
- package/dist/types/rules/index.d.ts +4 -0
- package/dist/types/rules/threshold.d.ts +3 -0
- package/dist/types/rules/types.d.ts +89 -0
- package/dist/types/rules/validate.d.ts +6 -0
- package/dist/types/types/loadedDataset.d.ts +5 -0
- package/dist/types/types/plotSeries.d.ts +5 -0
- package/package.json +7 -2
- package/dist/importers-DHeUdZcP.js +0 -5
- package/dist/krc-BIfw0rX1.js +0 -9
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { VideoMessage } from './videoWire';
|
|
2
|
+
/** One complete encoded access unit (H.264), never a decoded frame. */
|
|
3
|
+
export interface EncodedUnit {
|
|
4
|
+
t: number;
|
|
5
|
+
seq: number;
|
|
6
|
+
key: boolean;
|
|
7
|
+
data: Uint8Array;
|
|
8
|
+
arrivedAt: number;
|
|
9
|
+
}
|
|
10
|
+
export interface VideoTrackInfo {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
codec: string;
|
|
14
|
+
latestT: number | null;
|
|
15
|
+
lagMs: number | null;
|
|
16
|
+
units: number;
|
|
17
|
+
bytes: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A camera's video as the Camera panel plays it: a live camera connection's ring (kind 'live'), or a camera
|
|
21
|
+
* recorded with a cloud recording (kind 'recorded', RecordedVideoSource). Listed by engine.video.sources().
|
|
22
|
+
*/
|
|
23
|
+
export interface VideoSource {
|
|
24
|
+
/** The camera stream's id (the same for its live connection and its recordings). */
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
kind: 'live' | 'recorded';
|
|
28
|
+
/** The camera's data stream id; null when unknown. */
|
|
29
|
+
parentId: string | null;
|
|
30
|
+
/** Live: a camera's low layer names its high camera (the Camera panel picks the layer; pickers skip it). */
|
|
31
|
+
lowOf?: string | null;
|
|
32
|
+
/** Recorded: the parent data stream's name, for labels when that stream isn't connected. */
|
|
33
|
+
parentName?: string | null;
|
|
34
|
+
/** Recorded: the data recording it was recorded with (that dataset's info.meta.recordingId). */
|
|
35
|
+
recordingId?: string | null;
|
|
36
|
+
info(): VideoTrackInfo;
|
|
37
|
+
/** Earliest and latest capture times (Unix s), or null. */
|
|
38
|
+
range(): [number, number] | null;
|
|
39
|
+
/** Units to decode to show the frame at capture time `t` (Unix s): the last keyframe <= t through the last unit <= t. */
|
|
40
|
+
seekPlan(t: number): EncodedUnit[] | Promise<EncodedUnit[]>;
|
|
41
|
+
/** Live: the newest keyframe and everything after it. */
|
|
42
|
+
livePlan?(): EncodedUnit[];
|
|
43
|
+
/** Live: each new unit; returns an unsubscribe. */
|
|
44
|
+
onUnit?(fn: (u: EncodedUnit) => void): () => void;
|
|
45
|
+
/** Live: hold the video while it is shown; returns the release. */
|
|
46
|
+
acquire?(): () => void;
|
|
47
|
+
/** Recorded: resolves once the codec is known (info().codec). */
|
|
48
|
+
ready?(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/** A live camera connection's track as a VideoSource (the same object per track while id/name/parent stay). */
|
|
51
|
+
export declare function liveVideoSource(c: {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
parentId: string | null;
|
|
55
|
+
lowOf?: string | null;
|
|
56
|
+
video: VideoTrack;
|
|
57
|
+
}): VideoSource;
|
|
58
|
+
/** Per-camera ring of encoded units: reassembles fragments, bounds memory at GOP boundaries, plans decodes. */
|
|
59
|
+
export declare class VideoTrack {
|
|
60
|
+
private ring;
|
|
61
|
+
private bytes;
|
|
62
|
+
private needKey;
|
|
63
|
+
private width;
|
|
64
|
+
private height;
|
|
65
|
+
private codec;
|
|
66
|
+
private pending;
|
|
67
|
+
private subs;
|
|
68
|
+
private holders;
|
|
69
|
+
private demand;
|
|
70
|
+
private maxBytes;
|
|
71
|
+
private now;
|
|
72
|
+
constructor(maxBytes?: number, now?: () => number);
|
|
73
|
+
/** Feed a decoded KIND_VIDEO message; returns the completed unit, or null while incomplete or discarded. */
|
|
74
|
+
push(m: VideoMessage): EncodedUnit | null;
|
|
75
|
+
/** Drop whole GOPs from the front while over budget; the only GOP is never dropped. */
|
|
76
|
+
private trim;
|
|
77
|
+
/** Units to decode to show the frame at wall time `t` (unix s): last keyframe <= t through last unit <= t. */
|
|
78
|
+
seekPlan(t: number): EncodedUnit[];
|
|
79
|
+
/** The newest keyframe and everything after it. */
|
|
80
|
+
livePlan(): EncodedUnit[];
|
|
81
|
+
/** Called with each completed unit added to the ring. Returns an unsubscribe. */
|
|
82
|
+
onUnit(fn: (u: EncodedUnit) => void): () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Hold the video while it is shown (a Camera panel): the connection downloads only while
|
|
85
|
+
* someone holds it. Returns the release (calling it again does nothing).
|
|
86
|
+
*/
|
|
87
|
+
acquire(): () => void;
|
|
88
|
+
/** The connection's hook: called with true when the first holder arrives, false when the last leaves. */
|
|
89
|
+
onDemandChange(fn: (wanted: boolean) => void): void;
|
|
90
|
+
info(): VideoTrackInfo;
|
|
91
|
+
/** Earliest and latest buffered capture times, or null. */
|
|
92
|
+
range(): [number, number] | null;
|
|
93
|
+
/** After a gap (e.g. a rejoin): drop the half-received unit and skip deltas until the next keyframe. The ring stays. */
|
|
94
|
+
resync(): void;
|
|
95
|
+
clear(): void;
|
|
96
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaintext of a KIND_VIDEO relay message: one H.264 access unit (Annex B), or one
|
|
3
|
+
* fragment of it, stamped with its capture time in Unix seconds. A keyframe's first
|
|
4
|
+
* fragment carries the codec string, so a viewer joining mid-stream configures its
|
|
5
|
+
* decoder from it (Annex B keyframes carry SPS/PPS). Byte-compatible with
|
|
6
|
+
* packages/python/src/kymoscope/wire.py (encode_video / decode_video).
|
|
7
|
+
*/
|
|
8
|
+
export declare const VIDEO_VERSION = 1;
|
|
9
|
+
export declare const VIDEO_CODEC_H264 = 1;
|
|
10
|
+
/** Fragments stay under the cloud relay's 1 MiB message limit with room for the header and seal. */
|
|
11
|
+
export declare const VIDEO_MAX_FRAGMENT: number;
|
|
12
|
+
export interface VideoMessage {
|
|
13
|
+
key: boolean;
|
|
14
|
+
last: boolean;
|
|
15
|
+
t: number;
|
|
16
|
+
seq: number;
|
|
17
|
+
fragIndex: number;
|
|
18
|
+
fragCount: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
codec: string;
|
|
22
|
+
payload: Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
export declare function encodeVideo(m: VideoMessage): Uint8Array;
|
|
25
|
+
export declare function decodeVideo(b: Uint8Array): VideoMessage | null;
|
|
26
|
+
/** One access unit as the plaintexts to seal, split to VIDEO_MAX_FRAGMENT. */
|
|
27
|
+
export declare function fragmentVideo(au: {
|
|
28
|
+
key: boolean;
|
|
29
|
+
t: number;
|
|
30
|
+
seq: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
codec: string;
|
|
34
|
+
data: Uint8Array;
|
|
35
|
+
}): Uint8Array[];
|
|
@@ -6,6 +6,10 @@ export declare const KIND_COLUMNS = 3;
|
|
|
6
6
|
export declare const KIND_BLOCK = 4;
|
|
7
7
|
/** The channel table KIND_BLOCK messages refer to (see blockWire.ts). */
|
|
8
8
|
export declare const KIND_BLOCK_SCHEMA = 5;
|
|
9
|
+
/** One encoded video access unit or a fragment of one (see videoWire.ts). */
|
|
10
|
+
export declare const KIND_VIDEO = 6;
|
|
11
|
+
/** Each channel's last value and its time, against a KIND_BLOCK_SCHEMA (see blockWire.ts). */
|
|
12
|
+
export declare const KIND_LAST_VALUES = 7;
|
|
9
13
|
export declare const KEY_ID_FLAG = 128;
|
|
10
14
|
export interface SealedMessage {
|
|
11
15
|
kind: number;
|
|
@@ -372,12 +372,24 @@ export interface GanttPanelChartSettings {
|
|
|
372
372
|
gtEndCol: string;
|
|
373
373
|
gtGroupCol: string;
|
|
374
374
|
}
|
|
375
|
+
export interface CameraPanelSettings {
|
|
376
|
+
kind: 'camera';
|
|
377
|
+
/** The camera stream's id; '' until chosen. Always the first of `cameras` (kept for settings saved before walls). */
|
|
378
|
+
cameraStreamId: string;
|
|
379
|
+
/** The cameras shown, in order (up to MAX_PANEL_CAMERAS): two or more make a wall. See panelCameras. */
|
|
380
|
+
cameras: string[];
|
|
381
|
+
/** The data stream this camera syncs with; '' = its own stream (the camera's parent) when connected, else the first live data stream. */
|
|
382
|
+
syncStreamId: string;
|
|
383
|
+
/** Manual correction, ms (−10000..10000). */
|
|
384
|
+
offsetMs: number;
|
|
385
|
+
fit: 'contain' | 'cover';
|
|
386
|
+
}
|
|
375
387
|
/** Settings every chart kind has besides its own. */
|
|
376
388
|
export interface CommonPanelChartSettings {
|
|
377
389
|
/** Marks drawn over the chart (text, brush, arrows, boxes, lines). */
|
|
378
390
|
annotations?: ChartAnnotation[];
|
|
379
391
|
}
|
|
380
|
-
export type PanelChartSettings = CommonPanelChartSettings & (MultibandPanelChartSettings | XyPanelChartSettings | XyzPanelChartSettings | HistogramPanelChartSettings | PolarPanelChartSettings | SpectrumPanelChartSettings | BoxPlotPanelChartSettings | SpectrogramPanelChartSettings | HeatmapPanelChartSettings | ViolinPanelChartSettings | ConfusionPanelChartSettings | RocPanelChartSettings | LossCurvePanelChartSettings | ControlChartPanelChartSettings | ParallelCoordsPanelChartSettings | EmbeddingPanelChartSettings | FlameGraphPanelChartSettings | BarChartPanelChartSettings | RadarPanelChartSettings | AreaChartPanelChartSettings | CdfChartPanelChartSettings | BubbleChartPanelChartSettings | TreemapPanelChartSettings | SankeyPanelChartSettings | CalibrationPanelChartSettings | GaugePanelChartSettings | QQPlotPanelChartSettings | GanttPanelChartSettings);
|
|
392
|
+
export type PanelChartSettings = CommonPanelChartSettings & (MultibandPanelChartSettings | XyPanelChartSettings | XyzPanelChartSettings | HistogramPanelChartSettings | PolarPanelChartSettings | SpectrumPanelChartSettings | BoxPlotPanelChartSettings | SpectrogramPanelChartSettings | HeatmapPanelChartSettings | ViolinPanelChartSettings | ConfusionPanelChartSettings | RocPanelChartSettings | LossCurvePanelChartSettings | ControlChartPanelChartSettings | ParallelCoordsPanelChartSettings | EmbeddingPanelChartSettings | FlameGraphPanelChartSettings | BarChartPanelChartSettings | RadarPanelChartSettings | AreaChartPanelChartSettings | CdfChartPanelChartSettings | BubbleChartPanelChartSettings | TreemapPanelChartSettings | SankeyPanelChartSettings | CalibrationPanelChartSettings | GaugePanelChartSettings | QQPlotPanelChartSettings | GanttPanelChartSettings | CameraPanelSettings);
|
|
381
393
|
/** Parse optional axis range from min/max strings (same rules as App useMemo). */
|
|
382
394
|
export declare function parseOptionalAxisRange(minStr: string, maxStr: string): [number, number] | undefined;
|
|
383
395
|
/** Keep in sync with `savedLayout.ts` defaults. */
|
|
@@ -412,8 +424,35 @@ export declare function defaultGaugePanelSettings(): GaugePanelChartSettings;
|
|
|
412
424
|
export declare function defaultCalibrationPanelSettings(): CalibrationPanelChartSettings;
|
|
413
425
|
export declare function defaultQQPlotPanelSettings(): QQPlotPanelChartSettings;
|
|
414
426
|
export declare function defaultGanttPanelSettings(): GanttPanelChartSettings;
|
|
427
|
+
/** A camera in pickers: "Bench 3 · Camera 1" (its data stream's name: connected, or a recorded camera's parentName),
|
|
428
|
+
* else the camera's own name. */
|
|
429
|
+
export declare function cameraLabel(cam: {
|
|
430
|
+
name: string;
|
|
431
|
+
parentId?: string | null;
|
|
432
|
+
parentName?: string | null;
|
|
433
|
+
}, live: readonly {
|
|
434
|
+
id: string;
|
|
435
|
+
name: string;
|
|
436
|
+
}[]): string;
|
|
437
|
+
export declare const defaultCameraPanelSettings: () => CameraPanelSettings;
|
|
438
|
+
/** A Camera panel shows at most this many cameras (a 3x3 wall). */
|
|
439
|
+
export declare const MAX_PANEL_CAMERAS = 9;
|
|
440
|
+
/** The cameras a Camera panel shows: `cameras` while it starts with cameraStreamId, else just cameraStreamId
|
|
441
|
+
* (a host that sets only cameraStreamId, as before walls, gets that one camera). */
|
|
442
|
+
export declare function panelCameras(s: Pick<CameraPanelSettings, 'cameraStreamId' | 'cameras'>): string[];
|
|
415
443
|
/** An alarm line from untrusted input, or null. */
|
|
416
444
|
export declare function coerceAlarmLine(v: unknown): AlarmLine | null;
|
|
445
|
+
/** What a linked line shows for its rule: the rule's threshold, and whether the rule is active now. */
|
|
446
|
+
export interface LinkedRuleLine {
|
|
447
|
+
value: number;
|
|
448
|
+
active: boolean;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Lines linked to rules the runtime holds draw the rule's threshold and state (`linked`). Walks the four alarm
|
|
452
|
+
* places (multiband series, the simple kinds' alarm field, gauge rows, X-Y / X-Y-Z axes). Returns `s` itself when no
|
|
453
|
+
* line resolves, so memoised charts don't redraw.
|
|
454
|
+
*/
|
|
455
|
+
export declare function resolveLinkedAlarms(s: PanelChartSettings, rules: ReadonlyMap<string, LinkedRuleLine>): PanelChartSettings;
|
|
417
456
|
/** The setting holding the alarm line of the chart kinds whose frame draws it. */
|
|
418
457
|
export declare const CHART_ALARM_FIELDS: {
|
|
419
458
|
readonly histogram: "histAlarm";
|
|
@@ -15,6 +15,7 @@ export interface ExportOptions {
|
|
|
15
15
|
export declare const EXPORT_TYPES: {
|
|
16
16
|
readonly csv: "text/csv";
|
|
17
17
|
readonly mf4: "application/octet-stream";
|
|
18
|
+
readonly parquet: "application/vnd.apache.parquet";
|
|
18
19
|
};
|
|
19
20
|
/**
|
|
20
21
|
* A recording as a CSV or MF4 file, built in the browser from its encrypted chunks and handed to `write` piece by
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type MessageKey } from '../live/wire';
|
|
2
|
+
import type { EncodedUnit, VideoSource, VideoTrackInfo } from '../live/videoTrack';
|
|
3
|
+
export interface RecordedVideoSourceOptions {
|
|
4
|
+
/** The camera stream's id (what a Camera panel's cameraStreamId names). */
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
/** The camera's data stream id. */
|
|
8
|
+
parentId: string | null;
|
|
9
|
+
/** The data stream's name (labels "Stream · Camera" when that stream isn't connected). */
|
|
10
|
+
parentName?: string | null;
|
|
11
|
+
/** The data recording the camera was recorded with: the recording dataset's info.meta.recordingId. */
|
|
12
|
+
recordingId: string;
|
|
13
|
+
/** The camera recording's chunks: relay times (ms since epoch) of each one's first and last message. */
|
|
14
|
+
chunks: {
|
|
15
|
+
seq: number;
|
|
16
|
+
t0: number;
|
|
17
|
+
t1: number;
|
|
18
|
+
}[];
|
|
19
|
+
fetchChunk(seq: number): Promise<ArrayBuffer>;
|
|
20
|
+
/** The camera's key(s). */
|
|
21
|
+
open: MessageKey;
|
|
22
|
+
/** Decoded units kept, in bytes (default 256 MB); least recently used chunks go first. */
|
|
23
|
+
maxBytes?: number;
|
|
24
|
+
}
|
|
25
|
+
export declare class RecordedVideoSource implements VideoSource {
|
|
26
|
+
readonly kind: "recorded";
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly parentId: string | null;
|
|
30
|
+
readonly parentName: string | null;
|
|
31
|
+
readonly recordingId: string;
|
|
32
|
+
private chunks;
|
|
33
|
+
private fetch;
|
|
34
|
+
private open;
|
|
35
|
+
private maxBytes;
|
|
36
|
+
/** By chunk index, least recently used first. */
|
|
37
|
+
private cache;
|
|
38
|
+
/** Settled entries: [bytes, units]. */
|
|
39
|
+
private sizes;
|
|
40
|
+
private bytes;
|
|
41
|
+
private width;
|
|
42
|
+
private height;
|
|
43
|
+
private codec;
|
|
44
|
+
private waiting;
|
|
45
|
+
constructor(o: RecordedVideoSourceOptions);
|
|
46
|
+
private parse;
|
|
47
|
+
private parsed;
|
|
48
|
+
private evict;
|
|
49
|
+
/** Chunk i's units in order, its last one finished from the next chunk; [] when it can't be downloaded. */
|
|
50
|
+
private units;
|
|
51
|
+
seekPlan(t: number): Promise<EncodedUnit[]>;
|
|
52
|
+
/** Resolves once the codec is known (the first keyframe of the first chunks), or they had none. */
|
|
53
|
+
ready(): Promise<void>;
|
|
54
|
+
info(): VideoTrackInfo;
|
|
55
|
+
range(): [number, number] | null;
|
|
56
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A 10 px bell, drawn at the label end of an alarm line linked to an alert rule (canvas and SVG share the path). */
|
|
2
|
+
export declare const ALERT_GLYPH_PATH = "M5 .8a3.1 3.1 0 0 0-3.1 3.1v2.3L.8 7.6h8.4L8.1 6.2V3.9A3.1 3.1 0 0 0 5 .8zM3.9 8.4a1.1 1.1 0 0 0 2.2 0z";
|
|
3
|
+
export declare const ALERT_GLYPH_SIZE = 10;
|
|
4
|
+
/** A linked line is dashed while its rule is active (spec §6.1.1); otherwise it keeps its own style. */
|
|
5
|
+
export declare const ACTIVE_DASH: number[];
|
|
6
|
+
/** Paint the bell with its top-left at (x, y). */
|
|
7
|
+
export declare function drawAlertGlyph(ctx: CanvasRenderingContext2D, x: number, y: number, color: string): void;
|
|
@@ -4,7 +4,7 @@ export interface GpuSeriesStyle {
|
|
|
4
4
|
bandBottom: number;
|
|
5
5
|
scaleMin: number;
|
|
6
6
|
scaleMax: number;
|
|
7
|
-
/**
|
|
7
|
+
/** Mean consecutive |Δx| of the column (0 if unknown): drives gap-splitting (see joinGapThresholdForColumn). */
|
|
8
8
|
gapMedian: number;
|
|
9
9
|
/** Line thickness in CSS px; defaults to the renderer's `lineWidth`. */
|
|
10
10
|
width?: number;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type CompareOp } from './rules';
|
|
2
|
+
export type AlignAxis = {
|
|
3
|
+
kind: 'elapsed';
|
|
4
|
+
preroll_s?: number;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'event';
|
|
7
|
+
channel: string;
|
|
8
|
+
op: CompareOp;
|
|
9
|
+
value: number;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'cumulative';
|
|
12
|
+
channel: string;
|
|
13
|
+
integral?: boolean;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'clock';
|
|
16
|
+
tz: string;
|
|
17
|
+
};
|
|
18
|
+
export interface AlignedSegment {
|
|
19
|
+
x: Float64Array;
|
|
20
|
+
t: Float64Array;
|
|
21
|
+
cols: Map<string, Float64Array>;
|
|
22
|
+
}
|
|
23
|
+
export interface ReferenceChannel {
|
|
24
|
+
mean: Float32Array;
|
|
25
|
+
sd: Float32Array;
|
|
26
|
+
min: Float32Array;
|
|
27
|
+
max: Float32Array;
|
|
28
|
+
n: Uint16Array;
|
|
29
|
+
}
|
|
30
|
+
export interface ReferenceCurve {
|
|
31
|
+
x: Float64Array;
|
|
32
|
+
channels: Map<string, ReferenceChannel>;
|
|
33
|
+
}
|
|
34
|
+
export interface Comparison {
|
|
35
|
+
/** Per sample of the segment: value − reference mean at its X (NaN where either is missing). */
|
|
36
|
+
delta: Map<string, Float64Array>;
|
|
37
|
+
/** Highest first: mean |delta| / σ (the grid point's σ with ≥ 2 sources, else the channel's spread over the grid). */
|
|
38
|
+
score: Array<{
|
|
39
|
+
channel: string;
|
|
40
|
+
z: number;
|
|
41
|
+
}>;
|
|
42
|
+
/** Runs out of band: from the first sample out to the first sample back in (or the last sample). */
|
|
43
|
+
deviations: Array<{
|
|
44
|
+
t0: number;
|
|
45
|
+
t1: number;
|
|
46
|
+
channels: string[];
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export declare const MAX_GRID = 8000;
|
|
50
|
+
/** ponytail: channels × grid points of one reference (2.4 MB raw); split references by channel group if a customer needs more. */
|
|
51
|
+
export declare const MAX_BAND_CELLS = 131072;
|
|
52
|
+
export declare function axisColumn(a: AlignAxis, units?: Record<string, string>): {
|
|
53
|
+
name: string;
|
|
54
|
+
unit: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function localSeconds(t: number, tz: string): number;
|
|
57
|
+
/** X of one segment's samples, fed in time order: history in one pass, live sample by sample. */
|
|
58
|
+
export declare class AxisState {
|
|
59
|
+
#private;
|
|
60
|
+
readonly axis: AlignAxis;
|
|
61
|
+
constructor(axis: AlignAxis);
|
|
62
|
+
/** A segment starts at t0 (resets the state). */
|
|
63
|
+
begin(t0: number): void;
|
|
64
|
+
/** X at time t; `c` is the axis channel's value there (NaN when it has none). NaN when undefined (live: before an event). */
|
|
65
|
+
x(t: number, c: number): number;
|
|
66
|
+
}
|
|
67
|
+
/** A segment's samples (t and NaN-padded columns, e.g. wideDay of its pieces) on `axis`; `tstart` is its start. For
|
|
68
|
+
* `event` the event is searched over the whole segment first, so samples before it get negative X. */
|
|
69
|
+
export declare function alignSegment(t: Float64Array, cols: Map<string, Float64Array>, tstart: number, axis: AlignAxis): AlignedSegment;
|
|
70
|
+
/** y(x) at the grid points: linear between finite neighbours; NaN outside the data or across a gap wider than 4× the
|
|
71
|
+
* median step. Unsorted X (a noisy cumulative tag) is sorted first. */
|
|
72
|
+
export declare function resample(x: Float64Array, y: ArrayLike<number>, grid: Float64Array): Float64Array;
|
|
73
|
+
/** A grid array's value at x (linear; NaN outside the grid or next to a NaN). */
|
|
74
|
+
export declare function gridAt(grid: Float64Array, a: ArrayLike<number>, x: number): number;
|
|
75
|
+
/** The reference of `segs` on a uniform grid of `points` over their X range (one segment: σ 0, n 1). */
|
|
76
|
+
export declare function buildReference(segs: AlignedSegment[], channels: string[], points: number): ReferenceCurve;
|
|
77
|
+
/** A channel's band edges: mean ± k·σ, or min..max. */
|
|
78
|
+
export declare function bandEdges(c: ReferenceChannel, k: number, band: 'sigma' | 'minmax'): {
|
|
79
|
+
lo: Float32Array;
|
|
80
|
+
hi: Float32Array;
|
|
81
|
+
};
|
|
82
|
+
export declare function compareToReference(seg: AlignedSegment, ref: ReferenceCurve, k: number, band?: 'sigma' | 'minmax', minS?: number): Comparison;
|
|
83
|
+
/** A reference curve as bytes (plan Formats "Reference band", zlib). */
|
|
84
|
+
export declare function encodeBand(ref: ReferenceCurve, channels: string[]): Uint8Array;
|
|
85
|
+
export declare function decodeBand(bytes: Uint8Array, channels: string[]): ReferenceCurve;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live against a reference (Historian phase 5; spec E3 "Live against reference"; plan S6): on every ingested block the
|
|
3
|
+
* definition's rule runs over the new samples, and the open segment's X on the alignment axis is written into the ring
|
|
4
|
+
* as a computed column (`column`), restarting at each segment, so the beacon chart (cycles on that column) draws the
|
|
5
|
+
* open segment over the reference dataset with no React at data rate. With a reference, `<channel> Δ` columns (value −
|
|
6
|
+
* reference mean at the same X) are written too, and every sample is checked against the band where the reference has
|
|
7
|
+
* ≥ 2 segments (a single reference gives a delta, never deviations; as compareToReference): `onEvent` fires only on
|
|
8
|
+
* transitions (open, close, deviation start once it lasted minDeviationS, deviation end after minDeviationS back in band). Work is per block: a few arrays per
|
|
9
|
+
* block, nothing allocated per sample.
|
|
10
|
+
*/
|
|
11
|
+
import { type LiveBuffer } from '../live/buffer';
|
|
12
|
+
import { type AlignAxis } from './align';
|
|
13
|
+
import { type DetectedSegment, type KpiSpec, type SegmentRule } from './rules';
|
|
14
|
+
export declare const DELTA_SUFFIX = " \u0394";
|
|
15
|
+
export interface LiveReference {
|
|
16
|
+
grid: Float64Array;
|
|
17
|
+
/** Per channel: mean and band edges on the grid, and the segments behind each point (the band counts where n ≥ 2). */
|
|
18
|
+
channels: Map<string, {
|
|
19
|
+
mean: Float32Array;
|
|
20
|
+
lo: Float32Array;
|
|
21
|
+
hi: Float32Array;
|
|
22
|
+
n: ArrayLike<number>;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export type LiveSegmentEvent = {
|
|
26
|
+
type: 'open';
|
|
27
|
+
tstart: number;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'close';
|
|
30
|
+
segment: DetectedSegment;
|
|
31
|
+
} | {
|
|
32
|
+
type: 'deviation';
|
|
33
|
+
t0: number;
|
|
34
|
+
channels: string[];
|
|
35
|
+
} | {
|
|
36
|
+
type: 'deviation-end';
|
|
37
|
+
t0: number;
|
|
38
|
+
t1: number;
|
|
39
|
+
channels: string[];
|
|
40
|
+
};
|
|
41
|
+
export interface LiveSegmentAxis {
|
|
42
|
+
rule: SegmentRule;
|
|
43
|
+
kpis?: KpiSpec[];
|
|
44
|
+
axis: AlignAxis;
|
|
45
|
+
/** The computed X column written into the ring, and its unit. */
|
|
46
|
+
column: string;
|
|
47
|
+
unit: string;
|
|
48
|
+
/** The open segment's start when the ring may no longer hold it (the collector's open segment), else null. */
|
|
49
|
+
start?: number | null;
|
|
50
|
+
reference?: LiveReference | null;
|
|
51
|
+
/** A deviation is reported once out of band this long (s); default 5. */
|
|
52
|
+
minDeviationS?: number;
|
|
53
|
+
onEvent?: (e: LiveSegmentEvent) => void;
|
|
54
|
+
}
|
|
55
|
+
export declare function liveSegmentTracker(cfg: LiveSegmentAxis): {
|
|
56
|
+
/** Samples from absolute index `from` on. `quiet`: no events (a replay of samples already seen). */
|
|
57
|
+
feed(buf: LiveBuffer, from: number, quiet?: boolean): void;
|
|
58
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Segment rules (Historian phase 5; spec E1 "Segment definition"): where a stream is cut into segments, and the KPIs
|
|
3
|
+
* captured when a segment closes. One state machine for every use: a history read day by day (app segmentRun.ts), the
|
|
4
|
+
* live ring buffer (liveAxis.ts) and, from the same JSON, the collector (packages/collector/src/kymoscope_collector/
|
|
5
|
+
* segments.py), pinned by tests/vectors/segment-rules-v1.json. Semantics: the plan's Formats "Rule JSON". A NaN value
|
|
6
|
+
* never changes a rule. splitLaps (../beacon.ts) is the edge rule `reset` through resetStep.
|
|
7
|
+
*/
|
|
8
|
+
export type CompareOp = '>' | '>=' | '<' | '<=' | '==' | '!=';
|
|
9
|
+
export type EdgeOn = 'change' | 'rise' | 'fall' | 'reset';
|
|
10
|
+
export type SegmentRule = {
|
|
11
|
+
kind: 'manual';
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'edge';
|
|
14
|
+
channel: string;
|
|
15
|
+
on: EdgeOn;
|
|
16
|
+
value?: number;
|
|
17
|
+
} | {
|
|
18
|
+
kind: 'condition';
|
|
19
|
+
channel: string;
|
|
20
|
+
op: CompareOp;
|
|
21
|
+
value: number;
|
|
22
|
+
hysteresis?: number;
|
|
23
|
+
min_s?: number;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'window';
|
|
26
|
+
starts: string[];
|
|
27
|
+
tz: string;
|
|
28
|
+
};
|
|
29
|
+
export type KpiStat = 'min' | 'max' | 'mean' | 'integral' | 'first' | 'last' | 'delta';
|
|
30
|
+
export declare const KPI_STATS: KpiStat[];
|
|
31
|
+
export interface KpiSpec {
|
|
32
|
+
channel: string;
|
|
33
|
+
stat: KpiStat;
|
|
34
|
+
}
|
|
35
|
+
/** `duration` (s) and `<channel>:<stat>`; null when the channel had no sample in the segment. */
|
|
36
|
+
export type Kpis = Record<string, number | null>;
|
|
37
|
+
export interface DetectedSegment {
|
|
38
|
+
tstart: number;
|
|
39
|
+
tend: number | null;
|
|
40
|
+
kpis: Kpis;
|
|
41
|
+
}
|
|
42
|
+
export declare const kpiKey: (k: KpiSpec) => string;
|
|
43
|
+
export declare const ruleChannels: (r: SegmentRule) => string[];
|
|
44
|
+
export declare function compareOp(op: CompareOp, v: number, c: number): boolean;
|
|
45
|
+
/** A cycle's running state for resetStep; prev NaN: nothing seen yet. */
|
|
46
|
+
export interface ResetState {
|
|
47
|
+
prev: number;
|
|
48
|
+
lo: number;
|
|
49
|
+
hi: number;
|
|
50
|
+
}
|
|
51
|
+
export declare const newResetState: () => ResetState;
|
|
52
|
+
/** One value through the reset rule (laps, battery cycles): true when it starts a new cycle, a drop larger than half
|
|
53
|
+
* of the span seen since the cycle began, so jitter backwards never cuts. Mutates `s`. */
|
|
54
|
+
export declare function resetStep(s: ResetState, v: number): boolean;
|
|
55
|
+
/** Local wall clock minus UTC, in seconds, at instant t. */
|
|
56
|
+
export declare function tzOffsetS(t: number, tz: string): number;
|
|
57
|
+
/** The local date (YYYY-MM-DD) of t in tz. */
|
|
58
|
+
export declare function localDay(t: number, tz: string): string;
|
|
59
|
+
/** The instant of a local wall-clock time (a DST gap resolves forward, an overlap to the first occurrence). */
|
|
60
|
+
export declare function zonedInstant(day: string, hhmm: string, tz: string): number;
|
|
61
|
+
export declare const shiftDay: (day: string, n: number) => string;
|
|
62
|
+
export declare class RuleRunner {
|
|
63
|
+
#private;
|
|
64
|
+
readonly rule: SegmentRule;
|
|
65
|
+
readonly kpis: KpiSpec[];
|
|
66
|
+
constructor(rule: SegmentRule, kpis?: KpiSpec[]);
|
|
67
|
+
/** Continue a segment that started at `tstart`, before the data fed from now on (a live ring that no longer holds it). */
|
|
68
|
+
assumeOpen(tstart: number): void;
|
|
69
|
+
/**
|
|
70
|
+
* Samples in time order; returns the segments they closed. `col(name)`: the column of a channel, aligned with `t`
|
|
71
|
+
* (NaN where it has no value), or undefined. `each(i, start)`: after sample i, the start of the open segment (a
|
|
72
|
+
* condition still shorter than min_s counts), null outside one.
|
|
73
|
+
*/
|
|
74
|
+
feed(t: ArrayLike<number>, col: (name: string) => ArrayLike<number> | undefined, each?: (i: number, start: number | null) => void): DetectedSegment[];
|
|
75
|
+
/** The open segment so far (its KPIs up to the last sample; tend null), or null. A condition shows once it lasted min_s. */
|
|
76
|
+
open(): DetectedSegment | null;
|
|
77
|
+
}
|
|
@@ -4,6 +4,7 @@ import type { PanelChartSettings } from '../panelChartSettings';
|
|
|
4
4
|
import type { DashboardPanel, DashboardPanelKind } from '../../components/dashboardGridLayout';
|
|
5
5
|
import type { BeaconConfig } from '../beacon';
|
|
6
6
|
import type { MathChannel } from '../mathChannels/types';
|
|
7
|
+
import type { SegmentContext } from '../../engine/types';
|
|
7
8
|
type ExportedWorksheet = {
|
|
8
9
|
name: string;
|
|
9
10
|
xKey: string;
|
|
@@ -32,6 +33,8 @@ export interface WorkbookBody {
|
|
|
32
33
|
liveWindowSeconds: number | null;
|
|
33
34
|
/** Lap / cycle split, without the dataset it came from. */
|
|
34
35
|
laps: BeaconConfig | null;
|
|
36
|
+
/** The Segments panel's ids (Historian phase 5); absent in older bodies. */
|
|
37
|
+
segments?: SegmentContext | null;
|
|
35
38
|
}
|
|
36
39
|
/** What `exportWorkspace()` returns (envelope v2 since cloud workbooks). */
|
|
37
40
|
export type WorkspaceExportEnvelope = WorkbookBody;
|
|
@@ -74,6 +77,8 @@ export interface ParsedWorkbook extends ImportResult {
|
|
|
74
77
|
mathChannels: WorkbookChannel[];
|
|
75
78
|
liveWindowSeconds: number | null | undefined;
|
|
76
79
|
laps: BeaconConfig | null | undefined;
|
|
80
|
+
/** Undefined: a body from before segments (keep the current context). */
|
|
81
|
+
segments: SegmentContext | null | undefined;
|
|
77
82
|
}
|
|
78
83
|
export type ParsedKymoscopeFile = {
|
|
79
84
|
type: 'workspace';
|
|
@@ -100,6 +105,7 @@ export declare function buildWorkbookBody(s: {
|
|
|
100
105
|
}>;
|
|
101
106
|
liveWindowSeconds: number | null;
|
|
102
107
|
laps: BeaconConfig | null;
|
|
108
|
+
segments?: SegmentContext | null;
|
|
103
109
|
}): WorkbookBody;
|
|
104
110
|
export declare function buildWorkspaceExportBlob(worksheets: Worksheet[]): Blob;
|
|
105
111
|
export declare function buildWorksheetEnvelope(worksheet: Worksheet): WorksheetExportEnvelope;
|
|
@@ -26,3 +26,14 @@ export declare function formatTick(v: number, step: number): string;
|
|
|
26
26
|
* at any scale (0.6523, 3.142, 12035), SI prefixes outside 0.001..1e6.
|
|
27
27
|
*/
|
|
28
28
|
export declare function formatValue(v: number): string;
|
|
29
|
+
/** X reads as clock time: a seconds axis ("Name (s)") whose both ends are Unix times of 2000–2100 (collector streams
|
|
30
|
+
* and Historian ranges carry Unix seconds in ElapsedTime). */
|
|
31
|
+
export declare function isClockAxis(xLabel: string, lo: number, hi: number): boolean;
|
|
32
|
+
export declare function setClockTimeZone(tz: string | undefined): void;
|
|
33
|
+
export declare const getClockTimeZone: () => string | undefined;
|
|
34
|
+
export declare function subscribeClockTimeZone(cb: () => void): () => void;
|
|
35
|
+
/** A clock tick (the clock zone unless `timeZone`): the date from a day's step, date and minutes across days, minutes,
|
|
36
|
+
* seconds, then milliseconds. ponytail: ticks stay evenly spaced, not on round times; snap to round times if asked. */
|
|
37
|
+
export declare function formatClockTick(v: number, step: number, span: number, timeZone?: string | undefined): string;
|
|
38
|
+
/** The crosshair readout on a clock axis: date, year and time to the millisecond. */
|
|
39
|
+
export declare function formatClockValue(v: number, timeZone?: string | undefined): string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Derived, RuleDoc } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* A rule compiled for block evaluation: the condition tree flattened into ops in post-order (children before their
|
|
4
|
+
* parent, the root last), so each op fills one Int8Array of tri-states (0 false, 1 unknown, 2 true) per block with a
|
|
5
|
+
* plain typed loop. No closures per row.
|
|
6
|
+
*/
|
|
7
|
+
export type Op = {
|
|
8
|
+
k: 'above' | 'below' | 'outside' | 'inside' | 'equals' | 'changes' | 'noData';
|
|
9
|
+
i: number;
|
|
10
|
+
v: number;
|
|
11
|
+
lo: number;
|
|
12
|
+
hi: number;
|
|
13
|
+
h: number;
|
|
14
|
+
f: number;
|
|
15
|
+
prev: number;
|
|
16
|
+
/** Where the leaf writes: its own slot (mode 0), or straight into its all/any parent's (0 first, then min / max). */
|
|
17
|
+
into: number;
|
|
18
|
+
mode: 0 | 1 | 2;
|
|
19
|
+
} | {
|
|
20
|
+
k: 'all' | 'any';
|
|
21
|
+
kids: number[]; /** the kids that are not leaves written into this slot */
|
|
22
|
+
rest: number[];
|
|
23
|
+
fused: boolean;
|
|
24
|
+
} | {
|
|
25
|
+
k: 'not';
|
|
26
|
+
kid: number;
|
|
27
|
+
};
|
|
28
|
+
export interface Compiled {
|
|
29
|
+
aliases: string[];
|
|
30
|
+
base: number;
|
|
31
|
+
derived: Array<{
|
|
32
|
+
i: number;
|
|
33
|
+
d: Derived;
|
|
34
|
+
src: number[];
|
|
35
|
+
}>;
|
|
36
|
+
ops: Op[];
|
|
37
|
+
/** Per alias: a `changes` leaf reads its previous sample value. */
|
|
38
|
+
needPrev: boolean[];
|
|
39
|
+
/** Per alias: something reads the time of its last sample (a noData leaf, or staleS). */
|
|
40
|
+
needAt: boolean[];
|
|
41
|
+
/** The peak's signal (spec §2.3.6): the first leaf's alias and how far a value is past its threshold (> 0: past). */
|
|
42
|
+
first: {
|
|
43
|
+
i: number;
|
|
44
|
+
excess: (x: number) => number;
|
|
45
|
+
} | null;
|
|
46
|
+
}
|
|
47
|
+
export declare function compileRule(r: RuleDoc): Compiled;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { RuleDoc } from './types';
|
|
2
|
+
export interface RuleTarget {
|
|
3
|
+
kind: 'stream' | 'history' | 'dataset';
|
|
4
|
+
id: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
tags?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export type RuleStateName = 'disabled' | 'not_applicable' | 'waiting' | 'idle' | 'pending' | 'active' | 'clearing';
|
|
9
|
+
export interface AlertTransition {
|
|
10
|
+
ruleId: string;
|
|
11
|
+
ruleVersion: number;
|
|
12
|
+
target: RuleTarget;
|
|
13
|
+
kind: 'raised' | 'cleared' | 'lost';
|
|
14
|
+
t: number;
|
|
15
|
+
peak?: {
|
|
16
|
+
v: number;
|
|
17
|
+
t: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface RuleEvaluatorState {
|
|
21
|
+
state: RuleStateName;
|
|
22
|
+
missing?: string[];
|
|
23
|
+
since?: number;
|
|
24
|
+
late: number;
|
|
25
|
+
lastT: number;
|
|
26
|
+
}
|
|
27
|
+
export interface LiveBlock {
|
|
28
|
+
t: Float64Array;
|
|
29
|
+
columns: Record<string, Float64Array | undefined>;
|
|
30
|
+
/** Optional: pass the same (empty) map with one block to every evaluator that reads it, and the per-column checks
|
|
31
|
+
* (no NaN, ascending time) run once per block instead of once per rule. Don't reuse it for another block. */
|
|
32
|
+
scan?: Map<string, boolean>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* One rule on one target (spec §2.3). Pure: no DOM, no timers. `bind` with the target's channel names whenever they
|
|
36
|
+
* change, `push` appended rows in time order, `tick` to advance the timed parts (noData, forS, clearForS).
|
|
37
|
+
*
|
|
38
|
+
* A block is evaluated column-wise: first the rows the rule evaluates (a sample of one of its signals, later than the
|
|
39
|
+
* last evaluated time), then per alias the held value / time of its last sample / "new sample here" arrays, then one
|
|
40
|
+
* typed loop per condition op, then the state machine over the root's tri-states. A block where every signal has a
|
|
41
|
+
* sample on every row in ascending time (the common live case) uses the columns as they are, without copying.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createRuleEvaluator(rule: RuleDoc, target: RuleTarget): {
|
|
44
|
+
rule: RuleDoc;
|
|
45
|
+
target: RuleTarget;
|
|
46
|
+
bind: (names: Iterable<string>) => AlertTransition[];
|
|
47
|
+
push: (block: LiveBlock) => AlertTransition[];
|
|
48
|
+
tick: (now: number) => AlertTransition[];
|
|
49
|
+
state: () => RuleEvaluatorState;
|
|
50
|
+
};
|
|
51
|
+
export type RuleEvaluator = ReturnType<typeof createRuleEvaluator>;
|