@signalk/tracks-plugin 3.1.1 → 3.3.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/README.md +72 -0
- package/dist/asyncTrackStore.d.ts +26 -2
- package/dist/bin.js +285 -0
- package/dist/e2e.test-utils.d.ts +16 -2
- package/dist/gpx.d.ts +11 -2
- package/dist/gpxExport.test.d.ts +1 -0
- package/dist/gpxImport.test.d.ts +1 -0
- package/dist/import.js +98 -0
- package/dist/importedTracks.d.ts +52 -0
- package/dist/importedTracks.test.d.ts +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.html +52 -0
- package/dist/index.js +759 -71
- package/dist/index.js.map +1 -1
- package/dist/recycleBin.d.ts +20 -0
- package/dist/recycleBin.test.d.ts +1 -0
- package/dist/recycleBinApi.test.d.ts +1 -0
- package/dist/sqliteStore.d.ts +67 -1
- package/dist/store.d.ts +43 -1
- package/dist/style.css +78 -0
- package/dist/trackApi.d.ts +63 -5
- package/dist/trackProvider.d.ts +22 -1
- package/dist/trackStoreProtocol.d.ts +1 -1
- package/dist/trackStoreWorker.js +393 -1
- package/dist/trackStoreWorker.js.map +1 -1
- package/dist/tracks.js +132 -13
- package/dist/types.d.ts +74 -0
- package/dist/upload.d.ts +19 -0
- package/dist/{utils-CGIGp4Xf.js → utils-C0VkiidM.js} +32 -2
- package/dist/{utils-CGIGp4Xf.js.map → utils-C0VkiidM.js.map} +1 -1
- package/dist/utils.d.ts +14 -0
- package/docs/history-and-storage.md +19 -0
- package/package.json +1 -1
- package/public/bin.js +285 -0
- package/public/import.js +98 -0
- package/public/index.html +52 -0
- package/public/style.css +78 -0
- package/public/tracks.js +132 -13
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DeletedSpan, TimedPosition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Prefix of a recorded track's id. The rest is the vessel's context: a vessel
|
|
4
|
+
* has one recording, so its context is all an id needs, and a provider may
|
|
5
|
+
* derive the id from it, as the server's Track API foresees.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RECORDED_PREFIX = "recorded:";
|
|
8
|
+
export declare const recordedId: (context: string) => string;
|
|
9
|
+
/** The context a recorded track's id names, or undefined for any other id. */
|
|
10
|
+
export declare const recordedContext: (id: string) => string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The points outside every deleted span.
|
|
13
|
+
*
|
|
14
|
+
* Applied to what a history provider returns, which this plugin cannot delete
|
|
15
|
+
* from: without it the next query would fill a deleted span back in. A
|
|
16
|
+
* history point stands for a bucket starting at its timestamp, and the fix it
|
|
17
|
+
* carries can lie anywhere in that bucket, so a bucket that overlaps a span at
|
|
18
|
+
* all is dropped; the store's own points answer for the rest of it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function outsideSpans(points: TimedPosition[], spans: readonly DeletedSpan[]): TimedPosition[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/sqliteStore.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TrackQuery } from './timeWindow.js';
|
|
2
2
|
import { TrackStore } from './store.js';
|
|
3
|
-
import { Context, Debug, LatLngTuple, TimedPosition, TimedTrackCollection, TimeWindow, TrackCollection, TrackParams } from './types.js';
|
|
3
|
+
import { BinEntry, Context, Debug, ImportedTrack, ImportFilter, LatLngTuple, RecordedSpan, RestoreResult, TimedPosition, TimedTrackCollection, TimeWindow, TrackCollection, TrackParams } from './types.js';
|
|
4
4
|
export declare class TransactionStateError extends Error {
|
|
5
5
|
}
|
|
6
6
|
export interface SqliteStoreConfig {
|
|
@@ -17,6 +17,8 @@ export interface SqliteStoreConfig {
|
|
|
17
17
|
resolution?: number;
|
|
18
18
|
/** Drop positions older than this many ms. 0 keeps everything. */
|
|
19
19
|
retention?: number;
|
|
20
|
+
/** Purge a recycle bin entry this many ms after its delete. 0 never purges. */
|
|
21
|
+
binRetention?: number;
|
|
20
22
|
/** Cells per bounding box covering. */
|
|
21
23
|
maxCells?: number;
|
|
22
24
|
/** A gap longer than this ms starts a new track segment. */
|
|
@@ -38,9 +40,11 @@ export declare class SqliteTrackStore implements TrackStore {
|
|
|
38
40
|
private readonly insert;
|
|
39
41
|
private readonly insertName;
|
|
40
42
|
private readonly selectName;
|
|
43
|
+
private readonly selectImportedPoints;
|
|
41
44
|
private readonly maxCells;
|
|
42
45
|
private readonly segmentGap;
|
|
43
46
|
private readonly retention;
|
|
47
|
+
private readonly binRetention;
|
|
44
48
|
private readonly resolution;
|
|
45
49
|
/** See CLIP_STRETCH_GAP; widened so a coarse write resolution does not split every fix. */
|
|
46
50
|
private readonly stretchGap;
|
|
@@ -123,6 +127,68 @@ export declare class SqliteTrackStore implements TrackStore {
|
|
|
123
127
|
recordName(context: Context, name: string, timestamp?: number): void;
|
|
124
128
|
nameFor(context: Context): string | undefined;
|
|
125
129
|
prune(maxAge: number, keep?: Context, now?: number): void;
|
|
130
|
+
/**
|
|
131
|
+
* Keep an imported track. The caller mints the id; a second track under the
|
|
132
|
+
* same id fails rather than replacing the first.
|
|
133
|
+
*/
|
|
134
|
+
storeImport(track: ImportedTrack): void;
|
|
135
|
+
/**
|
|
136
|
+
* Write a track imported for a vessel into its recording, in place of what
|
|
137
|
+
* was recorded over the same time. The positions within each segment's
|
|
138
|
+
* span go to the recycle bin first, one entry per segment, so a restore
|
|
139
|
+
* brings them back beside the import. Every span is binned before any point
|
|
140
|
+
* is written, so segments that overlap in time cannot bin each other.
|
|
141
|
+
* Resolves to the bin entries made.
|
|
142
|
+
*/
|
|
143
|
+
recordTrack(context: Context, segments: TimedPosition[][], deletedAt: number, keepEmpty: boolean): number[];
|
|
144
|
+
/**
|
|
145
|
+
* Move a vessel's positions recorded within `[from, to]` into the recycle
|
|
146
|
+
* bin, resolving to the entry's id and whether the store held the vessel at
|
|
147
|
+
* all.
|
|
148
|
+
*
|
|
149
|
+
* An entry is made even when the store holds nothing there if `keepEmpty`
|
|
150
|
+
* says another source does: the span still has to hide what a history
|
|
151
|
+
* provider holds. Without one, an empty delete leaves no entry behind.
|
|
152
|
+
*/
|
|
153
|
+
binRecorded(context: Context, from: number | undefined, to: number, deletedAt: number, keepEmpty: boolean): {
|
|
154
|
+
id?: number;
|
|
155
|
+
known: boolean;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Move an imported track into the recycle bin, or with a span only its
|
|
159
|
+
* points within it, resolving to the entry's id; undefined when there is no
|
|
160
|
+
* such import, or the span holds none of its points.
|
|
161
|
+
*/
|
|
162
|
+
binImport(importId: string, span: {
|
|
163
|
+
from?: number;
|
|
164
|
+
to?: number;
|
|
165
|
+
} | undefined, deletedAt: number): number | undefined;
|
|
166
|
+
private newBinEntry;
|
|
167
|
+
/**
|
|
168
|
+
* Put a recycle bin entry's rows back where they were deleted from.
|
|
169
|
+
*
|
|
170
|
+
* A span of an import whose whole track has since gone to the bin as well
|
|
171
|
+
* is a conflict: its points have no track to return to until that is
|
|
172
|
+
* restored first.
|
|
173
|
+
*/
|
|
174
|
+
restoreFromBin(id: number): RestoreResult;
|
|
175
|
+
/** Purge one recycle bin entry now, resolving whether it was in the bin. */
|
|
176
|
+
purgeFromBin(id: number): boolean;
|
|
177
|
+
/** Entries still in the recycle bin, newest delete first. */
|
|
178
|
+
binEntries(): BinEntry[];
|
|
179
|
+
/** Every deleted span of a recorded track, purged or not: what history must not show. */
|
|
180
|
+
deletedSpans(): RecordedSpan[];
|
|
181
|
+
private liveEntry;
|
|
182
|
+
/**
|
|
183
|
+
* Remove an entry's rows for good. A recorded span stays as a tombstone, so
|
|
184
|
+
* history cannot refill it; a whole import takes the spans deleted from it
|
|
185
|
+
* earlier with it, since they have no track left to be restored into.
|
|
186
|
+
*/
|
|
187
|
+
private purge;
|
|
188
|
+
getImport(id: string): ImportedTrack | undefined;
|
|
189
|
+
/** Imported tracks the filter lets through, in the order they were stored. */
|
|
190
|
+
findImports(filter?: ImportFilter): ImportedTrack[];
|
|
191
|
+
private importFrom;
|
|
126
192
|
/** Worker startup snapshot; queries and name lookups must not open a second database. */
|
|
127
193
|
storedNames(): {
|
|
128
194
|
context: string;
|
package/dist/store.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Context, Debug, LatLngTuple, TimedPosition, TimedTrackCollection, TimeWindow, TrackCollection, TrackParams } from './types.js';
|
|
1
|
+
import { BinEntry, Context, Debug, ImportedTrack, ImportFilter, LatLngTuple, RecordedSpan, RestoreResult, TimedPosition, TimedTrackCollection, TimeWindow, TrackCollection, TrackParams } from './types.js';
|
|
2
2
|
import { TrackQuery } from './timeWindow.js';
|
|
3
3
|
/**
|
|
4
4
|
* A track store: somewhere positions are accumulated and queried back.
|
|
@@ -86,6 +86,48 @@ export interface TrackStore {
|
|
|
86
86
|
* keeps it out of a real configuration.
|
|
87
87
|
*/
|
|
88
88
|
prune(maxAge: number, keep?: Context): void;
|
|
89
|
+
/**
|
|
90
|
+
* Keep a track a client imported. Optional: a store that only records what
|
|
91
|
+
* it observes leaves the four import methods out, and the Track API then
|
|
92
|
+
* answers that storing tracks is not supported.
|
|
93
|
+
*
|
|
94
|
+
* Resolves once the track is durably stored, unlike the recording writes
|
|
95
|
+
* above: the caller hands its id to a client, which must be able to read it
|
|
96
|
+
* back at once.
|
|
97
|
+
*/
|
|
98
|
+
storeImport?(track: ImportedTrack): void | Promise<void>;
|
|
99
|
+
getImport?(id: string): ImportedTrack | undefined | Promise<ImportedTrack | undefined>;
|
|
100
|
+
findImports?(filter?: ImportFilter): ImportedTrack[] | Promise<ImportedTrack[]>;
|
|
101
|
+
/**
|
|
102
|
+
* The recycle bin. Optional like the import methods: a store without it
|
|
103
|
+
* cannot delete. A delete moves rows into the bin rather than removing them,
|
|
104
|
+
* and each of these resolves once committed, like `storeImport`.
|
|
105
|
+
*
|
|
106
|
+
* `binRecorded` moves a vessel's positions recorded within `[from, to]`;
|
|
107
|
+
* `binImport` moves an imported track, or only its points within a span.
|
|
108
|
+
*/
|
|
109
|
+
binRecorded?(context: Context, from: number | undefined, to: number, deletedAt: number, keepEmpty: boolean): {
|
|
110
|
+
id?: number;
|
|
111
|
+
known: boolean;
|
|
112
|
+
} | Promise<{
|
|
113
|
+
id?: number;
|
|
114
|
+
known: boolean;
|
|
115
|
+
}>;
|
|
116
|
+
/**
|
|
117
|
+
* Write a track imported for a vessel into its recording, binning what was
|
|
118
|
+
* recorded over the same time; resolves to the bin entries made.
|
|
119
|
+
*/
|
|
120
|
+
recordTrack?(context: Context, segments: TimedPosition[][], deletedAt: number, keepEmpty: boolean): number[] | Promise<number[]>;
|
|
121
|
+
binImport?(importId: string, span: {
|
|
122
|
+
from?: number;
|
|
123
|
+
to?: number;
|
|
124
|
+
} | undefined, deletedAt: number): number | undefined | Promise<number | undefined>;
|
|
125
|
+
restoreFromBin?(id: number): RestoreResult | Promise<RestoreResult>;
|
|
126
|
+
/** Purge an entry now, resolving whether it was in the bin. */
|
|
127
|
+
purgeFromBin?(id: number): boolean | Promise<boolean>;
|
|
128
|
+
binEntries?(): BinEntry[] | Promise<BinEntry[]>;
|
|
129
|
+
/** Every deleted span of a recorded track, purged or not: what history must not show. */
|
|
130
|
+
deletedSpans?(): RecordedSpan[] | Promise<RecordedSpan[]>;
|
|
89
131
|
/**
|
|
90
132
|
* Release any resources held by the store.
|
|
91
133
|
*
|
package/dist/style.css
CHANGED
|
@@ -47,3 +47,81 @@ tbody tr:hover {
|
|
|
47
47
|
.self {
|
|
48
48
|
font-weight: 600;
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
.sr-only {
|
|
52
|
+
position: absolute;
|
|
53
|
+
width: 1px;
|
|
54
|
+
height: 1px;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
clip-path: inset(50%);
|
|
57
|
+
white-space: nowrap;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
h2 {
|
|
61
|
+
font-size: 1.1rem;
|
|
62
|
+
margin: 2rem 0 0.25rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#import-form {
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-wrap: wrap;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: 0.5rem 1rem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#bin-status,
|
|
73
|
+
#import-status {
|
|
74
|
+
color: GrayText;
|
|
75
|
+
margin: 0 0 1rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.error,
|
|
79
|
+
#bin-status[data-state='error'],
|
|
80
|
+
#import-status[data-state='error'] {
|
|
81
|
+
color: crimson;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.imported {
|
|
85
|
+
color: GrayText;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.actions {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-wrap: wrap;
|
|
91
|
+
gap: 0.5rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.danger {
|
|
95
|
+
color: crimson;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
dialog {
|
|
99
|
+
max-width: min(32rem, calc(100vw - 2rem));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
dialog h2 {
|
|
103
|
+
margin-top: 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
dialog fieldset {
|
|
107
|
+
display: grid;
|
|
108
|
+
gap: 0.5rem;
|
|
109
|
+
border: none;
|
|
110
|
+
padding: 0;
|
|
111
|
+
margin: 0 0 1rem;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
dialog .span {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-wrap: wrap;
|
|
117
|
+
gap: 0.5rem 1rem;
|
|
118
|
+
margin-left: 1.5rem;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
dialog menu {
|
|
122
|
+
display: flex;
|
|
123
|
+
justify-content: flex-end;
|
|
124
|
+
gap: 0.5rem;
|
|
125
|
+
padding: 0;
|
|
126
|
+
margin: 0;
|
|
127
|
+
}
|
package/dist/trackApi.d.ts
CHANGED
|
@@ -8,7 +8,10 @@ import { Temporal } from '@js-temporal/polyfill';
|
|
|
8
8
|
* imports when it is.
|
|
9
9
|
*
|
|
10
10
|
* Specified in https://github.com/SignalK/signalk-server/issues/2504 and
|
|
11
|
-
* implemented in https://github.com/SignalK/signalk-server/pull/2995
|
|
11
|
+
* implemented in https://github.com/SignalK/signalk-server/pull/2995; storing,
|
|
12
|
+
* fetching and deleting a track by id in
|
|
13
|
+
* https://github.com/SignalK/signalk-server/pull/3038, and deleting part of
|
|
14
|
+
* one in the server's `deleteTrackSpan`.
|
|
12
15
|
*/
|
|
13
16
|
/** `[west, south, east, north]` — GeoJSON coordinate order. */
|
|
14
17
|
export type TrackBoundingBox = [number, number, number, number];
|
|
@@ -47,11 +50,20 @@ export interface TracksRequest {
|
|
|
47
50
|
geometry?: boolean;
|
|
48
51
|
}
|
|
49
52
|
export interface TrackProperties {
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
/** Identifies a stored track within this provider; recorded tracks carry none. */
|
|
54
|
+
id?: string;
|
|
55
|
+
/** Absent for an imported track that names no vessel. */
|
|
56
|
+
context?: string;
|
|
57
|
+
/** Absent along with `context`. */
|
|
58
|
+
isSelf?: boolean;
|
|
52
59
|
contextName?: string;
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
/** The track's own name, as an imported GPX `<trk><name>` carries. */
|
|
61
|
+
name?: string;
|
|
62
|
+
/** Set on a track a client stored, absent on a recorded one. */
|
|
63
|
+
imported?: true;
|
|
64
|
+
/** Absent, with `to`, for a track whose points carry no times. */
|
|
65
|
+
from?: string;
|
|
66
|
+
to?: string;
|
|
55
67
|
bbox?: TrackBoundingBox;
|
|
56
68
|
pointCount: number;
|
|
57
69
|
resolution?: string;
|
|
@@ -59,6 +71,8 @@ export interface TrackProperties {
|
|
|
59
71
|
coordTimes?: string[][];
|
|
60
72
|
appliedProperties?: string[];
|
|
61
73
|
values?: Record<string, (number | string | null)[][]>;
|
|
74
|
+
/** Whatever else an imported track was posted with, returned as posted. */
|
|
75
|
+
[key: string]: unknown;
|
|
62
76
|
}
|
|
63
77
|
export interface TrackFeature {
|
|
64
78
|
type: 'Feature';
|
|
@@ -76,6 +90,50 @@ export interface TracksResponse {
|
|
|
76
90
|
export interface TrackApi {
|
|
77
91
|
getTracks(query: TracksRequest): Promise<TracksResponse>;
|
|
78
92
|
getTrackContexts(query: TracksRequest): Promise<string[]>;
|
|
93
|
+
/** One stored track by id, or undefined when there is none. */
|
|
94
|
+
getTrack?(id: string): Promise<TrackFeature | undefined>;
|
|
95
|
+
/** Keep a track a client supplied, resolving to the id it was given. */
|
|
96
|
+
storeTrack?(track: TrackImport): Promise<string>;
|
|
97
|
+
/** Delete a stored track by id, resolving false when there is none. */
|
|
98
|
+
deleteTrack?(id: string): Promise<boolean>;
|
|
99
|
+
/** Delete the part of a stored track recorded within `span`, resolving false when there is no such track. */
|
|
100
|
+
deleteTrackSpan?(id: string, span: TrackSpan): Promise<boolean>;
|
|
101
|
+
}
|
|
102
|
+
/** Every point recorded at or after `from` and at or before `to`; an absent bound is open. */
|
|
103
|
+
export interface TrackSpan {
|
|
104
|
+
from?: Temporal.Instant;
|
|
105
|
+
to?: Temporal.Instant;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A track offered for storage, in the canonical form the server reduces every
|
|
109
|
+
* import to: a MultiLineString, `coordTimes` nested to match it and in UTC, a
|
|
110
|
+
* qualified context, and none of the properties a provider derives itself.
|
|
111
|
+
*/
|
|
112
|
+
export interface TrackImport {
|
|
113
|
+
type: 'Feature';
|
|
114
|
+
geometry: {
|
|
115
|
+
type: 'MultiLineString';
|
|
116
|
+
coordinates: [number, number][][];
|
|
117
|
+
};
|
|
118
|
+
properties: TrackImportProperties;
|
|
119
|
+
}
|
|
120
|
+
export interface TrackImportProperties {
|
|
121
|
+
coordTimes?: string[][];
|
|
122
|
+
name?: string;
|
|
123
|
+
context?: string;
|
|
124
|
+
/** The client's own metadata, stored as posted. */
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Thrown by `storeTrack` when this provider will not keep the track, which
|
|
129
|
+
* the server answers with a 400 rather than a 500.
|
|
130
|
+
*
|
|
131
|
+
* The server recognises it by `isTrackRejected` rather than by class, since
|
|
132
|
+
* this is a copy of its own.
|
|
133
|
+
*/
|
|
134
|
+
export declare class TrackRejectedError extends Error {
|
|
135
|
+
readonly isTrackRejected: true;
|
|
136
|
+
constructor(message?: string);
|
|
79
137
|
}
|
|
80
138
|
/** Present on servers that carry the Track API; absent on older ones. */
|
|
81
139
|
export interface WithTrackApi {
|
package/dist/trackProvider.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TrackStore } from './store.js';
|
|
2
2
|
import { TrackApi } from './trackApi.js';
|
|
3
|
-
import { TimedPosition, TimeWindow } from './types.js';
|
|
3
|
+
import { ImportedTrack, TimedPosition, TimeWindow } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Serves the v2 Track API from this plugin's store.
|
|
6
6
|
*
|
|
@@ -49,6 +49,27 @@ export interface TrackProviderDeps {
|
|
|
49
49
|
* only before this plugin was installed is known to history alone.
|
|
50
50
|
*/
|
|
51
51
|
historyContexts: (window: TimeWindow | undefined) => Promise<ReadonlySet<string>>;
|
|
52
|
+
/** Whether a history provider holds anything at all for a context. */
|
|
53
|
+
historyKnows: (context: string) => Promise<boolean>;
|
|
54
|
+
/** Called after a delete, so whatever hides deleted spans from history reloads them. */
|
|
55
|
+
deleted: () => void;
|
|
52
56
|
reconcileWithHistory: (context: string, stored: TimedPosition[], window: TimeWindow | undefined, resolutionMs: number | undefined) => Promise<TimedPosition[]>;
|
|
53
57
|
}
|
|
54
58
|
export declare function createTrackProvider(deps: TrackProviderDeps): TrackApi;
|
|
59
|
+
export interface KeepTrackDeps {
|
|
60
|
+
store: Required<Pick<TrackStore, 'storeImport' | 'recordTrack'>>;
|
|
61
|
+
selfContext: string;
|
|
62
|
+
historyKnows: (context: string) => Promise<boolean>;
|
|
63
|
+
deleted: () => void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Keep a client's track, resolving to the id that addresses it.
|
|
67
|
+
*
|
|
68
|
+
* A timed track of the own vessel is the vessel's own passage, from before
|
|
69
|
+
* the plugin recorded it or from another plotter, so it is written into the
|
|
70
|
+
* recording in place of what was recorded over the same time and answers
|
|
71
|
+
* as `recorded:<context>`. Everything else is kept as an import: another
|
|
72
|
+
* vessel's track is not this boat's recording, and an untimed one cannot be
|
|
73
|
+
* placed in it.
|
|
74
|
+
*/
|
|
75
|
+
export declare function keepTrack(track: ImportedTrack, deps: KeepTrackDeps): Promise<string>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SqliteTrackStore } from './sqliteStore.js';
|
|
2
|
-
export type StoreMethod = 'newPosition' | 'recordName' | 'initialTrack' | 'prune' | 'get' | 'getTimed' | 'getAllTracks' | 'getFilteredTracks' | 'getFilteredTimedTracks' | 'close';
|
|
2
|
+
export type StoreMethod = 'newPosition' | 'recordName' | 'initialTrack' | 'prune' | 'get' | 'getTimed' | 'getAllTracks' | 'getFilteredTracks' | 'getFilteredTimedTracks' | 'storeImport' | 'getImport' | 'findImports' | 'binRecorded' | 'recordTrack' | 'binImport' | 'restoreFromBin' | 'purgeFromBin' | 'binEntries' | 'deletedSpans' | 'close';
|
|
3
3
|
export type Operation = {
|
|
4
4
|
[K in StoreMethod]: {
|
|
5
5
|
id: number;
|