@signalk/tracks-plugin 3.2.0 → 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.
@@ -132,6 +132,15 @@ export declare class SqliteTrackStore implements TrackStore {
132
132
  * same id fails rather than replacing the first.
133
133
  */
134
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[];
135
144
  /**
136
145
  * Move a vessel's positions recorded within `[from, to]` into the recycle
137
146
  * bin, resolving to the entry's id and whether the store held the vessel at
package/dist/store.d.ts CHANGED
@@ -113,6 +113,11 @@ export interface TrackStore {
113
113
  id?: number;
114
114
  known: boolean;
115
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[]>;
116
121
  binImport?(importId: string, span: {
117
122
  from?: number;
118
123
  to?: number;
@@ -59,6 +59,8 @@ export interface TrackProperties {
59
59
  contextName?: string;
60
60
  /** The track's own name, as an imported GPX `<trk><name>` carries. */
61
61
  name?: string;
62
+ /** Set on a track a client stored, absent on a recorded one. */
63
+ imported?: true;
62
64
  /** Absent, with `to`, for a track whose points carry no times. */
63
65
  from?: string;
64
66
  to?: string;
@@ -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
  *
@@ -56,3 +56,20 @@ export interface TrackProviderDeps {
56
56
  reconcileWithHistory: (context: string, stored: TimedPosition[], window: TimeWindow | undefined, resolutionMs: number | undefined) => Promise<TimedPosition[]>;
57
57
  }
58
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' | 'storeImport' | 'getImport' | 'findImports' | 'binRecorded' | 'binImport' | 'restoreFromBin' | 'purgeFromBin' | 'binEntries' | 'deletedSpans' | '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;
@@ -11712,6 +11712,26 @@ var SqliteTrackStore = class {
11712
11712
  for (const [segment, segmentPoints] of track.segments.entries()) for (const { position, timestamp } of segmentPoints) insert.run(track.id, seq++, segment, timestamp ?? null, position[0], position[1]);
11713
11713
  }
11714
11714
  /**
11715
+ * Write a track imported for a vessel into its recording, in place of what
11716
+ * was recorded over the same time. The positions within each segment's
11717
+ * span go to the recycle bin first, one entry per segment, so a restore
11718
+ * brings them back beside the import. Every span is binned before any point
11719
+ * is written, so segments that overlap in time cannot bin each other.
11720
+ * Resolves to the bin entries made.
11721
+ */
11722
+ recordTrack(context, segments, deletedAt, keepEmpty) {
11723
+ const binned = [];
11724
+ for (const points of segments) {
11725
+ const first = points[0];
11726
+ const last = points.at(-1);
11727
+ if (first === void 0 || last === void 0) continue;
11728
+ const { id } = this.binRecorded(context, first.timestamp, last.timestamp, deletedAt, keepEmpty);
11729
+ if (id !== void 0) binned.push(id);
11730
+ }
11731
+ for (const points of segments) for (const { position, timestamp } of points) this.store(context, position, timestamp);
11732
+ return binned;
11733
+ }
11734
+ /**
11715
11735
  * Move a vessel's positions recorded within `[from, to]` into the recycle
11716
11736
  * bin, resolving to the entry's id and whether the store held the vessel at
11717
11737
  * all.
@@ -11999,6 +12019,7 @@ function mutate(operation, target) {
11999
12019
  var ACKNOWLEDGED = /* @__PURE__ */ new Set([
12000
12020
  "storeImport",
12001
12021
  "binRecorded",
12022
+ "recordTrack",
12002
12023
  "binImport",
12003
12024
  "restoreFromBin",
12004
12025
  "purgeFromBin"
@@ -12007,6 +12028,7 @@ function acknowledge(operation, target) {
12007
12028
  switch (operation.method) {
12008
12029
  case "storeImport": return target.storeImport(...operation.args);
12009
12030
  case "binRecorded": return target.binRecorded(...operation.args);
12031
+ case "recordTrack": return target.recordTrack(...operation.args);
12010
12032
  case "binImport": return target.binImport(...operation.args);
12011
12033
  case "restoreFromBin": return target.restoreFromBin(...operation.args);
12012
12034
  case "purgeFromBin": return target.purgeFromBin(...operation.args);