signalk-questdb 2.0.1 → 2.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.
Files changed (91) hide show
  1. package/.coderabbit.yaml +4 -3
  2. package/README.md +151 -5
  3. package/dist/api-contract.d.ts +62 -0
  4. package/dist/config/schema.d.ts +1 -0
  5. package/dist/config/schema.js +5 -0
  6. package/dist/config/schema.js.map +1 -1
  7. package/dist/configpanel/responses.d.ts +33 -1
  8. package/dist/configpanel/responses.js +89 -0
  9. package/dist/configpanel/responses.js.map +1 -1
  10. package/dist/history-v1.js +12 -9
  11. package/dist/history-v1.js.map +1 -1
  12. package/dist/history-v2.d.ts +18 -6
  13. package/dist/history-v2.js +275 -41
  14. package/dist/history-v2.js.map +1 -1
  15. package/dist/ilp-writer.d.ts +22 -0
  16. package/dist/ilp-writer.js +76 -4
  17. package/dist/ilp-writer.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +326 -58
  20. package/dist/index.js.map +1 -1
  21. package/dist/influx-detect.d.ts +19 -0
  22. package/dist/influx-detect.js +165 -0
  23. package/dist/influx-detect.js.map +1 -0
  24. package/dist/migration.d.ts +147 -0
  25. package/dist/migration.js +819 -0
  26. package/dist/migration.js.map +1 -0
  27. package/dist/query-client.d.ts +9 -0
  28. package/dist/query-client.js +11 -0
  29. package/dist/query-client.js.map +1 -1
  30. package/dist/restore.js +9 -0
  31. package/dist/restore.js.map +1 -1
  32. package/dist/schema-errors.d.ts +15 -0
  33. package/dist/schema-errors.js +38 -0
  34. package/dist/schema-errors.js.map +1 -0
  35. package/package.json +5 -4
  36. package/public/assets/PluginConfigurationPanel-CR4mD9IH.js +9 -0
  37. package/public/assets/{index-Z7eUk0W6.js → index-CyI4zKUm.js} +1 -1
  38. package/public/assets/{virtualExposes-CyrNon4j.js → virtualExposes-BBIkbTtD.js} +1 -1
  39. package/public/remoteEntry.js +1 -1
  40. package/dist/test/config.test.d.ts +0 -1
  41. package/dist/test/config.test.js +0 -161
  42. package/dist/test/config.test.js.map +0 -1
  43. package/dist/test/configpanel-responses.test.d.ts +0 -1
  44. package/dist/test/configpanel-responses.test.js +0 -108
  45. package/dist/test/configpanel-responses.test.js.map +0 -1
  46. package/dist/test/console-proxy.test.d.ts +0 -1
  47. package/dist/test/console-proxy.test.js +0 -664
  48. package/dist/test/console-proxy.test.js.map +0 -1
  49. package/dist/test/container-env.test.d.ts +0 -1
  50. package/dist/test/container-env.test.js +0 -70
  51. package/dist/test/container-env.test.js.map +0 -1
  52. package/dist/test/delta-routing.test.d.ts +0 -1
  53. package/dist/test/delta-routing.test.js +0 -258
  54. package/dist/test/delta-routing.test.js.map +0 -1
  55. package/dist/test/full-export-range.test.d.ts +0 -1
  56. package/dist/test/full-export-range.test.js +0 -78
  57. package/dist/test/full-export-range.test.js.map +0 -1
  58. package/dist/test/history-v1.test.d.ts +0 -1
  59. package/dist/test/history-v1.test.js +0 -676
  60. package/dist/test/history-v1.test.js.map +0 -1
  61. package/dist/test/history-v2.test.d.ts +0 -1
  62. package/dist/test/history-v2.test.js +0 -563
  63. package/dist/test/history-v2.test.js.map +0 -1
  64. package/dist/test/host-limits.test.d.ts +0 -1
  65. package/dist/test/host-limits.test.js +0 -81
  66. package/dist/test/host-limits.test.js.map +0 -1
  67. package/dist/test/ilp-writer.test.d.ts +0 -1
  68. package/dist/test/ilp-writer.test.js +0 -391
  69. package/dist/test/ilp-writer.test.js.map +0 -1
  70. package/dist/test/package-e2e.test.d.ts +0 -1
  71. package/dist/test/package-e2e.test.js +0 -306
  72. package/dist/test/package-e2e.test.js.map +0 -1
  73. package/dist/test/path-matcher.test.d.ts +0 -1
  74. package/dist/test/path-matcher.test.js +0 -224
  75. package/dist/test/path-matcher.test.js.map +0 -1
  76. package/dist/test/query-client.test.d.ts +0 -1
  77. package/dist/test/query-client.test.js +0 -299
  78. package/dist/test/query-client.test.js.map +0 -1
  79. package/dist/test/questdb-endpoint.test.d.ts +0 -1
  80. package/dist/test/questdb-endpoint.test.js +0 -297
  81. package/dist/test/questdb-endpoint.test.js.map +0 -1
  82. package/dist/test/restore.test.d.ts +0 -1
  83. package/dist/test/restore.test.js +0 -496
  84. package/dist/test/restore.test.js.map +0 -1
  85. package/dist/test/time-range.test.d.ts +0 -1
  86. package/dist/test/time-range.test.js +0 -53
  87. package/dist/test/time-range.test.js.map +0 -1
  88. package/dist/test/wal-monitor.test.d.ts +0 -1
  89. package/dist/test/wal-monitor.test.js +0 -405
  90. package/dist/test/wal-monitor.test.js.map +0 -1
  91. 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
+ };