@sksat/uneri 0.1.1
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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/assets/chartDataWorker-DCpKMXgg.js +12 -0
- package/dist/components/TimeSeriesChart.d.ts +70 -0
- package/dist/db/IngestBuffer.d.ts +59 -0
- package/dist/db/duckdb.d.ts +6 -0
- package/dist/db/store.d.ts +94 -0
- package/dist/hooks/useDuckDB.d.ts +9 -0
- package/dist/hooks/useTimeSeriesStore.d.ts +35 -0
- package/dist/hooks/useTimeSeriesStoreWorker.d.ts +33 -0
- package/dist/index.css +2 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +10460 -0
- package/dist/types.d.ts +36 -0
- package/dist/utils/ChartBuffer.d.ts +57 -0
- package/dist/utils/alignTimeSeries.d.ts +23 -0
- package/dist/utils/chartViewport.d.ts +18 -0
- package/dist/utils/mergeChartData.d.ts +11 -0
- package/dist/worker/chartDataWorker.d.ts +11 -0
- package/dist/worker/chartDataWorkerClient.d.ts +47 -0
- package/dist/worker/multiChartDataWorker.d.ts +10 -0
- package/dist/worker/multiChartDataWorkerClient.d.ts +52 -0
- package/dist/worker/protocol.d.ts +145 -0
- package/package.json +71 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Minimum requirement for a data point: must have a time field. */
|
|
2
|
+
export interface TimePoint {
|
|
3
|
+
readonly t: number;
|
|
4
|
+
}
|
|
5
|
+
/** SQL column type supported by DuckDB. */
|
|
6
|
+
export type ColumnType = "DOUBLE" | "INTEGER" | "BIGINT" | "FLOAT";
|
|
7
|
+
/** Defines a single column in the time-series table. */
|
|
8
|
+
export interface ColumnDef {
|
|
9
|
+
name: string;
|
|
10
|
+
type: ColumnType;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Defines a derived quantity computed from base columns via SQL.
|
|
14
|
+
*
|
|
15
|
+
* **Constraint**: `sql` MUST be a row-local expression — it may only
|
|
16
|
+
* reference columns from the same row. Window functions (LAG, LEAD,
|
|
17
|
+
* AVG(...) OVER, ROW_NUMBER OVER, etc.) and correlated subqueries are
|
|
18
|
+
* NOT supported and will produce incorrect results with incremental queries.
|
|
19
|
+
*/
|
|
20
|
+
export interface DerivedColumn {
|
|
21
|
+
name: string;
|
|
22
|
+
sql: string;
|
|
23
|
+
unit?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Full schema definition for a time-series table. */
|
|
26
|
+
export interface TableSchema<T extends TimePoint = TimePoint> {
|
|
27
|
+
tableName: string;
|
|
28
|
+
columns: ColumnDef[];
|
|
29
|
+
derived: DerivedColumn[];
|
|
30
|
+
toRow(point: T): (number | null)[];
|
|
31
|
+
}
|
|
32
|
+
/** Generic chart data: keyed by column name. */
|
|
33
|
+
export type ChartDataMap = {
|
|
34
|
+
t: Float64Array;
|
|
35
|
+
[derivedName: string]: Float64Array;
|
|
36
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ChartDataMap } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Column-oriented ring buffer for real-time chart display.
|
|
4
|
+
*
|
|
5
|
+
* Stores time-series data as Float64Arrays keyed by column name,
|
|
6
|
+
* matching the ChartDataMap shape expected by uPlot. Supports
|
|
7
|
+
* efficient append and left-trim operations.
|
|
8
|
+
*
|
|
9
|
+
* Used as a DuckDB bypass: during live streaming, data flows
|
|
10
|
+
* directly from WebSocket → ChartBuffer → uPlot.setData().
|
|
11
|
+
*/
|
|
12
|
+
export declare class ChartBuffer {
|
|
13
|
+
private _columns;
|
|
14
|
+
private _data;
|
|
15
|
+
private _length;
|
|
16
|
+
private _capacity;
|
|
17
|
+
/**
|
|
18
|
+
* @param columns Column names (must include "t" as the time axis).
|
|
19
|
+
* @param capacity Maximum number of points before oldest are dropped.
|
|
20
|
+
*/
|
|
21
|
+
constructor(columns: string[], capacity: number);
|
|
22
|
+
get length(): number;
|
|
23
|
+
get capacity(): number;
|
|
24
|
+
get columns(): readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* Append a single row of values.
|
|
27
|
+
* @param values Object with a value for each column name.
|
|
28
|
+
*/
|
|
29
|
+
push(values: Record<string, number>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Append multiple rows at once.
|
|
32
|
+
* @param rows Array of value objects, one per row.
|
|
33
|
+
*/
|
|
34
|
+
pushMany(rows: Record<string, number>[]): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get a snapshot of the current data as ChartDataMap.
|
|
37
|
+
* Returns subarray views (zero-copy) into the internal buffers.
|
|
38
|
+
*/
|
|
39
|
+
toChartData(): ChartDataMap;
|
|
40
|
+
/**
|
|
41
|
+
* Get a windowed view of data for a specific time range.
|
|
42
|
+
* Returns subarray views (zero-copy) for points where tMin <= t <= tMax.
|
|
43
|
+
*/
|
|
44
|
+
getWindow(tMin: number, tMax: number): ChartDataMap;
|
|
45
|
+
/** Clear all data. */
|
|
46
|
+
clear(): void;
|
|
47
|
+
/** The latest time value, or -Infinity if empty. */
|
|
48
|
+
get latestT(): number;
|
|
49
|
+
/** The earliest time value, or Infinity if empty. */
|
|
50
|
+
get earliestT(): number;
|
|
51
|
+
/** Drop the oldest half of the data when capacity is reached. */
|
|
52
|
+
private _trimOldest;
|
|
53
|
+
/** Binary search: first index where arr[i] >= value. */
|
|
54
|
+
private _lowerBound;
|
|
55
|
+
/** Binary search: first index where arr[i] > value. */
|
|
56
|
+
private _upperBound;
|
|
57
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** A single named time series with independent time array. */
|
|
2
|
+
export interface NamedTimeSeries {
|
|
3
|
+
label: string;
|
|
4
|
+
t: Float64Array;
|
|
5
|
+
values: Float64Array;
|
|
6
|
+
}
|
|
7
|
+
/** Result of alignment: shared time array + per-series values (NaN for gaps). */
|
|
8
|
+
export interface AlignedMultiSeries {
|
|
9
|
+
/** Merged, sorted, deduplicated time array. */
|
|
10
|
+
t: Float64Array;
|
|
11
|
+
/** One array per input series, same length as t. Missing values are NaN. */
|
|
12
|
+
values: Float64Array[];
|
|
13
|
+
/** Labels in the same order as values[]. */
|
|
14
|
+
labels: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Merge independent time series into a shared time axis.
|
|
18
|
+
*
|
|
19
|
+
* Each input series may have a different time array. The output has a single
|
|
20
|
+
* merged time array with all unique time values (sorted), and each series
|
|
21
|
+
* is filled with NaN where it has no data at a given time point.
|
|
22
|
+
*/
|
|
23
|
+
export declare function alignTimeSeries(inputs: NamedTimeSeries[]): AlignedMultiSeries;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice typed arrays to a visible time window.
|
|
3
|
+
* Uses binary search (O(log n)) + Float64Array.subarray (zero-copy).
|
|
4
|
+
*
|
|
5
|
+
* @param arrays - Array of Float64Arrays where arrays[0] is the time column.
|
|
6
|
+
* @param currentTime - Right edge of the viewport. If undefined, use all data.
|
|
7
|
+
* @param timeRange - Duration of the viewport window. If null, no left-edge clipping.
|
|
8
|
+
*/
|
|
9
|
+
export declare function sliceArrays(arrays: Float64Array[] | null, currentTime: number | undefined, timeRange: number | null): Float64Array[] | null;
|
|
10
|
+
/**
|
|
11
|
+
* Quantize time to 0.5s steps to reduce useMemo recalculations.
|
|
12
|
+
* 60fps over 10s produces ~20 unique values instead of 600.
|
|
13
|
+
*/
|
|
14
|
+
export declare function quantizeChartTime(time: number | undefined): number | undefined;
|
|
15
|
+
/** Find first index where arr[i] >= value. */
|
|
16
|
+
export declare function lowerBound(arr: Float64Array, value: number, lo: number, hi: number): number;
|
|
17
|
+
/** Find first index where arr[i] > value. */
|
|
18
|
+
export declare function upperBound(arr: Float64Array, value: number, lo: number, hi: number): number;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ChartDataMap } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Concatenate cold snapshot + hot buffer into a single ChartDataMap.
|
|
4
|
+
* Returns `cold` directly when `hot` is null or empty (zero allocation).
|
|
5
|
+
*/
|
|
6
|
+
export declare function mergeChartData(cold: ChartDataMap, hot: ChartDataMap | null, derivedNames: string[]): ChartDataMap;
|
|
7
|
+
/**
|
|
8
|
+
* Trim data points where t < tMin using binary search + subarray (O(1) zero-copy).
|
|
9
|
+
* Returns the original data if no trimming is needed.
|
|
10
|
+
*/
|
|
11
|
+
export declare function trimChartDataLeft(data: ChartDataMap, tMin: number, derivedNames: string[]): ChartDataMap;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart Data Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* Owns DuckDB and runs the cold/hot tick loop autonomously.
|
|
5
|
+
* Receives data points (as row tuples) from the main thread,
|
|
6
|
+
* inserts them into DuckDB, and periodically queries + merges
|
|
7
|
+
* to produce ChartDataMap which is transferred back via zero-copy.
|
|
8
|
+
*
|
|
9
|
+
* This is a direct port of the useTimeSeriesStore tick logic.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread typed wrapper for the chart data Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* Manages Worker lifecycle, message buffering before ready,
|
|
5
|
+
* and typed callbacks for chart data and errors.
|
|
6
|
+
*/
|
|
7
|
+
import type { TimeRange } from "../hooks/useTimeSeriesStore.js";
|
|
8
|
+
import type { ChartDataMap } from "../types.js";
|
|
9
|
+
import type { RowTuple, WorkerTableSchema } from "./protocol.js";
|
|
10
|
+
export declare class ChartDataWorkerClient {
|
|
11
|
+
private worker;
|
|
12
|
+
private ready;
|
|
13
|
+
private disposed;
|
|
14
|
+
private pendingMessages;
|
|
15
|
+
private onDataCallback;
|
|
16
|
+
private onErrorCallback;
|
|
17
|
+
private queryId;
|
|
18
|
+
private debugResolvers;
|
|
19
|
+
private zoomResolvers;
|
|
20
|
+
constructor();
|
|
21
|
+
/** Initialize the Worker with a table schema and optional tick parameters. */
|
|
22
|
+
init(schema: WorkerTableSchema, opts?: {
|
|
23
|
+
tickInterval?: number;
|
|
24
|
+
coldRefreshEveryN?: number;
|
|
25
|
+
hotRowBudget?: number;
|
|
26
|
+
}): void;
|
|
27
|
+
/** Send data points (as pre-converted row tuples) to the Worker. */
|
|
28
|
+
ingest(rows: RowTuple[], latestT: number): void;
|
|
29
|
+
/** Signal a full table rebuild with new data. */
|
|
30
|
+
rebuild(rows: RowTuple[], latestT: number): void;
|
|
31
|
+
/** Update time range and max points configuration. */
|
|
32
|
+
configure(timeRange: TimeRange, maxPoints: number): void;
|
|
33
|
+
/** Register callback for receiving chart data from the Worker. */
|
|
34
|
+
onData(callback: (data: ChartDataMap) => void): void;
|
|
35
|
+
/** Register callback for Worker errors. */
|
|
36
|
+
onError(callback: (message: string) => void): void;
|
|
37
|
+
/** Query the row count in DuckDB (for debug/testing). */
|
|
38
|
+
queryRowCount(): Promise<number>;
|
|
39
|
+
/** Run a zoom query on the Worker's DuckDB and return the result. */
|
|
40
|
+
zoomQuery(tMin: number, tMax: number, maxPoints: number): Promise<ChartDataMap>;
|
|
41
|
+
/** Dispose the Worker and release resources. */
|
|
42
|
+
dispose(): void;
|
|
43
|
+
/** Resolve all pending query Promises so callers don't hang. */
|
|
44
|
+
private resolveAllPending;
|
|
45
|
+
private send;
|
|
46
|
+
private handleMessage;
|
|
47
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-satellite Chart Data Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* Manages N DuckDB tables (one per satellite), runs per-satellite queries
|
|
5
|
+
* with unified tMin/tMax, aligns results via alignTimeSeries, and produces
|
|
6
|
+
* serialized MultiChartDataMap transferred back to the main thread.
|
|
7
|
+
*
|
|
8
|
+
* Direct port of useMultiSatelliteStore tick logic.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread typed wrapper for the multi-satellite chart data Web Worker.
|
|
3
|
+
*/
|
|
4
|
+
import type { TimeRange } from "../hooks/useTimeSeriesStore.js";
|
|
5
|
+
import type { RowTuple, WorkerSatelliteConfig, WorkerTableSchema } from "./protocol.js";
|
|
6
|
+
/** Deserialized multi-series data for a single metric. */
|
|
7
|
+
export interface MultiSeriesResult {
|
|
8
|
+
t: Float64Array;
|
|
9
|
+
values: Float64Array[];
|
|
10
|
+
series: Array<{
|
|
11
|
+
label: string;
|
|
12
|
+
color: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
/** Map from metric name to multi-series data. */
|
|
16
|
+
export type MultiChartDataResult = {
|
|
17
|
+
[metricName: string]: MultiSeriesResult | null;
|
|
18
|
+
};
|
|
19
|
+
export declare class MultiChartDataWorkerClient {
|
|
20
|
+
private worker;
|
|
21
|
+
private ready;
|
|
22
|
+
private disposed;
|
|
23
|
+
private pendingMessages;
|
|
24
|
+
private onDataCallback;
|
|
25
|
+
private onErrorCallback;
|
|
26
|
+
private queryId;
|
|
27
|
+
private zoomResolvers;
|
|
28
|
+
constructor();
|
|
29
|
+
init(baseSchema: WorkerTableSchema, satelliteConfigs: WorkerSatelliteConfig[], metricNames: string[], opts?: {
|
|
30
|
+
tickInterval?: number;
|
|
31
|
+
queryEveryN?: number;
|
|
32
|
+
compactEveryN?: number;
|
|
33
|
+
}): void;
|
|
34
|
+
ingest(satelliteId: string, rows: RowTuple[], latestT: number): void;
|
|
35
|
+
rebuild(satelliteId: string, rows: RowTuple[], latestT: number): void;
|
|
36
|
+
configure(timeRange: TimeRange, maxPoints: number): void;
|
|
37
|
+
updateConfigs(satelliteConfigs: WorkerSatelliteConfig[], metricNames: string[]): void;
|
|
38
|
+
/**
|
|
39
|
+
* Ad-hoc zoom query: request aligned multi-series data for the absolute
|
|
40
|
+
* time window `[tMin, tMax]`, bypassing the tick loop's configured
|
|
41
|
+
* `timeRange`. Returns a Promise that resolves with the same
|
|
42
|
+
* `MultiChartDataResult` shape as `onData`.
|
|
43
|
+
*/
|
|
44
|
+
zoomQuery(tMin: number, tMax: number, maxPoints: number): Promise<MultiChartDataResult>;
|
|
45
|
+
onData(callback: (data: MultiChartDataResult) => void): void;
|
|
46
|
+
onError(callback: (message: string) => void): void;
|
|
47
|
+
dispose(): void;
|
|
48
|
+
/** Resolve all pending zoom promises so callers do not hang on disposal. */
|
|
49
|
+
private resolveAllPending;
|
|
50
|
+
private send;
|
|
51
|
+
private handleMessage;
|
|
52
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message protocol for the chart data Web Worker.
|
|
3
|
+
*
|
|
4
|
+
* The Worker owns DuckDB and the entire tick loop (cold/hot query, merge, trim).
|
|
5
|
+
* The main thread only sends data points and configuration, and receives
|
|
6
|
+
* ready-to-render ChartDataMap via zero-copy ArrayBuffer transfer.
|
|
7
|
+
*/
|
|
8
|
+
import type { TimeRange } from "../hooks/useTimeSeriesStore.js";
|
|
9
|
+
import type { ColumnDef, DerivedColumn } from "../types.js";
|
|
10
|
+
/** A single row as a tuple of nullable numbers, produced by schema.toRow(). */
|
|
11
|
+
export type RowTuple = (number | null)[];
|
|
12
|
+
/**
|
|
13
|
+
* Serializable subset of TableSchema — excludes the `toRow` function
|
|
14
|
+
* which cannot be transferred to a Worker.
|
|
15
|
+
*/
|
|
16
|
+
export interface WorkerTableSchema {
|
|
17
|
+
tableName: string;
|
|
18
|
+
columns: ColumnDef[];
|
|
19
|
+
derived: DerivedColumn[];
|
|
20
|
+
}
|
|
21
|
+
export type MainToWorkerMessage = {
|
|
22
|
+
type: "init";
|
|
23
|
+
schema: WorkerTableSchema;
|
|
24
|
+
tickInterval?: number;
|
|
25
|
+
coldRefreshEveryN?: number;
|
|
26
|
+
hotRowBudget?: number;
|
|
27
|
+
} | {
|
|
28
|
+
type: "ingest";
|
|
29
|
+
rows: RowTuple[];
|
|
30
|
+
latestT: number;
|
|
31
|
+
} | {
|
|
32
|
+
type: "rebuild";
|
|
33
|
+
rows: RowTuple[];
|
|
34
|
+
latestT: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: "configure";
|
|
37
|
+
timeRange: TimeRange;
|
|
38
|
+
maxPoints: number;
|
|
39
|
+
} | {
|
|
40
|
+
type: "dispose";
|
|
41
|
+
} | {
|
|
42
|
+
type: "debug-query";
|
|
43
|
+
id: number;
|
|
44
|
+
query: "row-count";
|
|
45
|
+
} | {
|
|
46
|
+
type: "zoom-query";
|
|
47
|
+
id: number;
|
|
48
|
+
tMin: number;
|
|
49
|
+
tMax: number;
|
|
50
|
+
maxPoints: number;
|
|
51
|
+
};
|
|
52
|
+
/** Serializable satellite config (matches SatelliteConfig from buildMultiChartData). */
|
|
53
|
+
export interface WorkerSatelliteConfig {
|
|
54
|
+
id: string;
|
|
55
|
+
label: string;
|
|
56
|
+
color: string;
|
|
57
|
+
}
|
|
58
|
+
export type MultiMainToWorkerMessage = {
|
|
59
|
+
type: "multi-init";
|
|
60
|
+
baseSchema: WorkerTableSchema;
|
|
61
|
+
satelliteConfigs: WorkerSatelliteConfig[];
|
|
62
|
+
metricNames: string[];
|
|
63
|
+
tickInterval?: number;
|
|
64
|
+
queryEveryN?: number;
|
|
65
|
+
compactEveryN?: number;
|
|
66
|
+
} | {
|
|
67
|
+
type: "multi-ingest";
|
|
68
|
+
satelliteId: string;
|
|
69
|
+
rows: RowTuple[];
|
|
70
|
+
latestT: number;
|
|
71
|
+
} | {
|
|
72
|
+
type: "multi-rebuild";
|
|
73
|
+
satelliteId: string;
|
|
74
|
+
rows: RowTuple[];
|
|
75
|
+
latestT: number;
|
|
76
|
+
} | {
|
|
77
|
+
type: "multi-configure";
|
|
78
|
+
timeRange: TimeRange;
|
|
79
|
+
maxPoints: number;
|
|
80
|
+
} | {
|
|
81
|
+
type: "multi-update-configs";
|
|
82
|
+
satelliteConfigs: WorkerSatelliteConfig[];
|
|
83
|
+
metricNames: string[];
|
|
84
|
+
} | {
|
|
85
|
+
/**
|
|
86
|
+
* Ad-hoc zoom query: return aligned multi-series data for the absolute
|
|
87
|
+
* time window `[tMin, tMax]`, bypassing the configured `timeRange`.
|
|
88
|
+
* Each satellite's DuckDB is queried for the same window; results
|
|
89
|
+
* are aligned and returned as a one-shot response keyed by `id`.
|
|
90
|
+
*/
|
|
91
|
+
type: "multi-zoom-query";
|
|
92
|
+
id: number;
|
|
93
|
+
tMin: number;
|
|
94
|
+
tMax: number;
|
|
95
|
+
maxPoints: number;
|
|
96
|
+
} | {
|
|
97
|
+
type: "dispose";
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Serialized MultiSeriesData for a single metric.
|
|
101
|
+
* `t` is the aligned time array, `values` are per-satellite value arrays.
|
|
102
|
+
*/
|
|
103
|
+
export interface SerializedMultiSeriesData {
|
|
104
|
+
metricName: string;
|
|
105
|
+
seriesLabels: string[];
|
|
106
|
+
seriesColors: string[];
|
|
107
|
+
/** [t, values[0], values[1], ...] — all transferred. */
|
|
108
|
+
buffers: ArrayBuffer[];
|
|
109
|
+
}
|
|
110
|
+
export type MultiWorkerToMainMessage = {
|
|
111
|
+
type: "ready";
|
|
112
|
+
} | {
|
|
113
|
+
type: "multi-chart-data";
|
|
114
|
+
/** One entry per metric that has data. */
|
|
115
|
+
metrics: SerializedMultiSeriesData[];
|
|
116
|
+
} | {
|
|
117
|
+
/** One-shot response to a `multi-zoom-query`, correlated by `id`. */
|
|
118
|
+
type: "multi-zoom-result";
|
|
119
|
+
id: number;
|
|
120
|
+
metrics: SerializedMultiSeriesData[];
|
|
121
|
+
} | {
|
|
122
|
+
type: "error";
|
|
123
|
+
message: string;
|
|
124
|
+
};
|
|
125
|
+
export type WorkerToMainMessage = {
|
|
126
|
+
type: "ready";
|
|
127
|
+
} | {
|
|
128
|
+
type: "chart-data";
|
|
129
|
+
/** Column names in the same order as buffers. */
|
|
130
|
+
keys: string[];
|
|
131
|
+
/** One ArrayBuffer per column — transferred (zero-copy). */
|
|
132
|
+
buffers: ArrayBuffer[];
|
|
133
|
+
} | {
|
|
134
|
+
type: "error";
|
|
135
|
+
message: string;
|
|
136
|
+
} | {
|
|
137
|
+
type: "debug-result";
|
|
138
|
+
id: number;
|
|
139
|
+
result: number;
|
|
140
|
+
} | {
|
|
141
|
+
type: "zoom-result";
|
|
142
|
+
id: number;
|
|
143
|
+
keys: string[];
|
|
144
|
+
buffers: ArrayBuffer[];
|
|
145
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sksat/uneri",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "DuckDB-wasm + uPlot real-time time-series charting for streaming simulation data.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"duckdb",
|
|
7
|
+
"wasm",
|
|
8
|
+
"charting",
|
|
9
|
+
"uplot",
|
|
10
|
+
"time-series",
|
|
11
|
+
"visualization"
|
|
12
|
+
],
|
|
13
|
+
"author": "sksat <sksat@sksat.net>",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/sksat/orts",
|
|
18
|
+
"directory": "uneri"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://sksat.github.io/orts/",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./style.css": "./dist/index.css",
|
|
30
|
+
"./align": "./src/utils/alignTimeSeries.ts",
|
|
31
|
+
"./multiWorkerClient": "./src/worker/multiChartDataWorkerClient.ts",
|
|
32
|
+
"./workerProtocol": "./src/worker/protocol.ts"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"react": ">=18.0.0",
|
|
39
|
+
"react-dom": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@duckdb/duckdb-wasm": "1.32.0",
|
|
43
|
+
"uplot": "^1.6.32"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@playwright/test": "^1.58.2",
|
|
47
|
+
"@types/react": "^19.2.13",
|
|
48
|
+
"@types/react-dom": "^19.2.3",
|
|
49
|
+
"@types/ws": "^8.18.1",
|
|
50
|
+
"@vitejs/plugin-react": "^6.0.0",
|
|
51
|
+
"happy-dom": "^20.5.0",
|
|
52
|
+
"react": "^19.2.4",
|
|
53
|
+
"react-dom": "^19.2.4",
|
|
54
|
+
"tsx": "^4.19.0",
|
|
55
|
+
"typescript": "^5.7.0",
|
|
56
|
+
"vite": "^8.0.8",
|
|
57
|
+
"vite-plugin-dts": "^4.0.0",
|
|
58
|
+
"vitest": "^4.1.4",
|
|
59
|
+
"ws": "^8.18.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"test:watch": "vitest",
|
|
65
|
+
"test:e2e": "playwright test",
|
|
66
|
+
"example:sine-wave": "npx tsx examples/sine-wave/server.ts & npx vite --config vite.example.config.ts --port 5174",
|
|
67
|
+
"example:mixed-density": "npx tsx examples/mixed-density/server.ts & npx vite --config vite.mixed-density.config.ts --port 5175",
|
|
68
|
+
"example:multi-series": "npx tsx examples/multi-series/server.ts & npx vite --config vite.multi-series.config.ts --port 5176",
|
|
69
|
+
"example:multi-table": "npx tsx examples/multi-table/server.ts & npx vite --config vite.multi-table.config.ts --port 5177"
|
|
70
|
+
}
|
|
71
|
+
}
|