@kymoscope/sdk 0.3.0 → 0.5.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-Y-PAIexV.js +5 -0
- package/dist/keys-DMRJGG6U.js +10 -0
- package/dist/kymoscope-embed.js +92 -90
- package/dist/kymoscope-sdk.js +87 -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 +3 -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 +111 -3
- 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 +69 -4
- package/dist/types/index.d.ts +29 -4
- package/dist/types/lib/annotations.d.ts +20 -0
- package/dist/types/lib/beacon.d.ts +2 -1
- package/dist/types/lib/cycles/cut.d.ts +48 -0
- package/dist/types/lib/cycles/evaluator.d.ts +127 -0
- 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 +10 -0
- package/dist/types/lib/live/publisher.d.ts +168 -0
- package/dist/types/lib/live/types.d.ts +21 -3
- 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 +65 -0
- package/dist/types/lib/segments/rules.d.ts +91 -0
- package/dist/types/lib/workspaces/io.d.ts +12 -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 +20 -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,56 @@
|
|
|
1
|
+
import { type AlertTransition, type LiveBlock, type RuleTarget } from '../rules/evaluator';
|
|
2
|
+
import { type RuleProblem } from '../rules/validate';
|
|
3
|
+
import type { RuleDoc, Severity } from '../rules/types';
|
|
4
|
+
/** A span on the charts from one rule episode (read-only; never stored in chart settings). t1 null: still open. */
|
|
5
|
+
export interface ChartMark {
|
|
6
|
+
id: string;
|
|
7
|
+
ruleId: string;
|
|
8
|
+
ruleName: string;
|
|
9
|
+
severity: Severity;
|
|
10
|
+
targetId: string;
|
|
11
|
+
timeColumn: string;
|
|
12
|
+
t0: number;
|
|
13
|
+
t1: number | null;
|
|
14
|
+
}
|
|
15
|
+
export interface RuleStateInfo {
|
|
16
|
+
ruleId: string;
|
|
17
|
+
target: RuleTarget;
|
|
18
|
+
state: string;
|
|
19
|
+
missing?: string[];
|
|
20
|
+
since?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface AlertsHost {
|
|
23
|
+
/** Targets now open, with their channel names. */
|
|
24
|
+
targets(): Array<RuleTarget & {
|
|
25
|
+
channels: string[];
|
|
26
|
+
}>;
|
|
27
|
+
maxRules(): number | null;
|
|
28
|
+
emit(t: AlertTransition): void;
|
|
29
|
+
limit(): void;
|
|
30
|
+
setMarks(marks: ChartMark[]): void;
|
|
31
|
+
setStates(s: RuleStateInfo[]): void;
|
|
32
|
+
/** DataSource.readColumns of a loaded dataset. */
|
|
33
|
+
readDataset(id: string, columns: string[], offset: number, limit: number): Promise<Record<string, Float64Array>>;
|
|
34
|
+
}
|
|
35
|
+
export declare function createAlerts(host: AlertsHost): {
|
|
36
|
+
/** Replace the rule set (the host's whole list). Returns the problems of the refused rules. */
|
|
37
|
+
setRules(docs: RuleDoc[]): Array<RuleProblem & {
|
|
38
|
+
ruleId: string;
|
|
39
|
+
}>;
|
|
40
|
+
rules: () => RuleDoc[];
|
|
41
|
+
state: () => RuleStateInfo[];
|
|
42
|
+
/** Evaluate the rules over a loaded dataset from its first row (fresh evaluators: "Test on loaded data"). */
|
|
43
|
+
evaluate(datasetId: string, o: {
|
|
44
|
+
timeColumn: string;
|
|
45
|
+
ruleIds?: string[];
|
|
46
|
+
}): Promise<AlertTransition[]>;
|
|
47
|
+
/** Live: called by the live controller with the newly appended rows of a stream. */
|
|
48
|
+
pushLive(streamId: string, block: LiveBlock): void;
|
|
49
|
+
tickLive(streamId: string, t: number): void;
|
|
50
|
+
/** The channel names the rules bound on a stream use (what pushLive needs from the buffer). */
|
|
51
|
+
liveColumns(streamId: string): string[];
|
|
52
|
+
/** The host's targets or their channel sets changed (a dataset loaded, a stream's schema grew). */
|
|
53
|
+
sync: () => void;
|
|
54
|
+
clearMarks(targetId?: string): void;
|
|
55
|
+
};
|
|
56
|
+
export type EngineAlerts = ReturnType<typeof createAlerts>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LoadedDataset } from '../types/loadedDataset';
|
|
2
|
+
import { type HistoryPiece } from '../lib/data/historyDataSource';
|
|
2
3
|
/** Columnar numeric data handed over by the host. */
|
|
3
4
|
export interface ColumnsInput {
|
|
4
5
|
name: string;
|
|
@@ -11,6 +12,11 @@ export interface ColumnsInput {
|
|
|
11
12
|
* times a second, where the copy is most of the cost.
|
|
12
13
|
*/
|
|
13
14
|
transfer?: boolean;
|
|
15
|
+
/** Bands to shade under columns (a reference's envelope, Historian phase 5): edges aligned with the columns' rows. */
|
|
16
|
+
bands?: Record<string, {
|
|
17
|
+
lo: ArrayLike<number>;
|
|
18
|
+
hi: ArrayLike<number>;
|
|
19
|
+
}>;
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
16
22
|
* Above this many rows host columns stay columnar (no row objects at all):
|
|
@@ -19,6 +25,8 @@ export interface ColumnsInput {
|
|
|
19
25
|
* so laps and math channels see every row.
|
|
20
26
|
*/
|
|
21
27
|
export declare const COLUMNAR_ROWS = 1000000;
|
|
28
|
+
/** Rows kept from a columnar dataset for the row-based charts (scatter, histogram, …). */
|
|
29
|
+
export declare const COLUMNAR_SAMPLE_ROWS = 12000;
|
|
22
30
|
/** Build a dataset from host-provided numeric columns (each is copied once). */
|
|
23
31
|
export declare function datasetFromColumns(id: string, input: ColumnsInput): LoadedDataset;
|
|
24
32
|
/**
|
|
@@ -42,3 +50,11 @@ export declare function replaceColumns(ds: LoadedDataset, input: Record<string,
|
|
|
42
50
|
* (cached), never on load or on each replaceColumns.
|
|
43
51
|
*/
|
|
44
52
|
export declare function columnsText(ds: LoadedDataset): string;
|
|
53
|
+
/** A Historian range handed to the engine (Historian phase 4): pieces from readHistoryRange and the channels' units. */
|
|
54
|
+
export interface HistoryRangeView {
|
|
55
|
+
name: string;
|
|
56
|
+
pieces: HistoryPiece[];
|
|
57
|
+
units?: Record<string, string>;
|
|
58
|
+
}
|
|
59
|
+
/** A Historian range as a dataset: read through HistoryDataSource; its rows are a time-ordered sample. */
|
|
60
|
+
export declare function historyDataset(id: string, view: HistoryRangeView): LoadedDataset;
|
|
@@ -13,22 +13,29 @@ import { type PanelChartSettings } from '../lib/panelChartSettings';
|
|
|
13
13
|
import type { MathChannel, MathChannelPatch } from '../lib/mathChannels/types';
|
|
14
14
|
import type { EvalResult } from '../lib/mathChannels/types';
|
|
15
15
|
import type { LiveConnection, LiveStreamDescriptor, LiveStreamOptions, LocalLiveStream, StreamKeyProvider } from '../lib/live/types';
|
|
16
|
+
import { type VideoSource } from '../lib/live/videoTrack';
|
|
16
17
|
import type { ChannelChooser } from '../lib/importers/types';
|
|
17
18
|
import type { RecordingKey } from '../lib/recordings/keys';
|
|
18
19
|
import { DATASET_PALETTE } from '../lib/datasetColors';
|
|
19
20
|
import { type BeaconConfig } from '../lib/beacon';
|
|
21
|
+
import { type CycleDefinition, type CycleFound, type RuleDef } from '../lib/cycles/evaluator';
|
|
22
|
+
import type { KpiSpec } from '../lib/segments/rules';
|
|
20
23
|
import { type Dataset, type DatasetParseConfig } from '../lib/parseDataset';
|
|
21
24
|
import { parseKymoscopeFile, type WorkbookBody } from '../lib/workspaces/io';
|
|
22
25
|
import { type WorkbookFileOptions } from '../lib/workspaces/encrypted';
|
|
23
26
|
import { canPickDirectory, isImportable, pickDirectoryEntries, type DirNode, type FolderEntry } from '../lib/folderTree';
|
|
24
27
|
import { type ChartView, type MountOptions } from '../charts/runtime';
|
|
25
28
|
import { type ChartWindow, type ChartWindowOptions } from '../charts/chartWindow';
|
|
26
|
-
import { type ColumnsInput } from './columns';
|
|
29
|
+
import { type ColumnsInput, type HistoryRangeView } from './columns';
|
|
27
30
|
import { createDerivations } from './derive';
|
|
28
31
|
import { chartLabel, type ChartKindInfo } from './kinds';
|
|
29
32
|
import { createLiveController } from './liveController';
|
|
33
|
+
import type { LiveSegmentAxis } from '../lib/segments/liveAxis';
|
|
34
|
+
import { type ChartMark, type RuleStateInfo } from './alerts';
|
|
35
|
+
import type { RuleDoc } from '../rules/types';
|
|
36
|
+
import type { LinkedRuleLine } from '../lib/panelChartSettings';
|
|
30
37
|
import { createStore } from './store';
|
|
31
|
-
import { type ChartKind, type ChartModel, type EngineEvents, type EngineOptions, type EngineState, type KymoscopeLimits } from './types';
|
|
38
|
+
import { type ChartKind, type ChartModel, type EngineEvents, type EngineOptions, type EngineState, type KymoscopeLimits, type SegmentContext } from './types';
|
|
32
39
|
export declare const DEFAULT_X = "ET";
|
|
33
40
|
/** Default series / scatter colours (matches the app). */
|
|
34
41
|
export declare const PALETTE: string[];
|
|
@@ -42,7 +49,12 @@ export interface InternalState {
|
|
|
42
49
|
offsets: Record<string, number>;
|
|
43
50
|
colors: Record<string, string>;
|
|
44
51
|
liveWindowSeconds: number | null;
|
|
52
|
+
segmentContext: SegmentContext | null;
|
|
53
|
+
/** Cycle and phase rules (lib/cycles), saved with the workbook. */
|
|
54
|
+
cycleRules: CycleDefinition[];
|
|
45
55
|
live: LiveConnection[];
|
|
56
|
+
/** Video sources registered by the host (engine.video.register): recorded cameras. */
|
|
57
|
+
video: VideoSource[];
|
|
46
58
|
mathChannels: MathChannel[];
|
|
47
59
|
limits: KymoscopeLimits;
|
|
48
60
|
palette: string[];
|
|
@@ -50,6 +62,10 @@ export interface InternalState {
|
|
|
50
62
|
/** null until the licence check finishes. */
|
|
51
63
|
licensed: boolean | null;
|
|
52
64
|
history: EngineState['history'];
|
|
65
|
+
marks: ChartMark[];
|
|
66
|
+
alerts: RuleStateInfo[];
|
|
67
|
+
/** The rules in force (engine.alerts.rules()), here so a new set re-renders the lines linked to them. */
|
|
68
|
+
alertRules: RuleDoc[];
|
|
53
69
|
}
|
|
54
70
|
export type ImportSource = File | FolderEntry;
|
|
55
71
|
export interface ImportResult {
|
|
@@ -90,6 +106,8 @@ export interface Exported {
|
|
|
90
106
|
}
|
|
91
107
|
export type ParsedFile = Awaited<ReturnType<typeof parseKymoscopeFile>>;
|
|
92
108
|
export type ChartSettingsPatch = Partial<PanelChartSettings> & Record<string, unknown>;
|
|
109
|
+
/** Point every chart's column picks at columns the new data actually has (X: time when there is one). */
|
|
110
|
+
export declare function adoptColumns(ws: Worksheet, nums: string[]): Worksheet;
|
|
93
111
|
export declare function createEngine(options?: EngineOptions): {
|
|
94
112
|
getState: () => EngineState;
|
|
95
113
|
subscribe(listener: () => void): () => void;
|
|
@@ -121,9 +139,19 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
121
139
|
* A cloud recording as a dataset: its encrypted chunks (KRC1, in order) decrypted with `keys` in the import
|
|
122
140
|
* worker, in memory or out of core like a file. Returns the id.
|
|
123
141
|
*/
|
|
124
|
-
openRecording(input: RecordingInput
|
|
142
|
+
openRecording(input: RecordingInput, o?: {
|
|
143
|
+
signal?: AbortSignal;
|
|
144
|
+
onProgress?: (fraction: number) => void;
|
|
145
|
+
}): Promise<string>;
|
|
125
146
|
/** New chunks of an open recording: the dataset keeps its id, selection, colour, offset and laps. */
|
|
126
147
|
reopenRecording(id: string, input: RecordingInput): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* A time range of a Historian history as a dataset (pieces from readHistoryRange; X `ElapsedTime`, Unix seconds).
|
|
150
|
+
* Returns the id. Selected like any new dataset.
|
|
151
|
+
*/
|
|
152
|
+
openHistoryRange(view: HistoryRangeView): string;
|
|
153
|
+
/** New pieces for a history dataset (pan/zoom, a later read): same id, selection, colour and offset. */
|
|
154
|
+
updateHistoryRange(id: string, view: HistoryRangeView): void;
|
|
127
155
|
/** Add numeric columns from the host (selected immediately). */
|
|
128
156
|
addColumns(input: ColumnsInput): string;
|
|
129
157
|
/**
|
|
@@ -148,6 +176,40 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
148
176
|
writeColumns(id: string, names: string[], fill: (cols: Record<string, Float64Array>, current: Record<string, Float64Array | undefined>) => void): void;
|
|
149
177
|
/** Add delimited text (CSV/TSV/.dat), parsed like an imported file. */
|
|
150
178
|
addText(text: string, name?: string): Promise<string>;
|
|
179
|
+
/** The cycles and phases of a dataset under cycle rules v2 (lib/cycles): closed ones, then the open ones (tend
|
|
180
|
+
* null), each with its definition's KPIs (`kpis`, by column name: "TIC201 max"). `timeKey`: its time column
|
|
181
|
+
* (seconds). Any kind of dataset: read through its source. */
|
|
182
|
+
findCycles(id: string, defs: Array<RuleDef & {
|
|
183
|
+
kpis?: KpiSpec[];
|
|
184
|
+
}>, timeKey: string): Promise<CycleFound[]>;
|
|
185
|
+
/**
|
|
186
|
+
* "Add to datasets": the picked cycles or phases of a dataset (from findCycles), each as a dataset of its samples
|
|
187
|
+
* with `Cycle time` (s since its start), then the cycles table and phases table of `cycleId` (unless `tables`
|
|
188
|
+
* false). Returns the new ids, in that order.
|
|
189
|
+
*/
|
|
190
|
+
addCycles(id: string, o: {
|
|
191
|
+
timeKey: string;
|
|
192
|
+
defs: Array<RuleDef & {
|
|
193
|
+
name: string;
|
|
194
|
+
kpis?: KpiSpec[];
|
|
195
|
+
}>;
|
|
196
|
+
cycleId: string;
|
|
197
|
+
found: CycleFound[];
|
|
198
|
+
pick: Array<Pick<CycleFound, "definitionId" | "index" | "parentIndex">>;
|
|
199
|
+
tables?: boolean;
|
|
200
|
+
}): Promise<string[]>;
|
|
201
|
+
/**
|
|
202
|
+
* Cut a dataset into cycles (the dataset's Cycles button): the cycles of `cycleId` and its phases, found in the
|
|
203
|
+
* browser over any kind of dataset; each becomes a part with `Cycle time` (s since its start), and the dataset is
|
|
204
|
+
* shown and selected as them, as laps are (a selected dataset plots all its cycles). `null` undoes it. Nothing is
|
|
205
|
+
* stored: a workbook keeps the rules, never the cycles. Resolves to the number of cycles (phases not counted).
|
|
206
|
+
* ponytail: reads the dataset's numeric columns whole (as addCycles); a part is a view, not a copy.
|
|
207
|
+
*/
|
|
208
|
+
cut(id: string, o: {
|
|
209
|
+
defs: CycleDefinition[];
|
|
210
|
+
cycleId: string;
|
|
211
|
+
timeKey: string;
|
|
212
|
+
} | null): Promise<number>;
|
|
151
213
|
remove(id: string): void;
|
|
152
214
|
/** Remove every dataset. Worksheets and charts are kept. */
|
|
153
215
|
clear(): void;
|
|
@@ -266,7 +328,12 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
266
328
|
/** Linked X zoom of a worksheet (default: active); null = full range. */
|
|
267
329
|
setXRange(range: [number, number] | null, worksheetId?: string): void;
|
|
268
330
|
resetZoom(worksheetId?: string): void;
|
|
331
|
+
/** Shared chart cursor of a worksheet (default: active), in X data units; null = none. Fires 'cursorchange'. */
|
|
332
|
+
setCursorX(x: number | null, worksheetId?: string): void;
|
|
333
|
+
cursorX(worksheetId?: string): number | null;
|
|
269
334
|
setLiveWindow(seconds: number | null): void;
|
|
335
|
+
/** The Segments panel's ids (history, definition, reference); saved with the workbook. */
|
|
336
|
+
setSegmentContext(ctx: SegmentContext | null): void;
|
|
270
337
|
};
|
|
271
338
|
mathChannels: {
|
|
272
339
|
/** Create a channel (`name` and `formula` at least). Returns it. */
|
|
@@ -289,6 +356,15 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
289
356
|
/** Host-owned store: push the authoritative list after it changes (an open workbook's channels stay). */
|
|
290
357
|
sync(channels: MathChannel[]): void;
|
|
291
358
|
};
|
|
359
|
+
/** Cycle and phase rules (lib/cycles), saved with the workbook: `getState().cycleRules`. */
|
|
360
|
+
cycles: {
|
|
361
|
+
/** Add or replace a cycle or phase rule (by id; a new one gets an id). Returns its id. Saved with the workbook. */
|
|
362
|
+
save(def: Omit<CycleDefinition, "id"> & {
|
|
363
|
+
id?: string;
|
|
364
|
+
}): string;
|
|
365
|
+
/** Remove a rule and the phases inside it. */
|
|
366
|
+
remove(id: string): void;
|
|
367
|
+
};
|
|
292
368
|
live: {
|
|
293
369
|
/** A stream the page feeds itself (no relay, no crypto). */
|
|
294
370
|
openLocal(name: string, options?: LiveStreamOptions): LocalLiveStream;
|
|
@@ -307,10 +383,22 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
307
383
|
name: string;
|
|
308
384
|
startedAt: number;
|
|
309
385
|
} | null;
|
|
386
|
+
/** Live against a reference (Historian phase 5): the definition's rule, the axis column and deltas on a connection. */
|
|
387
|
+
setSegmentAxis(id: string, cfg: LiveSegmentAxis | null): void;
|
|
310
388
|
/** Samples currently buffered for a connection (cheap; poll it for counters). */
|
|
311
389
|
rowCount(id: string): number;
|
|
312
390
|
disconnect(id: string): void;
|
|
313
391
|
};
|
|
392
|
+
/** Camera video the Camera panel plays: live cameras appear on their own; register recorded ones. `videochange`
|
|
393
|
+
* fires when the list changes. */
|
|
394
|
+
video: {
|
|
395
|
+
/** Live cameras (kind 'live', one per camera connection) and the registered sources (recorded cameras). */
|
|
396
|
+
sources: () => VideoSource[];
|
|
397
|
+
/** Add a video source (e.g. a RecordedVideoSource of an open recording); replaces one with the same id and recordingId. */
|
|
398
|
+
register(source: VideoSource): void;
|
|
399
|
+
/** Remove the registered sources of camera `id` (of only that recording when `recordingId` is given). */
|
|
400
|
+
unregister(id: string, recordingId?: string): void;
|
|
401
|
+
};
|
|
314
402
|
io: {
|
|
315
403
|
/** True when there are charts that a workspace import would replace. */
|
|
316
404
|
hasWork: () => boolean;
|
|
@@ -371,6 +459,24 @@ export declare function createEngine(options?: EngineOptions): {
|
|
|
371
459
|
/** Like merged() without the math channels: no row cloning, stable until the data changes. */
|
|
372
460
|
plotted(): Dataset | null;
|
|
373
461
|
};
|
|
462
|
+
/** Alert rules (kyr/1) on the open datasets and live streams. The engine never stores rules: pass the whole list
|
|
463
|
+
* to setRules whenever it changes. Transitions arrive as `alert` events; episodes become `marks`. */
|
|
464
|
+
alerts: {
|
|
465
|
+
setRules: (docs: RuleDoc[]) => (import("..").RuleProblem & {
|
|
466
|
+
ruleId: string;
|
|
467
|
+
})[];
|
|
468
|
+
rules: () => RuleDoc[];
|
|
469
|
+
state: () => RuleStateInfo[];
|
|
470
|
+
evaluate: (datasetId: string, o: {
|
|
471
|
+
timeColumn: string;
|
|
472
|
+
ruleIds?: string[];
|
|
473
|
+
}) => Promise<import("..").AlertTransition[]>;
|
|
474
|
+
clearMarks: (targetId?: string) => void;
|
|
475
|
+
};
|
|
476
|
+
/** Read-only spans on the charts from alert episodes (never stored in chart settings). */
|
|
477
|
+
marks: {
|
|
478
|
+
list: () => ChartMark[];
|
|
479
|
+
};
|
|
374
480
|
dispose(): void;
|
|
375
481
|
};
|
|
376
482
|
export type KymoscopeEngine = ReturnType<typeof createEngine>;
|
|
@@ -389,6 +495,8 @@ export interface EngineInternals {
|
|
|
389
495
|
columnUnits: Record<string, string>;
|
|
390
496
|
};
|
|
391
497
|
live: ReturnType<typeof createLiveController>;
|
|
498
|
+
/** Per rule id: the threshold and state lines linked to it draw (resolveLinkedAlarms). */
|
|
499
|
+
alertLines: () => ReadonlyMap<string, LinkedRuleLine>;
|
|
392
500
|
}
|
|
393
501
|
export declare function getInternals(engine: KymoscopeEngine): EngineInternals;
|
|
394
502
|
export { DATASET_PALETTE };
|
|
@@ -20,7 +20,7 @@ export declare function createDerivations(): {
|
|
|
20
20
|
staticDataset: (selected: LoadedDataset[]) => Dataset | null;
|
|
21
21
|
mergedDataset: (stat: Dataset | null, live: LiveConnection[]) => Dataset | null;
|
|
22
22
|
mergedParts: (selected: LoadedDataset[], live: LiveConnection[]) => Dataset[];
|
|
23
|
-
numericColumns: (merged: Dataset | null, selected: LoadedDataset[], channels: MathChannel[], parts?: Dataset[] | undefined) => string[];
|
|
23
|
+
numericColumns: (merged: Dataset | null, selected: LoadedDataset[], channels: MathChannel[], parts?: Dataset[] | undefined, live?: LiveConnection[] | undefined) => string[];
|
|
24
24
|
allColumns: (merged: Dataset | null, selected: LoadedDataset[], channels: MathChannel[]) => string[];
|
|
25
25
|
columnUnits: (merged: Dataset | null, channels: MathChannel[]) => Record<string, string>;
|
|
26
26
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type KymoscopeErrorCode = 'column_length_mismatch' | 'no_columns' | 'bad_workspace' | 'bad_file' | 'import_vetoed' | 'limit_reached' | 'not_found' | 'wrong_password' | 'password_required' | 'scope_key_required' | 'relay_unavailable' | 'disposed' | 'invalid_argument' | 'export_failed' | 'popup_blocked' | 'cancelled';
|
|
1
|
+
export type KymoscopeErrorCode = 'column_length_mismatch' | 'no_columns' | 'bad_workspace' | 'bad_file' | 'import_vetoed' | 'limit_reached' | 'not_found' | 'wrong_password' | 'password_required' | 'scope_key_required' | 'relay_unavailable' | 'disposed' | 'invalid_argument' | 'export_failed' | 'popup_blocked' | 'cancelled' | 'camera_codec_unsupported';
|
|
2
2
|
/** Every failure the SDK reports. `detail` carries structured context (e.g. `{reason}` for limits). */
|
|
3
3
|
export declare class KymoscopeError extends Error {
|
|
4
4
|
readonly code: KymoscopeErrorCode;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { LiveBuffer } from '../lib/live/buffer';
|
|
1
2
|
import { type LiveRelayConfig } from '../lib/live/stream';
|
|
2
3
|
import type { MathChannel } from '../lib/mathChannels/types';
|
|
4
|
+
import { type LiveSegmentAxis } from '../lib/segments/liveAxis';
|
|
3
5
|
import type { LiveConnection, LiveStreamDescriptor, LiveStreamOptions, LocalLiveStream, StreamKeyProvider } from '../lib/live/types';
|
|
4
6
|
export interface LiveController {
|
|
5
7
|
connections(): LiveConnection[];
|
|
@@ -20,8 +22,16 @@ export interface LiveController {
|
|
|
20
22
|
setRelay(relay: LiveRelayConfig | undefined): void;
|
|
21
23
|
/** Math channels evaluated on every stream (as computed buffer columns). */
|
|
22
24
|
setMathChannels(channels: MathChannel[]): void;
|
|
25
|
+
/** Run a segment definition live on a connection (plan S6), or stop it (null). Replays the ring quietly. */
|
|
26
|
+
setSegmentAxis(id: string, cfg: LiveSegmentAxis | null): void;
|
|
23
27
|
dispose(): void;
|
|
24
28
|
}
|
|
25
29
|
export declare function createLiveController(initialRelay: LiveRelayConfig | undefined, onChange: (connections: LiveConnection[]) => void,
|
|
26
30
|
/** The host's defaults for new streams (read when one opens). */
|
|
27
|
-
defaults?: () => LiveStreamOptions
|
|
31
|
+
defaults?: () => LiveStreamOptions,
|
|
32
|
+
/** Alert rules: `rows` after every ingested block (from absolute index `from`, math channels already computed),
|
|
33
|
+
* `tick` once a second per stream with the arrival time (ms) of its last frame. */
|
|
34
|
+
hooks?: {
|
|
35
|
+
rows(id: string, buf: LiveBuffer, from: number): void;
|
|
36
|
+
tick(id: string, buf: LiveBuffer, lastFrameAt: number): void;
|
|
37
|
+
}): LiveController;
|
|
@@ -1,21 +1,27 @@
|
|
|
1
|
+
import type { VideoSource } from '../lib/live/videoTrack';
|
|
1
2
|
import type { LiveStreamOptions } from '../lib/live/types';
|
|
2
3
|
import type { DashboardPanelKind } from '../components/dashboardGridLayout';
|
|
3
4
|
import type { PanelChartSettings } from '../lib/panelChartSettings';
|
|
4
5
|
import type { ChartAnnotation } from '../lib/annotations';
|
|
5
6
|
import type { MathChannel, MathChannelPatch } from '../lib/mathChannels/types';
|
|
7
|
+
import type { CycleDefinition, CycleFlag } from '../lib/cycles/evaluator';
|
|
6
8
|
import type { LiveRelayConfig } from '../lib/live/stream';
|
|
7
9
|
import type { BeaconConfig } from '../lib/beacon';
|
|
8
10
|
import type { DatasetParseConfig } from '../lib/parseDataset';
|
|
9
11
|
import type { DatasetFileInfo } from '../lib/importers/types';
|
|
12
|
+
import type { AlertTransition } from '../rules/evaluator';
|
|
13
|
+
import type { ChartMark, RuleStateInfo } from './alerts';
|
|
10
14
|
export type ChartKind = DashboardPanelKind;
|
|
11
15
|
/** Why a limit blocked an action. */
|
|
12
|
-
export type LimitReason = 'charts-per-worksheet' | 'channels-per-chart' | 'worksheets' | 'workspaces-io' | 'math-channels';
|
|
16
|
+
export type LimitReason = 'charts-per-worksheet' | 'channels-per-chart' | 'worksheets' | 'workspaces-io' | 'math-channels' | 'alert-rules';
|
|
13
17
|
/** Quantity limits; `null` = unlimited. */
|
|
14
18
|
export interface KymoscopeLimits {
|
|
15
19
|
maxChartsPerWorksheet: number | null;
|
|
16
20
|
maxChannelsPerChart: number | null;
|
|
17
21
|
maxWorksheets: number | null;
|
|
18
22
|
maxMathChannels: number | null;
|
|
23
|
+
/** Alert rules evaluated (engine.alerts.setRules keeps the first ones). */
|
|
24
|
+
maxAlertRules: number | null;
|
|
19
25
|
canImportExportWorkspaces: boolean;
|
|
20
26
|
}
|
|
21
27
|
export declare const UNLIMITED: KymoscopeLimits;
|
|
@@ -71,6 +77,23 @@ export interface LapInfo {
|
|
|
71
77
|
color: string;
|
|
72
78
|
offset: number;
|
|
73
79
|
selected: boolean;
|
|
80
|
+
/** A cut's cycle or phase (datasets.cut); absent for a beacon lap. */
|
|
81
|
+
cycle?: LapCycle;
|
|
82
|
+
}
|
|
83
|
+
/** What a cut found for one lap row: a cycle (no parentIndex) or one of its phases. */
|
|
84
|
+
export interface LapCycle {
|
|
85
|
+
definitionId: string;
|
|
86
|
+
/** The rule's name ("Cycle", "Heating"). */
|
|
87
|
+
rule: string;
|
|
88
|
+
index: number;
|
|
89
|
+
/** A phase: the index of its cycle. */
|
|
90
|
+
parentIndex: number | null;
|
|
91
|
+
tstart: number;
|
|
92
|
+
tend: number | null;
|
|
93
|
+
flags: CycleFlag[];
|
|
94
|
+
kpis: Record<string, number | null>;
|
|
95
|
+
/** Cut short: by the end of the data, or of its cycle (a phase). */
|
|
96
|
+
incomplete: boolean;
|
|
74
97
|
}
|
|
75
98
|
export interface DatasetInfo {
|
|
76
99
|
id: string;
|
|
@@ -90,7 +113,13 @@ export interface DatasetInfo {
|
|
|
90
113
|
/** Binary files: format, start time, groups (with rates), events; null for text. */
|
|
91
114
|
fileInfo: DatasetFileInfo | null;
|
|
92
115
|
beacon: BeaconConfig | null;
|
|
93
|
-
/**
|
|
116
|
+
/** The rule a dataset is cut by (datasets.cut), or null. */
|
|
117
|
+
cut: {
|
|
118
|
+
cycleId: string;
|
|
119
|
+
timeKey: string;
|
|
120
|
+
defs: CycleDefinition[];
|
|
121
|
+
} | null;
|
|
122
|
+
/** Present when the dataset is split into laps (beacon) or cut into cycles (then each lap has `cycle`). */
|
|
94
123
|
laps: LapInfo[] | null;
|
|
95
124
|
/** Selection state: true, false, or 'partial' when only some laps are selected. */
|
|
96
125
|
selected: boolean | 'partial';
|
|
@@ -125,9 +154,16 @@ export interface LiveConnectionInfo {
|
|
|
125
154
|
id: string;
|
|
126
155
|
name: string;
|
|
127
156
|
ownerName: string;
|
|
128
|
-
visibility: 'private' | 'public' | 'org' | 'project';
|
|
157
|
+
visibility: 'private' | 'public' | 'org' | 'project' | 'open';
|
|
129
158
|
orgName: string | null;
|
|
130
|
-
|
|
159
|
+
/** A camera carries video (a camera panel shows it); a data stream, samples. */
|
|
160
|
+
kind: 'data' | 'camera';
|
|
161
|
+
/** A camera's data stream; null for data streams. */
|
|
162
|
+
parentId: string | null;
|
|
163
|
+
/** A camera's low layer: its high camera's id (not a camera of its own: lists and pickers skip it); null otherwise. */
|
|
164
|
+
lowOf: string | null;
|
|
165
|
+
/** 'idle': a camera no panel shows (connected, not downloading). */
|
|
166
|
+
status: 'idle' | 'connecting' | 'live' | 'stale' | 'error';
|
|
131
167
|
error: string | null;
|
|
132
168
|
rowCount: number;
|
|
133
169
|
selected: boolean;
|
|
@@ -137,6 +173,14 @@ export interface LiveConnectionInfo {
|
|
|
137
173
|
customColor: boolean;
|
|
138
174
|
/** When a recording is running: its start time (ms since epoch), else null. */
|
|
139
175
|
recordingSince: number | null;
|
|
176
|
+
/** Its columns as of the last structural change (the time column first). */
|
|
177
|
+
channels: string[];
|
|
178
|
+
}
|
|
179
|
+
/** What the Segments panel shows (Historian phase 5): saved in workbooks by id (spec E4), never data. */
|
|
180
|
+
export interface SegmentContext {
|
|
181
|
+
historyId: string;
|
|
182
|
+
definitionId: string | null;
|
|
183
|
+
referenceId: string | null;
|
|
140
184
|
}
|
|
141
185
|
export interface EngineState {
|
|
142
186
|
datasets: DatasetInfo[];
|
|
@@ -148,6 +192,10 @@ export interface EngineState {
|
|
|
148
192
|
live: LiveConnectionInfo[];
|
|
149
193
|
/** Scrolling window for live charts on a time X axis (seconds; null = all). */
|
|
150
194
|
liveWindowSeconds: number | null;
|
|
195
|
+
/** The Segments panel's history, definition and reference, or null. */
|
|
196
|
+
segmentContext: SegmentContext | null;
|
|
197
|
+
/** Cycle and phase rules (engine.cycles), saved with the workbook. */
|
|
198
|
+
cycleRules: CycleDefinition[];
|
|
151
199
|
limits: KymoscopeLimits;
|
|
152
200
|
/** Colors given to plotted datasets in order (EngineOptions.palette). */
|
|
153
201
|
palette: string[];
|
|
@@ -173,16 +221,33 @@ export interface EngineState {
|
|
|
173
221
|
canUndo: boolean;
|
|
174
222
|
canRedo: boolean;
|
|
175
223
|
};
|
|
224
|
+
/** Read-only spans from alert rule episodes (engine.alerts), drawn on time charts. */
|
|
225
|
+
marks: ChartMark[];
|
|
226
|
+
/** Per rule and open target: waiting (with the missing channel names), idle, pending, active, clearing… */
|
|
227
|
+
alerts: RuleStateInfo[];
|
|
176
228
|
}
|
|
177
229
|
export interface EngineEvents extends Record<string, unknown> {
|
|
178
230
|
change: EngineState;
|
|
179
231
|
limit: {
|
|
180
232
|
reason: LimitReason;
|
|
181
233
|
};
|
|
234
|
+
/** An alert rule raised, cleared, or lost its channel on a target. */
|
|
235
|
+
alert: AlertTransition;
|
|
236
|
+
/** The shared chart cursor of a worksheet moved (view.setCursorX); x in data units, null = off the charts. */
|
|
237
|
+
cursorchange: {
|
|
238
|
+
worksheetId: string;
|
|
239
|
+
x: number | null;
|
|
240
|
+
};
|
|
241
|
+
/** engine.video.sources() changed: a live camera came or went, or a source was registered or unregistered. */
|
|
242
|
+
videochange: {
|
|
243
|
+
sources: VideoSource[];
|
|
244
|
+
};
|
|
182
245
|
error: {
|
|
183
246
|
error: Error;
|
|
184
247
|
context: string;
|
|
185
248
|
};
|
|
249
|
+
/** The engine was disposed (once; every call throws KymoscopeError 'disposed' from now on). */
|
|
250
|
+
dispose: undefined;
|
|
186
251
|
import: {
|
|
187
252
|
file: string;
|
|
188
253
|
phase: 'start' | 'progress' | 'done' | 'error';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ export type { KymoscopeEngine, Snapshot, ImportSource, ImportResult, ImportOptio
|
|
|
13
13
|
export { KymoscopeError } from './engine/errors';
|
|
14
14
|
export type { KymoscopeErrorCode } from './engine/errors';
|
|
15
15
|
export { UNLIMITED } from './engine/types';
|
|
16
|
-
export type { EngineOptions, EngineState, EngineEvents, KymoscopeLimits, LimitReason, MathChannelStoreAdapter, DatasetInfo, ColumnInfo, LapInfo, ChartKind, ChartModel, WorksheetState, LiveConnectionInfo, } from './engine/types';
|
|
16
|
+
export type { EngineOptions, EngineState, EngineEvents, KymoscopeLimits, LimitReason, MathChannelStoreAdapter, DatasetInfo, ColumnInfo, LapInfo, LapCycle, ChartKind, ChartModel, WorksheetState, LiveConnectionInfo, } from './engine/types';
|
|
17
|
+
export type { ChartMark, RuleStateInfo } from './engine/alerts';
|
|
17
18
|
export { CHART_KINDS, chartLabel } from './engine/kinds';
|
|
18
19
|
export type { ChartKindInfo } from './engine/kinds';
|
|
19
20
|
export type { ColumnsInput } from './engine/columns';
|
|
@@ -24,7 +25,7 @@ export type { ChartWindow, ChartWindowOptions } from './charts/chartWindow';
|
|
|
24
25
|
export type { ChartStatus, ContextMenuEvent } from './charts/ChartBody';
|
|
25
26
|
export * from './lib/panelChartSettings';
|
|
26
27
|
export { chartChannelCount } from './lib/chartChannels';
|
|
27
|
-
export { ANNOTATION_KINDS, DEFAULT_ANNOTATION_WIDTH, type AnnotationKind, type AnnotationTool, type ChartAnnotation } from './lib/annotations';
|
|
28
|
+
export { ANNOTATION_KINDS, DEFAULT_ANNOTATION_WIDTH, coerceAnnotation, markToAnnotation, SEVERITY_HEX, type AnnotationKind, type AnnotationTool, type ChartAnnotation } from './lib/annotations';
|
|
28
29
|
export { ANNOTATION_CONTROLS_ATTR } from './charts/AnnotationLayer';
|
|
29
30
|
export { colorAt, colorsCss, presetStops, type GaugeColorMode, type GaugeColorStop, type GaugePreset } from './lib/gaugeColors';
|
|
30
31
|
export type { PlotSeries, AlarmLine, AlarmStyle } from './types/plotSeries';
|
|
@@ -60,11 +61,35 @@ export type { LiveRelayConfig } from './lib/live/stream';
|
|
|
60
61
|
export type { LiveStreamDescriptor, LiveStreamOptions, LocalLiveStream, StreamKeyProvider } from './lib/live/types';
|
|
61
62
|
export type { LiveColumnsBlock, LiveMessage } from './lib/live/buffer';
|
|
62
63
|
export { LIVE_TIME_COLUMN } from './lib/live/buffer';
|
|
63
|
-
export { openMessage, sealMessage } from './lib/live/wire';
|
|
64
|
+
export { openMessage, sealMessage, KIND_VIDEO } from './lib/live/wire';
|
|
65
|
+
export { encodeVideo, decodeVideo, fragmentVideo, VIDEO_MAX_FRAGMENT, type VideoMessage } from './lib/live/videoWire';
|
|
66
|
+
export type { VideoSource, EncodedUnit, VideoTrackInfo } from './lib/live/videoTrack';
|
|
67
|
+
export { RecordedVideoSource, type RecordedVideoSourceOptions } from './lib/recordings/videoSource';
|
|
68
|
+
export { LivePublisher, type PublisherDeps, type PublisherOptions, type PublisherState, type PublisherStatus } from './lib/live/publisher';
|
|
69
|
+
export { CameraSender, CAMERA_PRESETS, LOW_PRESET, type CameraPreset, type CameraStats, type CameraLayerStats, type CameraSenderDeps } from './lib/live/cameraSender';
|
|
64
70
|
export type { RecordingKey } from './lib/recordings/keys';
|
|
65
71
|
export { recordingKeyAad, recordingKeySealAad } from './lib/recordings/keys';
|
|
66
72
|
export { parseKrc, parseKrcHeader, KRC_HEADER_BYTES } from './lib/recordings/krc';
|
|
67
73
|
export type { RecordingInput } from './engine/createEngine';
|
|
68
74
|
export { exportRecording, exportRecordingTo, EXPORT_TYPES, type ExportPart, type RecordingSource } from './lib/recordings/export';
|
|
69
75
|
export type { EncryptedEnvelope, DeviceWrap, SealedKey, PasswordSealed } from './lib/live/crypto';
|
|
70
|
-
export { generateApiToken, splitApiKey, generateDeviceKeyPair, unwrapStreamKey, unwrapForDevice, wrapForDevice, projectWrapAad, streamKeyAad, bindKeyAad, randomKey, importStreamKey, sealUnderProjectKey, openUnderProjectKey, senderBindKey, senderBinding, verifySenderBinding, deviceFingerprint, hashToken, generateSalt, deriveKey, deriveRawKeyBase64, makeKeyCheck, verifyKeyCheck, WORKBOOK_EXPORT_AAD, workbookBodyAad, workbookKeyAad, recoveryKeyAad, recoveryAttestationAad, sealWithKey, openWithKey, sealWithPassword, openWithPassword, recoveryCode, parseRecoveryCode, generateRecoveryKeyPair, recoveryPrivateKey, } from './lib/live/crypto';
|
|
76
|
+
export { generateApiToken, splitApiKey, generateDeviceKeyPair, unwrapStreamKey, unwrapForDevice, wrapForDevice, projectWrapAad, streamKeyAad, bindKeyAad, randomKey, importStreamKey, sealUnderProjectKey, openUnderProjectKey, senderBindKey, senderBinding, verifySenderBinding, deviceFingerprint, hashToken, generateSalt, deriveKey, OPEN_STREAM_PASSWORD, deriveRawKeyBase64, makeKeyCheck, verifyKeyCheck, WORKBOOK_EXPORT_AAD, workbookBodyAad, workbookKeyAad, historyKeyAad, projectConfigKeyAad, alertRuleAad, recoveryKeyAad, recoveryAttestationAad, sealWithKey, openWithKey, sealWithPassword, openWithPassword, recoveryCode, parseRecoveryCode, generateRecoveryKeyPair, recoveryPrivateKey, } from './lib/live/crypto';
|
|
77
|
+
export * from './rules/types';
|
|
78
|
+
export { validateRule, type RuleProblem } from './rules/validate';
|
|
79
|
+
export { thresholdOf } from './rules/threshold';
|
|
80
|
+
export { createRuleEvaluator, type RuleEvaluator, type RuleTarget, type AlertTransition, type RuleEvaluatorState, type LiveBlock } from './rules/evaluator';
|
|
81
|
+
export { footerLength, openFooter, openSealed, blockAad, type KhdFooter, type KhdBlock, type KhdChannel, type KhdFileId, type HistoryKind, type HistoryLevel } from './lib/historian/khd1';
|
|
82
|
+
export { warmHistoryDecoder } from './lib/historian/parquet';
|
|
83
|
+
export { blockCache, type BlockCache, type CacheDir } from './lib/historian/blockCache';
|
|
84
|
+
export { HistoryDataSource, splicePieces, clipPiece, slicePiece, type HistoryPiece } from './lib/data/historyDataSource';
|
|
85
|
+
export type { HistoryRangeView } from './engine/columns';
|
|
86
|
+
export { isClockAxis, formatClockTick, formatClockValue, setClockTimeZone, getClockTimeZone, subscribeClockTimeZone } from './lib/yAxisTicks';
|
|
87
|
+
export { readHistoryRange, readFooter, chooseLevel, pickSegments, coalesce, pool, RANGE_PARALLEL, HISTORY_PIXELS, type HistorySegmentRef, type HistoryReadOptions, type HistoryRange } from './lib/historian/reader';
|
|
88
|
+
export { exportHistoryTo, wideDay, f32text, isoMicros, MAX_WIDE_CELLS, MAX_PARQUET_VALUES, type HistoryExportFormat } from './lib/historian/export';
|
|
89
|
+
export { CycleRunner, CycleSet, cycleRuleChannels, type CycleRule, type Trigger as CycleTrigger, type Condition as CycleCondition, type CycleLimits, type CycleFlag, type CycleInstance, type CycleFound, type RuleDef, type CycleDefinition, parseCycleDefinitions } from './lib/cycles/evaluator';
|
|
90
|
+
export { CYCLE_TIME, readSource, findCycles, cutCycle, cycleTables, definitionChannels, kpiColumn, kpisOf, rowsCsv, type SourceColumns } from './lib/cycles/cut';
|
|
91
|
+
export { RuleRunner, KpiAcc, resetStep, newResetState, compareOp, kpiKey, ruleChannels, localDay, zonedInstant, shiftDay, tzOffsetS, KPI_STATS, type SegmentRule, type CompareOp, type EdgeOn, type KpiStat, type KpiSpec, type Kpis, type DetectedSegment, type ResetState } from './lib/segments/rules';
|
|
92
|
+
export type { SegmentContext } from './engine/types';
|
|
93
|
+
export { referenceBands } from './charts/beacon';
|
|
94
|
+
export { alignSegment, AxisState, axisColumn, localSeconds, resample, gridAt, buildReference, bandEdges, compareToReference, encodeBand, decodeBand, MAX_GRID, MAX_BAND_CELLS, type AlignAxis, type AlignedSegment, type ReferenceCurve, type ReferenceChannel, type Comparison } from './lib/segments/align';
|
|
95
|
+
export { liveSegmentTracker, DELTA_SUFFIX, type LiveSegmentAxis, type LiveSegmentEvent, type LiveReference } from './lib/segments/liveAxis';
|
|
@@ -35,3 +35,23 @@ export declare const DEFAULT_ANNOTATION_WIDTH: Record<AnnotationKind, number>;
|
|
|
35
35
|
/** One annotation from untrusted input (a file, an SDK call), or null if it isn't one. */
|
|
36
36
|
export declare function coerceAnnotation(v: unknown): ChartAnnotation | null;
|
|
37
37
|
export declare function coerceAnnotations(v: unknown): ChartAnnotation[] | null;
|
|
38
|
+
/** Severity colours of alert marks: the palette's own muted text, amber accent and danger (hex for annotations). */
|
|
39
|
+
export declare const SEVERITY_HEX: {
|
|
40
|
+
readonly info: "#8a93a6";
|
|
41
|
+
readonly warning: "#f5a524";
|
|
42
|
+
readonly critical: "#e5484d";
|
|
43
|
+
};
|
|
44
|
+
/** The same, following the page's theme on screen. */
|
|
45
|
+
export declare const SEVERITY_COLOR: {
|
|
46
|
+
readonly info: "var(--text-muted, #8a93a6)";
|
|
47
|
+
readonly warning: "var(--accent, #f5a524)";
|
|
48
|
+
readonly critical: "var(--danger, #e5484d)";
|
|
49
|
+
};
|
|
50
|
+
/** An alert mark as a box annotation pinned to X ("Keep as annotation"); an open mark ends at `rightEdgeX`. */
|
|
51
|
+
export declare function markToAnnotation(m: {
|
|
52
|
+
id: string;
|
|
53
|
+
ruleName: string;
|
|
54
|
+
severity: keyof typeof SEVERITY_HEX;
|
|
55
|
+
t0: number;
|
|
56
|
+
t1: number | null;
|
|
57
|
+
}, rightEdgeX: number): ChartAnnotation;
|
|
@@ -22,7 +22,8 @@ export interface LapRange {
|
|
|
22
22
|
/**
|
|
23
23
|
* Split rows wherever `channel` resets. A reset is a drop larger than half of
|
|
24
24
|
* the current lap's span so far, so small sensor jitter backwards never starts
|
|
25
|
-
* a new lap
|
|
25
|
+
* a new lap (the edge rule `reset` of segments/rules.ts). Rows whose channel is
|
|
26
|
+
* not numeric stay inside the current lap.
|
|
26
27
|
*/
|
|
27
28
|
export declare function splitLaps(rows: DatasetRow[], channel: string): LapRange[];
|
|
28
29
|
/**
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cutting any source into cycles (spec 2026-10-28-cycles-design, "Cutting any source"): read a source's time and the
|
|
3
|
+
* channels needed through DataSource.readColumns (every kind has it: memory, columnar, history range, recording, DuckDB),
|
|
4
|
+
* find the cycles with a CycleSet, and cut each one into columns with `Cycle time` (seconds since its start). The
|
|
5
|
+
* cycles table and phases table are rows (text flags), for the row-based charts.
|
|
6
|
+
* ponytail: the channels are read whole into memory; read per cycle (like segmentRun.loadAligned) if a source is too
|
|
7
|
+
* large for that.
|
|
8
|
+
*/
|
|
9
|
+
import type { DataSource } from '../data/dataSource';
|
|
10
|
+
import type { DatasetRow } from '../parseDataset';
|
|
11
|
+
import { type KpiSpec } from '../segments/rules';
|
|
12
|
+
import { type CycleFound, type RuleDef } from './evaluator';
|
|
13
|
+
export declare const CYCLE_TIME = "Cycle time";
|
|
14
|
+
export interface SourceColumns {
|
|
15
|
+
t: Float64Array;
|
|
16
|
+
cols: Map<string, Float64Array>;
|
|
17
|
+
}
|
|
18
|
+
/** `timeKey` and `channels` of a source, whole, in file order. Missing channels are left out. */
|
|
19
|
+
export declare function readSource(source: DataSource, timeKey: string, channels: string[]): Promise<SourceColumns>;
|
|
20
|
+
/** The cycles and phases of `defs` in the columns: closed ones, then the ones still open (tend null). */
|
|
21
|
+
export declare function findCycles(src: SourceColumns, defs: RuleDef[]): CycleFound[];
|
|
22
|
+
/** Every channel the definitions read (their rules and KPIs). */
|
|
23
|
+
export declare const definitionChannels: (defs: Array<RuleDef & {
|
|
24
|
+
kpis?: KpiSpec[];
|
|
25
|
+
}>) => string[];
|
|
26
|
+
/** A KPI's column name in the cycles and phases tables: "TIC201 max". */
|
|
27
|
+
export declare const kpiColumn: (k: KpiSpec) => string;
|
|
28
|
+
/** The KPIs of [tstart, tend) (an open one: to the end) from the source's columns; null where a channel has no value. */
|
|
29
|
+
export declare function kpisOf(src: SourceColumns, c: Pick<CycleFound, 'tstart' | 'tend'>, kpis: KpiSpec[]): Record<string, number | null>;
|
|
30
|
+
/** One cycle's samples, [tstart, tend) (an open cycle: to the end), as columns: `Cycle time`, the time and the channels
|
|
31
|
+
* (views of the source's arrays, not copies). */
|
|
32
|
+
export declare function cutCycle(src: SourceColumns, timeKey: string, c: Pick<CycleFound, 'tstart' | 'tend'>): Record<string, Float64Array>;
|
|
33
|
+
/**
|
|
34
|
+
* The cycles table (one row per cycle of `cycleId`: Cycle, Start, End, Duration, each phase's duration, Flags) and the
|
|
35
|
+
* phases table (one row per phase: Cycle, Phase, Start, End, Duration, Flags). `defs`: the definitions, named. A cycle's
|
|
36
|
+
* Flags also list its phases' flags ("Heating late"). Times in the source's seconds; an open cycle has no End.
|
|
37
|
+
*/
|
|
38
|
+
export declare function cycleTables(found: CycleFound[], cycleId: string, defs: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
parentId: string | null;
|
|
42
|
+
kpis?: KpiSpec[];
|
|
43
|
+
}>, src?: SourceColumns): {
|
|
44
|
+
cycles: DatasetRow[];
|
|
45
|
+
phases: DatasetRow[];
|
|
46
|
+
};
|
|
47
|
+
/** Rows as CSV (the columns of the first row; text quoted when it needs it; null empty). */
|
|
48
|
+
export declare function rowsCsv(rows: DatasetRow[]): string;
|