signalk-questdb 2.0.0 → 2.1.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/.coderabbit.yaml +4 -3
- package/README.md +162 -7
- package/dist/api-contract.d.ts +62 -0
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.js +5 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/configpanel/responses.d.ts +33 -1
- package/dist/configpanel/responses.js +89 -0
- package/dist/configpanel/responses.js.map +1 -1
- package/dist/history-v1.js +12 -9
- package/dist/history-v1.js.map +1 -1
- package/dist/history-v2.d.ts +18 -6
- package/dist/history-v2.js +275 -41
- package/dist/history-v2.js.map +1 -1
- package/dist/ilp-writer.d.ts +22 -0
- package/dist/ilp-writer.js +76 -4
- package/dist/ilp-writer.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +326 -70
- package/dist/index.js.map +1 -1
- package/dist/influx-detect.d.ts +19 -0
- package/dist/influx-detect.js +165 -0
- package/dist/influx-detect.js.map +1 -0
- package/dist/migration.d.ts +147 -0
- package/dist/migration.js +824 -0
- package/dist/migration.js.map +1 -0
- package/dist/query-client.d.ts +9 -0
- package/dist/query-client.js +11 -0
- package/dist/query-client.js.map +1 -1
- package/dist/restore.js +9 -0
- package/dist/restore.js.map +1 -1
- package/dist/schema-errors.d.ts +15 -0
- package/dist/schema-errors.js +38 -0
- package/dist/schema-errors.js.map +1 -0
- package/dist/test/configpanel-responses.test.js +90 -1
- package/dist/test/configpanel-responses.test.js.map +1 -1
- package/dist/test/history-v2.test.js +440 -2
- package/dist/test/history-v2.test.js.map +1 -1
- package/dist/test/ilp-writer.test.js +28 -0
- package/dist/test/ilp-writer.test.js.map +1 -1
- package/dist/test/influx-detect.test.d.ts +1 -0
- package/dist/test/influx-detect.test.js +287 -0
- package/dist/test/influx-detect.test.js.map +1 -0
- package/dist/test/migration.test.d.ts +1 -0
- package/dist/test/migration.test.js +851 -0
- package/dist/test/migration.test.js.map +1 -0
- package/dist/test/restore.test.js +47 -0
- package/dist/test/restore.test.js.map +1 -1
- package/package.json +5 -4
- package/public/assets/PluginConfigurationPanel-CR4mD9IH.js +9 -0
- package/public/assets/{index-Z7eUk0W6.js → index-CyI4zKUm.js} +1 -1
- package/public/assets/{virtualExposes-CyrNon4j.js → virtualExposes-BBIkbTtD.js} +1 -1
- package/public/remoteEntry.js +1 -1
- package/public/assets/PluginConfigurationPanel-CyS3A7gD.js +0 -9
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ILPWriter } from "./ilp-writer.js";
|
|
2
|
+
import type { MigrationBucket, MigrationMeasurement, MigrationProgress, MigrationRunState } from "./api-contract.js";
|
|
3
|
+
/**
|
|
4
|
+
* How much time one read covers. Small enough that a dense measurement does
|
|
5
|
+
* not return a result set too large to hold, large enough that a sparse one
|
|
6
|
+
* does not need thousands of round trips. A day is the natural unit for boat
|
|
7
|
+
* data: it bounds a busy passage to a few hundred thousand points.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_WINDOW_MS: number;
|
|
10
|
+
export interface InfluxAuth {
|
|
11
|
+
/** 2.x API token, or 1.x password when `username` is set. */
|
|
12
|
+
token?: string;
|
|
13
|
+
username?: string;
|
|
14
|
+
password?: string;
|
|
15
|
+
/** 2.x organisation, required by the Flux API. */
|
|
16
|
+
org?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface MigrationRequest {
|
|
19
|
+
url: string;
|
|
20
|
+
/** "influxdb1" or "influxdb2" — decides the query dialect. */
|
|
21
|
+
type: string;
|
|
22
|
+
/** Bucket (2.x) or database (1.x). */
|
|
23
|
+
bucket: string;
|
|
24
|
+
auth?: InfluxAuth;
|
|
25
|
+
/** ISO instants bounding the import. */
|
|
26
|
+
from: string;
|
|
27
|
+
to: string;
|
|
28
|
+
/** Signal K context to write rows under. */
|
|
29
|
+
context: string;
|
|
30
|
+
/** Restrict to these measurements; empty/absent means all of them. */
|
|
31
|
+
measurements?: string[];
|
|
32
|
+
/** `source` tag written on every imported row, so it is distinguishable. */
|
|
33
|
+
sourceLabel?: string;
|
|
34
|
+
windowMs?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Buckets (2.x) or databases (1.x) available to import from. */
|
|
37
|
+
export declare function listBuckets(req: {
|
|
38
|
+
url: string;
|
|
39
|
+
type: string;
|
|
40
|
+
auth?: InfluxAuth;
|
|
41
|
+
}, fetchImpl?: typeof fetch): Promise<MigrationBucket[]>;
|
|
42
|
+
/** Measurements in a bucket/database, with the field keys each carries. */
|
|
43
|
+
export declare function listMeasurements(req: {
|
|
44
|
+
url: string;
|
|
45
|
+
type: string;
|
|
46
|
+
bucket: string;
|
|
47
|
+
auth?: InfluxAuth;
|
|
48
|
+
}, fetchImpl?: typeof fetch): Promise<MigrationMeasurement[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Minimal annotated-CSV reader for Flux responses.
|
|
51
|
+
*
|
|
52
|
+
* Flux emits one or more *tables*, each preceded by annotation lines starting
|
|
53
|
+
* with `#` and then a header row. A response can therefore change its column
|
|
54
|
+
* layout partway through, which is why the header is tracked per block rather
|
|
55
|
+
* than read once at the top.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseAnnotatedCsv(text: string): AnnotatedRecord[];
|
|
58
|
+
/** One Flux CSV record plus the `#datatype` of each of its columns. */
|
|
59
|
+
export interface AnnotatedRecord {
|
|
60
|
+
values: Record<string, string>;
|
|
61
|
+
types: Record<string, string>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Parse an RFC3339 instant into nanoseconds since the epoch, preserving digits
|
|
65
|
+
* below the millisecond.
|
|
66
|
+
*
|
|
67
|
+
* `Date.parse` truncates to milliseconds. InfluxDB stores nanoseconds, and the
|
|
68
|
+
* QuestDB tables dedup on (ts, path, context, source) — so two points 200µs
|
|
69
|
+
* apart would collide and one would be lost. The fractional part is therefore
|
|
70
|
+
* read from the string directly.
|
|
71
|
+
*/
|
|
72
|
+
export declare function rfc3339ToNanos(value: string): bigint | null;
|
|
73
|
+
/**
|
|
74
|
+
* The Signal K path a measurement+field pair represents.
|
|
75
|
+
*
|
|
76
|
+
* signalk-to-influxdb writes the path as the measurement name and the value in
|
|
77
|
+
* a field called `value`. Anything else (a measurement with several named
|
|
78
|
+
* fields) is a non-Signal K schema, so the field name is appended to keep the
|
|
79
|
+
* two apart instead of overwriting one with the other.
|
|
80
|
+
*/
|
|
81
|
+
export declare function toSignalKPath(measurement: string, field: string): string;
|
|
82
|
+
/** Coerce an InfluxDB field value (always text over CSV) to a JS value. */
|
|
83
|
+
export declare function coerceValue(raw: string, dataType?: string): unknown;
|
|
84
|
+
export interface MigrationRunHandle {
|
|
85
|
+
id: string;
|
|
86
|
+
state: MigrationRunState;
|
|
87
|
+
url: string;
|
|
88
|
+
bucket: string;
|
|
89
|
+
startedAt: string;
|
|
90
|
+
finishedAt?: string;
|
|
91
|
+
progress: MigrationProgress;
|
|
92
|
+
error?: string;
|
|
93
|
+
cancel(): void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A single import run. Holds its own cancellation flag and counters so the
|
|
97
|
+
* HTTP layer can poll it without the importer knowing about Express.
|
|
98
|
+
*/
|
|
99
|
+
export declare class MigrationRun implements MigrationRunHandle {
|
|
100
|
+
readonly id: string;
|
|
101
|
+
readonly url: string;
|
|
102
|
+
readonly bucket: string;
|
|
103
|
+
state: MigrationRunState;
|
|
104
|
+
startedAt: string;
|
|
105
|
+
finishedAt?: string;
|
|
106
|
+
error?: string;
|
|
107
|
+
progress: MigrationProgress;
|
|
108
|
+
private cancelled;
|
|
109
|
+
constructor(id: string, url: string, bucket: string);
|
|
110
|
+
cancel(): void;
|
|
111
|
+
get isCancelled(): boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Copy history from InfluxDB into QuestDB.
|
|
115
|
+
*
|
|
116
|
+
* Rows are written through the plugin's own ILP writer, so imported history is
|
|
117
|
+
* subject to exactly the same schema, dedup and retention rules as live data —
|
|
118
|
+
* and re-running an import is idempotent, because a row with the same
|
|
119
|
+
* (ts, path, context, source) upserts rather than duplicating.
|
|
120
|
+
*/
|
|
121
|
+
export declare function runMigration(req: MigrationRequest, writer: Pick<ILPWriter, "writeAtNanos" | "writeStringAtNanos" | "writePositionAtNanos" | "pendingLines"> & {
|
|
122
|
+
readonly droppedLineCount?: number;
|
|
123
|
+
}, run: MigrationRun, deps?: {
|
|
124
|
+
fetchImpl?: typeof fetch;
|
|
125
|
+
debug?: (msg: string) => void;
|
|
126
|
+
/** Injected so tests don't wait on real backpressure sleeps. */
|
|
127
|
+
sleep?: (ms: number) => Promise<void>;
|
|
128
|
+
}): Promise<void>;
|
|
129
|
+
/** One point read out of InfluxDB, normalised across the two dialects. */
|
|
130
|
+
export interface SourceRow {
|
|
131
|
+
tsNanos: bigint;
|
|
132
|
+
field: string;
|
|
133
|
+
value: unknown;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Recombine latitude/longitude fields of a position measurement into one
|
|
137
|
+
* object value at the same instant.
|
|
138
|
+
*
|
|
139
|
+
* The Signal K InfluxDB plugins store navigation.position as two fields
|
|
140
|
+
* (`latitude`/`longitude`, or `lat`/`lon`). Left as-is they would import as
|
|
141
|
+
* two numeric paths and the position history would be unusable — QuestDB keeps
|
|
142
|
+
* positions in their own table.
|
|
143
|
+
*/
|
|
144
|
+
export declare function mergePositionRows(measurement: string, rows: SourceRow[]): {
|
|
145
|
+
rows: SourceRow[];
|
|
146
|
+
dropped: number;
|
|
147
|
+
};
|