@uwrl/qc-utils 0.0.18 → 0.0.19
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/index.js +16 -16
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/models/dataSource.d.ts +0 -173
- package/dist/models/index.d.ts +0 -2
- package/dist/models/payload.d.ts +0 -24
- package/dist/models/settings.d.ts +0 -65
- package/dist/models/timestamp.d.ts +0 -150
- package/dist/services/__tests__/createPatchObject.spec.d.ts +0 -1
- package/dist/services/__tests__/requestInterceptor.spec.d.ts +0 -1
- package/dist/services/__tests__/responseInterceptor.spec.d.ts +0 -1
- package/dist/services/api.d.ts +0 -147
- package/dist/services/apiMethods.d.ts +0 -8
- package/dist/services/createPatchObject.d.ts +0 -17
- package/dist/services/getCSRFToken.d.ts +0 -1
- package/dist/services/index.d.ts +0 -6
- package/dist/services/requestInterceptor.d.ts +0 -12
- package/dist/services/responseInterceptor.d.ts +0 -2
- package/dist/types/index.d.ts +0 -372
- package/dist/utils/__tests__/ellapsed-time.spec.d.ts +0 -1
- package/dist/utils/__tests__/format.spec.d.ts +0 -1
- package/dist/utils/__tests__/notifications.spec.d.ts +0 -1
- package/dist/utils/__tests__/observations.spec.d.ts +0 -1
- package/dist/utils/ellapsed-time.d.ts +0 -4
- package/dist/utils/format.d.ts +0 -4
- package/dist/utils/index.d.ts +0 -6
- package/dist/utils/notifications.d.ts +0 -46
- package/dist/utils/observations.d.ts +0 -5
- package/dist/utils/plotting/__tests__/calibration.spec.d.ts +0 -16
- package/dist/utils/plotting/__tests__/mock.d.ts +0 -4
- package/dist/utils/plotting/__tests__/observation-record-paths.spec.d.ts +0 -21
- package/dist/utils/plotting/__tests__/observation-record.spec.d.ts +0 -1
- package/dist/utils/plotting/__tests__/operation-cores.spec.d.ts +0 -12
- package/dist/utils/plotting/__tests__/workerMocks.d.ts +0 -119
- package/dist/utils/plotting/__tests__/workers.spec.d.ts +0 -18
- package/dist/utils/plotting/add-data.worker.d.ts +0 -1
- package/dist/utils/plotting/calibration.d.ts +0 -99
- package/dist/utils/plotting/change-values.worker.d.ts +0 -1
- package/dist/utils/plotting/change.worker.d.ts +0 -1
- package/dist/utils/plotting/delete-data.worker.d.ts +0 -1
- package/dist/utils/plotting/drift-correction.worker.d.ts +0 -1
- package/dist/utils/plotting/fill-gaps.worker.d.ts +0 -1
- package/dist/utils/plotting/find-gaps.worker.d.ts +0 -1
- package/dist/utils/plotting/interpolate.worker.d.ts +0 -1
- package/dist/utils/plotting/observation-record.d.ts +0 -281
- package/dist/utils/plotting/operation-cores.d.ts +0 -139
- package/dist/utils/plotting/persistence.worker.d.ts +0 -1
- package/dist/utils/plotting/rate-of-change.worker.d.ts +0 -1
- package/dist/utils/plotting/shift-datetimes.worker.d.ts +0 -1
- package/dist/utils/plotting/value-threshold.worker.d.ts +0 -1
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for the public surface of `calibration.ts`.
|
|
3
|
-
*
|
|
4
|
-
* The module imports `value-threshold.worker?worker&inline` eagerly, which
|
|
5
|
-
* Vite transforms in the app build but not in Vitest + happy-dom — so we
|
|
6
|
-
* substitute the same `MockValueThresholdWorker` used by
|
|
7
|
-
* `observation-record.spec.ts` to give `runBenchmarks()` a working worker
|
|
8
|
-
* constructor. The mock round-trips via `queueMicrotask`, which is enough
|
|
9
|
-
* for `ensureCalibration()` to complete synchronously-ish in tests.
|
|
10
|
-
*
|
|
11
|
-
* Module state (`activeProfile`, `lastBenchmarkDetail`, `listeners`,
|
|
12
|
-
* `localStorage`) lives at import scope, so every test begins with a
|
|
13
|
-
* `clearCalibration()` and a `localStorage.clear()` to avoid cross-
|
|
14
|
-
* pollination.
|
|
15
|
-
*/
|
|
16
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Coverage-focused tests for `observation-record.ts` that exercise
|
|
3
|
-
* paths the baseline spec skips:
|
|
4
|
-
*
|
|
5
|
-
* 1. **Worker fan-out paths** — every `_operation` routes through
|
|
6
|
-
* `shouldUseWorker()` and falls back to an inline core for small
|
|
7
|
-
* inputs. The existing `observation-record.spec.ts` uses tiny
|
|
8
|
-
* datasets, so only the inline branches run. Here we mock
|
|
9
|
-
* `../calibration` so callers can flip `forceWorker = true` and
|
|
10
|
-
* drive the worker branches without needing multi-MB fixtures.
|
|
11
|
-
* 2. **Bulk assignment ops** — `ASSIGN_VALUES_BULK` and
|
|
12
|
-
* `ASSIGN_DATETIMES_BULK` aren't touched by the baseline spec.
|
|
13
|
-
* 3. **Undo / redo** — `undo()` / `redo()` have their own state
|
|
14
|
-
* machines that aren't driven by the `dispatch()` tests.
|
|
15
|
-
* 4. **DATETIME_RANGE, SELECTION pop** — the remaining filter ops.
|
|
16
|
-
*
|
|
17
|
-
* Mocks are hoisted via `vi.mock`; the real calibration module is
|
|
18
|
-
* wrapped so non-mocked helpers (getCalibration, etc.) still work if
|
|
19
|
-
* anything reaches for them.
|
|
20
|
-
*/
|
|
21
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Direct unit tests for the pure kernels in `operation-cores.ts`. These
|
|
3
|
-
* functions are the shared source of truth for every `*.worker.ts` with an
|
|
4
|
-
* inline equivalent, so once they pass here the worker wrappers only need a
|
|
5
|
-
* thin "message in / message out" check (see `workers.spec.ts`).
|
|
6
|
-
*
|
|
7
|
-
* Cores are deliberately framework-free and accept plain typed arrays, so
|
|
8
|
-
* these tests build buffers from raw `Float32Array` / `Float64Array` rather
|
|
9
|
-
* than `SharedArrayBuffer`. Semantics are identical and happy-dom doesn't
|
|
10
|
-
* require the cross-origin-isolation headers SAB would.
|
|
11
|
-
*/
|
|
12
|
-
export {};
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-process mock implementations of every worker used by `ObservationRecord`.
|
|
3
|
-
*
|
|
4
|
-
* The real workers are loaded via Vite's `?worker&inline` query, which is not
|
|
5
|
-
* available in Vitest + happy-dom. Each mock here re-implements the logic of
|
|
6
|
-
* the matching `*.worker.ts` file and runs synchronously via `queueMicrotask`,
|
|
7
|
-
* which is enough to exercise every code path in `observation-record.ts`
|
|
8
|
-
* end-to-end. The handler is scheduled via microtask so the caller has a chance
|
|
9
|
-
* to assign `onmessage` before the response is dispatched (matching the real
|
|
10
|
-
* Worker API contract).
|
|
11
|
-
*/
|
|
12
|
-
export declare const MockDeleteDataWorker: {
|
|
13
|
-
new (): {
|
|
14
|
-
onmessage: ((event: {
|
|
15
|
-
data: any;
|
|
16
|
-
}) => void) | null;
|
|
17
|
-
postMessage(data: any): void;
|
|
18
|
-
terminate(): void;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
export declare const MockAddDataWorker: {
|
|
22
|
-
new (): {
|
|
23
|
-
onmessage: ((event: {
|
|
24
|
-
data: any;
|
|
25
|
-
}) => void) | null;
|
|
26
|
-
postMessage(data: any): void;
|
|
27
|
-
terminate(): void;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
export declare const MockChangeValuesWorker: {
|
|
31
|
-
new (): {
|
|
32
|
-
onmessage: ((event: {
|
|
33
|
-
data: any;
|
|
34
|
-
}) => void) | null;
|
|
35
|
-
postMessage(data: any): void;
|
|
36
|
-
terminate(): void;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
export declare const MockInterpolateWorker: {
|
|
40
|
-
new (): {
|
|
41
|
-
onmessage: ((event: {
|
|
42
|
-
data: any;
|
|
43
|
-
}) => void) | null;
|
|
44
|
-
postMessage(data: any): void;
|
|
45
|
-
terminate(): void;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
export declare const MockDriftCorrectionWorker: {
|
|
49
|
-
new (): {
|
|
50
|
-
onmessage: ((event: {
|
|
51
|
-
data: any;
|
|
52
|
-
}) => void) | null;
|
|
53
|
-
postMessage(data: any): void;
|
|
54
|
-
terminate(): void;
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
export declare const MockShiftDatetimesWorker: {
|
|
58
|
-
new (): {
|
|
59
|
-
onmessage: ((event: {
|
|
60
|
-
data: any;
|
|
61
|
-
}) => void) | null;
|
|
62
|
-
postMessage(data: any): void;
|
|
63
|
-
terminate(): void;
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
export declare const MockFillGapsWorker: {
|
|
67
|
-
new (): {
|
|
68
|
-
onmessage: ((event: {
|
|
69
|
-
data: any;
|
|
70
|
-
}) => void) | null;
|
|
71
|
-
postMessage(data: any): void;
|
|
72
|
-
terminate(): void;
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
export declare const MockFindGapsWorker: {
|
|
76
|
-
new (): {
|
|
77
|
-
onmessage: ((event: {
|
|
78
|
-
data: any;
|
|
79
|
-
}) => void) | null;
|
|
80
|
-
postMessage(data: any): void;
|
|
81
|
-
terminate(): void;
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
export declare const MockPersistenceWorker: {
|
|
85
|
-
new (): {
|
|
86
|
-
onmessage: ((event: {
|
|
87
|
-
data: any;
|
|
88
|
-
}) => void) | null;
|
|
89
|
-
postMessage(data: any): void;
|
|
90
|
-
terminate(): void;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
export declare const MockChangeWorker: {
|
|
94
|
-
new (): {
|
|
95
|
-
onmessage: ((event: {
|
|
96
|
-
data: any;
|
|
97
|
-
}) => void) | null;
|
|
98
|
-
postMessage(data: any): void;
|
|
99
|
-
terminate(): void;
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
export declare const MockRateOfChangeWorker: {
|
|
103
|
-
new (): {
|
|
104
|
-
onmessage: ((event: {
|
|
105
|
-
data: any;
|
|
106
|
-
}) => void) | null;
|
|
107
|
-
postMessage(data: any): void;
|
|
108
|
-
terminate(): void;
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
export declare const MockValueThresholdWorker: {
|
|
112
|
-
new (): {
|
|
113
|
-
onmessage: ((event: {
|
|
114
|
-
data: any;
|
|
115
|
-
}) => void) | null;
|
|
116
|
-
postMessage(data: any): void;
|
|
117
|
-
terminate(): void;
|
|
118
|
-
};
|
|
119
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wiring smoke tests for every `*.worker.ts` module.
|
|
3
|
-
*
|
|
4
|
-
* The algorithmic behaviour of each kernel is covered in
|
|
5
|
-
* `operation-cores.spec.ts`, so these tests only verify the worker
|
|
6
|
-
* handler is installed and forwards its payload to its core — i.e. the
|
|
7
|
-
* thin shell is plumbed correctly. Two workers still carry inline
|
|
8
|
-
* logic that has no core counterpart (`drift-correction.worker.ts` and
|
|
9
|
-
* `shift-datetimes.worker.ts`), so we keep behavioural assertions for
|
|
10
|
-
* those.
|
|
11
|
-
*
|
|
12
|
-
* Each worker file registers its handler via `self.onmessage = ...` at
|
|
13
|
-
* module evaluation time. We import each module once, capture its
|
|
14
|
-
* handler, and invoke it synchronously with `self.postMessage`
|
|
15
|
-
* redirected to a local capture buffer. `self` resolves to the global
|
|
16
|
-
* `Window` under happy-dom.
|
|
17
|
-
*/
|
|
18
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { EnumEditOperations, EnumFilterOperations } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Device-specific primitives measured during the benchmark. Everything
|
|
4
|
-
* is in consistent units:
|
|
5
|
-
* - `spawnOverheadMs` — wall-clock ms for one postMessage roundtrip
|
|
6
|
-
* including worker construction and termination,
|
|
7
|
-
* - `inlineThroughput` / `workerThroughput` — elements scanned per
|
|
8
|
-
* millisecond on a reference O(n) kernel (value-threshold).
|
|
9
|
-
*/
|
|
10
|
-
export interface DeviceProfile {
|
|
11
|
-
spawnOverheadMs: number;
|
|
12
|
-
inlineThroughput: number;
|
|
13
|
-
workerThroughput: number;
|
|
14
|
-
hwConcurrency: number;
|
|
15
|
-
measuredAt: number;
|
|
16
|
-
userAgent: string;
|
|
17
|
-
}
|
|
18
|
-
export interface BenchmarkDetail extends DeviceProfile {
|
|
19
|
-
sharedArrayBufferAvailable: boolean;
|
|
20
|
-
samples: {
|
|
21
|
-
spawnRoundtripMs: number[];
|
|
22
|
-
inlineScanMs: number[];
|
|
23
|
-
workerScanMs: number[];
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
/** Subscribers notified after every successful recalibration. */
|
|
27
|
-
type CalibrationListener = (profile: DeviceProfile) => void;
|
|
28
|
-
/**
|
|
29
|
-
* Per-operation algorithm descriptor. `weight` is the kernel's relative
|
|
30
|
-
* cost per element compared to the reference value-threshold scan
|
|
31
|
-
* (weight 1). `mode`:
|
|
32
|
-
* - `always-inline`: never worth the worker hop (O(log n), pure
|
|
33
|
-
* bookkeeping, or already single-shot loops),
|
|
34
|
-
* - `always-worker`: escape hatch for kernels that genuinely
|
|
35
|
-
* need thread-level parallelism (none in the current catalog),
|
|
36
|
-
* - `calibrated`: dispatch decides per-call using the estimator.
|
|
37
|
-
*/
|
|
38
|
-
type OperationMode = 'always-inline' | 'always-worker' | 'calibrated';
|
|
39
|
-
export interface DispatchSignals {
|
|
40
|
-
/** Total dataset length in points (source.x.length). */
|
|
41
|
-
datasetSize: number;
|
|
42
|
-
/** Indices involved when the op is selection-bound; 0 for full-scan. */
|
|
43
|
-
selectionSize?: number;
|
|
44
|
-
/** Override the measured workers count (defaults to hwConcurrency). */
|
|
45
|
-
parallelism?: number;
|
|
46
|
-
}
|
|
47
|
-
export interface DispatchDecision {
|
|
48
|
-
useWorker: boolean;
|
|
49
|
-
predictedInlineMs: number;
|
|
50
|
-
predictedWorkerMs: number;
|
|
51
|
-
/** Human-readable explanation (e.g. "inline faster at N=200"). */
|
|
52
|
-
reason: string;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Core dispatch decision. Returns `useWorker: false` when the
|
|
56
|
-
* predicted inline runtime beats the worker runtime (spawn overhead
|
|
57
|
-
* plus in-loop work divided across workers). Callers should short-
|
|
58
|
-
* circuit to the inline path when `useWorker` is false.
|
|
59
|
-
*/
|
|
60
|
-
export declare function shouldUseWorker(op: EnumEditOperations | EnumFilterOperations, signals: DispatchSignals): DispatchDecision;
|
|
61
|
-
/** Subscribe for post-benchmark updates (UI badge, etc.). */
|
|
62
|
-
export declare function onCalibrationChange(listener: CalibrationListener): () => void;
|
|
63
|
-
/** Read the active profile without triggering a benchmark. */
|
|
64
|
-
export declare function getCalibration(): DeviceProfile;
|
|
65
|
-
/** Detail snapshot for the dev popover; `null` until a benchmark runs. */
|
|
66
|
-
export declare function getLastBenchmarkDetail(): BenchmarkDetail | null;
|
|
67
|
-
/** Operation table for UI display (README + dev popover). */
|
|
68
|
-
export declare function getOperationTable(): ReadonlyArray<{
|
|
69
|
-
op: EnumEditOperations | EnumFilterOperations;
|
|
70
|
-
mode: OperationMode;
|
|
71
|
-
weight: number;
|
|
72
|
-
rationale: string;
|
|
73
|
-
}>;
|
|
74
|
-
/** Clear cached calibration — mostly for tests / debugging. */
|
|
75
|
-
export declare function clearCalibration(): void;
|
|
76
|
-
/**
|
|
77
|
-
* Kick off a benchmark when:
|
|
78
|
-
* - no profile exists yet, or
|
|
79
|
-
* - `force` is set (user clicked Recalibrate), or
|
|
80
|
-
* - the cached measurement is older than `STALE_AFTER_MS`.
|
|
81
|
-
* Returns the active profile immediately; use `onCalibrationChange`
|
|
82
|
-
* or the resolved `Promise<BenchmarkDetail>` to observe the result.
|
|
83
|
-
*/
|
|
84
|
-
export declare function ensureCalibration(opts?: {
|
|
85
|
-
force?: boolean;
|
|
86
|
-
}): Promise<DeviceProfile>;
|
|
87
|
-
/**
|
|
88
|
-
* Run the three microbenchmarks: worker spawn roundtrip, inline
|
|
89
|
-
* scan throughput, worker scan throughput. Each is sampled three
|
|
90
|
-
* times; we take the median to shake out noise. All numbers are in
|
|
91
|
-
* elements-per-millisecond or milliseconds.
|
|
92
|
-
*
|
|
93
|
-
* Uses the VALUE_THRESHOLD kernel as the reference scan because it
|
|
94
|
-
* already has both an inline core and a worker; per-op weights in
|
|
95
|
-
* `OPERATION_TABLE` are normalised to this baseline so a single
|
|
96
|
-
* throughput measurement covers all `calibrated` ops.
|
|
97
|
-
*/
|
|
98
|
-
export declare function runBenchmarks(): Promise<BenchmarkDetail>;
|
|
99
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import { EnumEditOperations, EnumFilterOperations, HistoryItem } from "../../types";
|
|
2
|
-
/**
|
|
3
|
-
* This number should approximate the number of observations that a dataset could increase by during a session.
|
|
4
|
-
* The lower this number, the less memory the entire app uses.
|
|
5
|
-
* Note that when a dataset number of data points increases by more than `INCREASE_AMOUNT`,
|
|
6
|
-
* the `_growBuffer()` method will allocate a new buffer, and the data will be copied into it.
|
|
7
|
-
*/
|
|
8
|
-
export declare const INCREASE_AMOUNT: number;
|
|
9
|
-
export declare class ObservationRecord {
|
|
10
|
-
/** The generated dataset to be used for plotting */
|
|
11
|
-
dataset: {
|
|
12
|
-
dimensions: string[];
|
|
13
|
-
source: {
|
|
14
|
-
x: Float64Array<SharedArrayBuffer>;
|
|
15
|
-
y: Float32Array<SharedArrayBuffer>;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
history: HistoryItem[];
|
|
19
|
-
/**
|
|
20
|
-
* Items popped off `history` by `undo()`, in undo order (top of stack
|
|
21
|
-
* at the end). `redo()` re-dispatches the top. A fresh `dispatchAction`
|
|
22
|
-
* / `dispatchFilter` call clears the stack — Word-style behavior where
|
|
23
|
-
* a new edit invalidates the redo chain.
|
|
24
|
-
*/
|
|
25
|
-
redoStack: HistoryItem[];
|
|
26
|
-
/**
|
|
27
|
-
* True while `undo()` / `redo()` is replaying a captured history entry.
|
|
28
|
-
* Suppresses the redo-stack clearing that otherwise fires on every new
|
|
29
|
-
* dispatch, so the stack survives the internal replay.
|
|
30
|
-
*/
|
|
31
|
-
private _isReplaying;
|
|
32
|
-
/**
|
|
33
|
-
* Set by each operation handler (or any of its subroutines) to record
|
|
34
|
-
* whether a worker was actually spawned during this dispatch. Sticky-
|
|
35
|
-
* upgrade semantics: the wrapper resets it to `"inline"` before the
|
|
36
|
-
* handler runs, and any code that spawns a worker flips it to
|
|
37
|
-
* `"worker"`. Once flipped it stays flipped for the rest of the
|
|
38
|
-
* dispatch — so an op whose top-level decision is "inline" but whose
|
|
39
|
-
* sub-op (e.g. `_shift` → `_deleteDataPoints`) still spawns workers
|
|
40
|
-
* will honestly show `"worker"` on its history entry.
|
|
41
|
-
*/
|
|
42
|
-
private _pendingExecutionMode;
|
|
43
|
-
loadingTime: number | null;
|
|
44
|
-
isLoading: boolean;
|
|
45
|
-
rawData: {
|
|
46
|
-
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
47
|
-
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
48
|
-
};
|
|
49
|
-
constructor(dataArrays: {
|
|
50
|
-
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
51
|
-
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
52
|
-
});
|
|
53
|
-
loadData(dataArrays: {
|
|
54
|
-
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
55
|
-
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
56
|
-
}): Promise<void>;
|
|
57
|
-
get dataX(): Float64Array<SharedArrayBuffer>;
|
|
58
|
-
get dataY(): Float32Array<SharedArrayBuffer>;
|
|
59
|
-
/**
|
|
60
|
-
* Resizes the typed array
|
|
61
|
-
* @param length The total number of elements that the view will contain
|
|
62
|
-
*/
|
|
63
|
-
private _resizeTo;
|
|
64
|
-
/**
|
|
65
|
-
* Buffer size is always in increments of `INCREASE_AMOUNT`.
|
|
66
|
-
* Grows the buffer by `INCREASE_AMOUNT` in bytes if the current data doesn't fit
|
|
67
|
-
* @param newLength The total number of elements that the view will contain
|
|
68
|
-
*/
|
|
69
|
-
private _growBuffer;
|
|
70
|
-
/**
|
|
71
|
-
* Reloads the dataset with the raw data
|
|
72
|
-
*/
|
|
73
|
-
reload(): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* @param index
|
|
76
|
-
* @returns
|
|
77
|
-
*/
|
|
78
|
-
reloadHistory(index: number): Promise<number[]>;
|
|
79
|
-
/**
|
|
80
|
-
* Remove a history item
|
|
81
|
-
* @param index
|
|
82
|
-
*/
|
|
83
|
-
removeHistoryItem(index: number): Promise<number[]>;
|
|
84
|
-
/**
|
|
85
|
-
* Undo the most recent history entry. Pushes it onto `redoStack` so a
|
|
86
|
-
* subsequent `redo()` can re-apply it, then reloads from the raw
|
|
87
|
-
* dataset and replays the remaining history in order.
|
|
88
|
-
*/
|
|
89
|
-
undo(): Promise<number[]>;
|
|
90
|
-
/**
|
|
91
|
-
* Re-apply the most recently undone entry from `redoStack`. The replay
|
|
92
|
-
* runs through `dispatch`, which pushes a fresh history entry for it;
|
|
93
|
-
* `_isReplaying` guards the redo stack from being wiped during the
|
|
94
|
-
* dispatch.
|
|
95
|
-
*/
|
|
96
|
-
redo(): Promise<number[]>;
|
|
97
|
-
get beginTime(): Date | null;
|
|
98
|
-
get endTime(): Date | null;
|
|
99
|
-
/** Dispatch an operation and log its signature in hisotry */
|
|
100
|
-
dispatchAction(action: EnumEditOperations, ...args: any): Promise<number[]>;
|
|
101
|
-
dispatch(actions: EnumEditOperations | EnumFilterOperations | [EnumEditOperations | EnumFilterOperations, ...any][], ...args: any): Promise<number[]>;
|
|
102
|
-
/** Filter operations do not transform the data and return a selection */
|
|
103
|
-
dispatchFilter(action: EnumFilterOperations, ...args: any): Promise<number[]>;
|
|
104
|
-
/**
|
|
105
|
-
* @param index An array containing the list of index of values to perform the operations on.
|
|
106
|
-
* @param operator The operator that will be applied
|
|
107
|
-
* @param value The value to use in the operation
|
|
108
|
-
* @returns an array of index values to keep selected in the plot
|
|
109
|
-
*/
|
|
110
|
-
/**
|
|
111
|
-
* Multi-threaded apply of an arithmetic operator to Y at the previously-filtered selection.
|
|
112
|
-
* 1. Selection is read from the previous history entry (the last entry is this operation itself).
|
|
113
|
-
* 2. Selection indexes are sharded into disjoint chunks; workers write in place to shared Y.
|
|
114
|
-
* 3. Writes are conflict-free because the selection carries distinct indexes.
|
|
115
|
-
*/
|
|
116
|
-
private _changeValues;
|
|
117
|
-
/**
|
|
118
|
-
* Apply an arithmetic operator to Y in-place on the main thread. Thin
|
|
119
|
-
* wrapper around {@link changeValuesCore} kept so `_assignValuesBulk`
|
|
120
|
-
* and callers outside this module can use the same routine the
|
|
121
|
-
* CHANGE_VALUES fast path does.
|
|
122
|
-
*/
|
|
123
|
-
private _applyOperatorInPlace;
|
|
124
|
-
/**
|
|
125
|
-
* One-shot assignment of distinct Y-values at the indices logged by the
|
|
126
|
-
* previous SELECTION filter entry. Args: `(values: number[])`, where
|
|
127
|
-
* `values[i]` is written to `dataY[selection[i]]`. Runs as a single
|
|
128
|
-
* tight loop on the main thread — no workers, no per-row dispatch
|
|
129
|
-
* ceremony. Intended for table-driven edits.
|
|
130
|
-
*
|
|
131
|
-
* Expected dispatch order (matches CHANGE_VALUES):
|
|
132
|
-
* [[SELECTION, indices], [ASSIGN_VALUES_BULK, values]]
|
|
133
|
-
* The SELECTION entry carries the indices for history, so this op does
|
|
134
|
-
* not log them again.
|
|
135
|
-
*/
|
|
136
|
-
private _assignValuesBulk;
|
|
137
|
-
/**
|
|
138
|
-
* One-shot assignment of distinct datetimes (epoch-ms) at the indices
|
|
139
|
-
* logged by the previous SELECTION filter entry. Internally: compute
|
|
140
|
-
* the replacement (x, y) pairs, do a single delete + single add — so
|
|
141
|
-
* the reindex-and-sort step runs once regardless of how many rows changed.
|
|
142
|
-
*
|
|
143
|
-
* Expected dispatch order (matches SHIFT_DATETIMES pattern):
|
|
144
|
-
* [[SELECTION, indices], [ASSIGN_DATETIMES_BULK, datetimes]]
|
|
145
|
-
*/
|
|
146
|
-
private _assignDatetimesBulk;
|
|
147
|
-
/**
|
|
148
|
-
* Multi-threaded linear interpolation over the selected indexes.
|
|
149
|
-
* 1. Main thread partitions the selected indexes into consecutive groups and computes each group's lower/upper anchors.
|
|
150
|
-
* 2. Groups are sharded across workers (disjoint by construction, so in-place writes are safe).
|
|
151
|
-
* 3. Each worker writes interpolated Y values directly into the shared Y buffer — no output copy needed since only a subset of Y changes.
|
|
152
|
-
*/
|
|
153
|
-
private _interpolate;
|
|
154
|
-
/** Interpolate existing values in the data source */
|
|
155
|
-
/**
|
|
156
|
-
* Shifts the selected indexes by specified amount of units. Elements are reinserted according to their datetime.
|
|
157
|
-
* @param index The index of the elements to shift
|
|
158
|
-
* @param amount Number of {@link TimeUnit}
|
|
159
|
-
* @param unit {@link TimeUnit}
|
|
160
|
-
* @returns
|
|
161
|
-
*/
|
|
162
|
-
private _shift;
|
|
163
|
-
/**
|
|
164
|
-
* Multi-threaded version of {@link _fillGaps}.
|
|
165
|
-
* 1. The main thread scans once for gaps and computes the number of fill points per gap.
|
|
166
|
-
* 2. The original array is split into equal segments; each gap is assigned to the segment containing its left index.
|
|
167
|
-
* 3. Cumulative fill counts before each segment give each worker's output startTarget, ensuring no overlap.
|
|
168
|
-
* 4. Each worker copies its segment to the output buffer and inserts its gap fills inline.
|
|
169
|
-
*/
|
|
170
|
-
private _fillGaps;
|
|
171
|
-
/**
|
|
172
|
-
Deletes data points from a large array using worker threads.
|
|
173
|
-
1. The main thread divides the original array into equal parts to distribute work among workers.
|
|
174
|
-
2. For each segment, binary search locates the indexes to delete (deleteSegment), ensuring efficient lookups.
|
|
175
|
-
3. The cumulative deletions before each segment help compute the starting index (startTarget) for each worker's output, ensuring no overlap.
|
|
176
|
-
4. Each worker processes its segment linearly, skipping deletions and copying kept elements to their computed positions.
|
|
177
|
-
* @param deleteIndices
|
|
178
|
-
*/
|
|
179
|
-
private _deleteDataPoints;
|
|
180
|
-
/**
|
|
181
|
-
*
|
|
182
|
-
* @param start The start index
|
|
183
|
-
* @param end The end index
|
|
184
|
-
* @param value The drift amount
|
|
185
|
-
*/
|
|
186
|
-
/**
|
|
187
|
-
* Multi-threaded drift correction over one or more [start, end, value] ranges.
|
|
188
|
-
* 1. Main thread reads each range's anchors (startDatetime, extent) once and chunks the range.
|
|
189
|
-
* 2. All chunks across all ranges are flattened into jobs and distributed round-robin across a fixed pool of workers.
|
|
190
|
-
* 3. Each worker applies y_n = y_0 + value * ((x_i - startDatetime) / extent) in place on its jobs.
|
|
191
|
-
* 4. Batching all ranges into a single call yields a single history entry.
|
|
192
|
-
*/
|
|
193
|
-
private _driftCorrection;
|
|
194
|
-
/** Traverses the index array and returns groups of consecutive values.
|
|
195
|
-
* i.e.: `[0, 1, 3, 4, 6] => [[0, 1], [3, 4], [6]]`
|
|
196
|
-
* Assumes the input array is sorted.
|
|
197
|
-
* @param index: the index array (sorted)
|
|
198
|
-
*/
|
|
199
|
-
private _getConsecutiveGroups;
|
|
200
|
-
/**
|
|
201
|
-
* Adds data points using worker threads.
|
|
202
|
-
* 1. Main thread sorts insertions by datetime and computes each insertion's target index via binary search on the original X.
|
|
203
|
-
* 2. The original array is split into equal chunks; each insertion is assigned to the chunk containing its target index.
|
|
204
|
-
* 3. `firstIns` per chunk doubles as the prefix sum of insertions placed before the chunk, giving each worker its outStart in the output buffer without overlap.
|
|
205
|
-
* 4. Each worker linearly merges its original slice with its insertion slice (both already sorted by datetime) into the output buffer. Originals win on datetime ties, matching the original `findLastLessOrEqual` semantics.
|
|
206
|
-
*/
|
|
207
|
-
private _addDataPoints;
|
|
208
|
-
/**
|
|
209
|
-
* Filter by applying a set of logical operations
|
|
210
|
-
* @param appliedFilters
|
|
211
|
-
* @returns an array of index values to select in the plot
|
|
212
|
-
*/
|
|
213
|
-
/**
|
|
214
|
-
* Filter by applying a set of logical operations, using worker threads.
|
|
215
|
-
* 1. Main thread encodes filters as numeric opcodes + thresholds (cheaper than string compares in the hot loop).
|
|
216
|
-
* 2. Workers scan disjoint chunks of Y; an index is selected if ANY filter matches (short-circuit).
|
|
217
|
-
* 3. Results from each chunk are concatenated in order to preserve ascending indexes.
|
|
218
|
-
*
|
|
219
|
-
* Opcodes: 0=LT, 1=LTE, 2=GT, 3=GTE, 4=E.
|
|
220
|
-
*/
|
|
221
|
-
private _valueThreshold;
|
|
222
|
-
/**
|
|
223
|
-
*
|
|
224
|
-
* @param comparator
|
|
225
|
-
* @param value
|
|
226
|
-
* @returns
|
|
227
|
-
*/
|
|
228
|
-
/**
|
|
229
|
-
* Find points where the relative rate `(curr - prev) / |prev|` satisfies the comparator, using worker threads.
|
|
230
|
-
* 1. Main thread partitions scan range [1, dataY.length) into chunks; `Y[i-1]` is safely read from the shared buffer across chunk boundaries.
|
|
231
|
-
* 2. Each worker runs a hoisted branch matching the comparator and returns matching indexes in ascending order.
|
|
232
|
-
* 3. Main thread concatenates results in chunk order, preserving ascending order.
|
|
233
|
-
*/
|
|
234
|
-
private _rateOfChange;
|
|
235
|
-
/**
|
|
236
|
-
* Select all points whose datetime falls inside `[from, to]` (inclusive).
|
|
237
|
-
* `dataX` is sorted ascending, so binary search bounds the range in
|
|
238
|
-
* O(log n) — no workers required. Pass `undefined` for either bound to
|
|
239
|
-
* leave that side unconstrained; omitting both selects the full series.
|
|
240
|
-
*/
|
|
241
|
-
private _datetimeRange;
|
|
242
|
-
/**
|
|
243
|
-
* @param index
|
|
244
|
-
* @returns
|
|
245
|
-
*/
|
|
246
|
-
private _selection;
|
|
247
|
-
/**
|
|
248
|
-
*
|
|
249
|
-
* @param comparator
|
|
250
|
-
* @param value
|
|
251
|
-
* @returns
|
|
252
|
-
*/
|
|
253
|
-
/**
|
|
254
|
-
* Find points where the change from the previous value satisfies the comparator, using worker threads.
|
|
255
|
-
* 1. Main thread partitions scan range [1, dataY.length) into chunks (each chunk's first index safely reads Y[i-1] from the shared buffer).
|
|
256
|
-
* 2. Each worker runs a hoisted branch matching the comparator and returns matching indexes in ascending order.
|
|
257
|
-
* 3. Main thread concatenates results in chunk order, preserving ascending order.
|
|
258
|
-
*/
|
|
259
|
-
private _change;
|
|
260
|
-
/**
|
|
261
|
-
* Find gaps in the data using worker threads.
|
|
262
|
-
* 1. Main thread slices the scan range [start, end] into equal chunks with a 1-index overlap so adjacent workers observe the boundary delta correctly.
|
|
263
|
-
* 2. Each worker scans its chunk and returns a flat list of [leftIdx, rightIdx] pairs for gaps whose delta exceeds the threshold.
|
|
264
|
-
* 3. Main thread collects all pairs and dedups via Set — identical return shape to the original implementation.
|
|
265
|
-
* @param value The time value
|
|
266
|
-
* @param unit The time unit (TimeUnit)
|
|
267
|
-
* @param range If specified, the gaps will be found only within the range
|
|
268
|
-
*/
|
|
269
|
-
private _findGaps;
|
|
270
|
-
/**
|
|
271
|
-
* Find points where the values are the same at least `times` in a row, using worker threads.
|
|
272
|
-
* 1. Main thread splits [start, end) into chunks and each worker emits its maximal runs of equal Y values as flat (startIndex, length, value) triplets.
|
|
273
|
-
* 2. Main thread stitches runs that cross chunk boundaries (same value, adjacent indexes).
|
|
274
|
-
* 3. Every run whose stitched length is >= `times` contributes all of its indexes to the selection.
|
|
275
|
-
*
|
|
276
|
-
* Matches the Python reference implementation in `edit_service.py::persistence` — every member of a qualifying run is selected (including the run's first index).
|
|
277
|
-
* @param times The minimum run length to qualify
|
|
278
|
-
* @param range If specified, the points will be found only within the range
|
|
279
|
-
*/
|
|
280
|
-
private _persistence;
|
|
281
|
-
}
|