signalk-wakelogger 0.2.0-beta.2 → 0.2.0-beta.4

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 (50) hide show
  1. package/CHANGELOG.md +52 -38
  2. package/README.md +59 -40
  3. package/dist/config/defaults.d.ts +1 -0
  4. package/dist/config/defaults.js +1 -0
  5. package/dist/config/defaults.js.map +1 -1
  6. package/dist/config/schema.d.ts +8 -0
  7. package/dist/config/schema.js +8 -0
  8. package/dist/config/schema.js.map +1 -1
  9. package/dist/courses/course-store.d.ts +19 -0
  10. package/dist/courses/course-store.js +182 -0
  11. package/dist/courses/course-store.js.map +1 -0
  12. package/dist/courses/native-course.d.ts +41 -0
  13. package/dist/courses/native-course.js +101 -0
  14. package/dist/courses/native-course.js.map +1 -0
  15. package/dist/courses/protocol.d.ts +43 -0
  16. package/dist/courses/protocol.js +60 -0
  17. package/dist/courses/protocol.js.map +1 -0
  18. package/dist/index.js +122 -29
  19. package/dist/index.js.map +1 -1
  20. package/dist/telemetry/types.d.ts +13 -0
  21. package/dist/transport/mqtt-client.d.ts +7 -2
  22. package/dist/transport/mqtt-client.js +26 -7
  23. package/dist/transport/mqtt-client.js.map +1 -1
  24. package/dist/transport/topics.d.ts +2 -0
  25. package/dist/transport/topics.js +2 -1
  26. package/dist/transport/topics.js.map +1 -1
  27. package/dist/trips/recording-store.d.ts +16 -0
  28. package/dist/trips/recording-store.js +127 -0
  29. package/dist/trips/recording-store.js.map +1 -0
  30. package/dist/trips/state-machine.js +3 -3
  31. package/dist/trips/state-machine.js.map +1 -1
  32. package/docs/course-sync.md +63 -0
  33. package/docs/onboard-mapping.md +125 -0
  34. package/docs/trip-detection.md +7 -1
  35. package/package.json +15 -9
  36. package/public/api-client.mjs +44 -0
  37. package/public/app.mjs +219 -0
  38. package/public/chart-sources.mjs +57 -0
  39. package/public/course-progress.mjs +49 -0
  40. package/public/index.html +16 -0
  41. package/public/map-preparation.mjs +60 -0
  42. package/public/style.css +1 -0
  43. package/public/vendor/LEAFLET-LICENSE +26 -0
  44. package/public/vendor/images/layers-2x.png +0 -0
  45. package/public/vendor/images/layers.png +0 -0
  46. package/public/vendor/images/marker-icon-2x.png +0 -0
  47. package/public/vendor/images/marker-icon.png +0 -0
  48. package/public/vendor/images/marker-shadow.png +0 -0
  49. package/public/vendor/leaflet.css +661 -0
  50. package/public/vendor/leaflet.js +6 -0
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NativeCourseService = void 0;
4
+ exports.nativeRouteId = nativeRouteId;
5
+ exports.nativeRouteHref = nativeRouteHref;
6
+ const node_crypto_1 = require("node:crypto");
7
+ const protocol_1 = require("./protocol");
8
+ function nativeRouteId(courseId) {
9
+ const hash = (0, node_crypto_1.createHash)('sha256').update(`signalk-wakelogger:course:${courseId}`).digest('hex');
10
+ return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-4${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
11
+ }
12
+ function nativeRouteHref(courseId) { return `/resources/routes/${nativeRouteId(courseId)}`; }
13
+ class NativeCourseService {
14
+ app;
15
+ constructor(app) {
16
+ this.app = app;
17
+ }
18
+ available() { return [this.app.resourcesApi?.getResource, this.app.resourcesApi?.setResource, this.app.getCourse, this.app.activateRoute, this.app.clearDestination].every((method) => typeof method === 'function'); }
19
+ async current() { return this.app.getCourse ? structuredClone(await this.app.getCourse() ?? null) : null; }
20
+ async matches(course) { return (await this.current())?.activeRoute?.href === nativeRouteHref(course.courseId); }
21
+ async ensureResource(course) {
22
+ this.assertAvailable();
23
+ const id = nativeRouteId(course.courseId);
24
+ const resource = {
25
+ name: course.name, description: `Wake Logger course ${course.courseId}`,
26
+ feature: {
27
+ type: 'Feature', geometry: { type: 'LineString', coordinates: (0, protocol_1.coursePoints)(course).map((point) => [point.longitude, point.latitude]) },
28
+ properties: { wakelogger: { courseId: course.courseId, revision: course.revision }, coordinatesMeta: (0, protocol_1.coursePoints)(course).map((point) => ({ name: point.name, ...(point.notes !== undefined ? { notes: point.notes } : {}) })) }
29
+ }
30
+ };
31
+ const existing = await this.readRoute(id);
32
+ if (existing && !ownedBy(existing, course.courseId))
33
+ throw new protocol_1.CourseError('native_route_conflict');
34
+ if (JSON.stringify(existing) === JSON.stringify(resource))
35
+ return;
36
+ await this.app.resourcesApi.setResource('routes', id, resource);
37
+ // Signal K 2.31's wrapper does not return its provider write promise. Read
38
+ // back the resource before activating, and fail visibly if it never commits.
39
+ for (let attempt = 0; attempt < 20; attempt += 1) {
40
+ const stored = await this.readRoute(id);
41
+ if (stored && ownedBy(stored, course.courseId)
42
+ && JSON.stringify(stored.feature.geometry) === JSON.stringify(resource.feature.geometry)
43
+ && stored.feature.properties.wakelogger.revision === course.revision)
44
+ return;
45
+ await new Promise((resolve) => setTimeout(resolve, 50));
46
+ }
47
+ throw new protocol_1.CourseError('native_route_write_unconfirmed');
48
+ }
49
+ async activate(course, explicit, previousCourse) {
50
+ this.assertAvailable();
51
+ const current = (await this.current())?.activeRoute?.href;
52
+ const target = nativeRouteHref(course.courseId);
53
+ if (!explicit && current && current !== target) {
54
+ if (!previousCourse || current !== nativeRouteHref(previousCourse.courseId))
55
+ return 'conflict';
56
+ const previousResource = await this.readRoute(nativeRouteId(previousCourse.courseId));
57
+ if (!previousResource || !ownedBy(previousResource, previousCourse.courseId))
58
+ return 'conflict';
59
+ }
60
+ // Replayed desired state must not reset an ongoing native course's progress.
61
+ if (current === target && !explicit && previousCourse?.revision === course.revision)
62
+ return 'active';
63
+ const existingIndex = (await this.current())?.activeRoute?.pointIndex;
64
+ const pointIndex = current === target && !explicit && Number.isInteger(existingIndex)
65
+ ? Math.min(existingIndex, (0, protocol_1.coursePoints)(course).length - 1)
66
+ : course.activeWaypointIndex ?? Math.min(1, (0, protocol_1.coursePoints)(course).length - 1);
67
+ await this.app.activateRoute({ href: target, pointIndex, reverse: false });
68
+ if (!await this.matches(course))
69
+ throw new protocol_1.CourseError('native_activation_unconfirmed');
70
+ return 'active';
71
+ }
72
+ async clearOwned(course) {
73
+ this.assertAvailable();
74
+ if (course && await this.matches(course)) {
75
+ const resource = await this.readRoute(nativeRouteId(course.courseId));
76
+ if (resource && ownedBy(resource, course.courseId))
77
+ await this.app.clearDestination();
78
+ }
79
+ }
80
+ async readRoute(id) {
81
+ try {
82
+ return await this.app.resourcesApi.getResource('routes', id);
83
+ }
84
+ catch (error) {
85
+ const failure = error;
86
+ if (/no provider for routes/i.test(failure.message ?? ''))
87
+ throw new protocol_1.CourseError('native_routes_unavailable');
88
+ if (failure.status === 404 || failure.statusCode === 404 || failure.code === 'ENOENT' || /not found/i.test(failure.message ?? ''))
89
+ return undefined;
90
+ throw error;
91
+ }
92
+ }
93
+ assertAvailable() { if (!this.available())
94
+ throw new protocol_1.CourseError('native_course_unavailable'); }
95
+ }
96
+ exports.NativeCourseService = NativeCourseService;
97
+ function ownedBy(value, courseId) {
98
+ const candidate = value;
99
+ return candidate?.feature?.properties?.wakelogger?.courseId === courseId;
100
+ }
101
+ //# sourceMappingURL=native-course.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-course.js","sourceRoot":"","sources":["../../src/courses/native-course.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export interface CoursePoint {
2
+ id: string;
3
+ name: string;
4
+ latitude: number;
5
+ longitude: number;
6
+ notes?: string;
7
+ }
8
+ export interface ActiveCourseDocument {
9
+ v: 1;
10
+ action: 'activate';
11
+ revision: number;
12
+ courseId: string;
13
+ racePlanId?: number;
14
+ name: string;
15
+ updatedAt: string;
16
+ start: CoursePoint;
17
+ marks: CoursePoint[];
18
+ finish: CoursePoint;
19
+ activeWaypointIndex?: number;
20
+ }
21
+ export interface ClearCourseDocument {
22
+ v: 1;
23
+ action: 'clear';
24
+ revision: number;
25
+ courseId: null;
26
+ updatedAt: string;
27
+ }
28
+ export type CourseDocument = ActiveCourseDocument | ClearCourseDocument;
29
+ export type MapReadiness = 'unknown' | 'unavailable' | 'online_only' | 'preparing' | 'offline_ready';
30
+ export interface CourseAcknowledgement {
31
+ mapReadiness?: MapReadiness;
32
+ v: 1;
33
+ revision: number;
34
+ status: 'applied' | 'rejected';
35
+ errorCode?: string;
36
+ activation?: 'active' | 'inactive' | 'conflict';
37
+ }
38
+ export declare class CourseError extends Error {
39
+ readonly code: string;
40
+ constructor(code: string);
41
+ }
42
+ export declare function coursePoints(course: ActiveCourseDocument): CoursePoint[];
43
+ export declare function parseCourse(payload: Buffer): CourseDocument;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CourseError = void 0;
4
+ exports.coursePoints = coursePoints;
5
+ exports.parseCourse = parseCourse;
6
+ class CourseError extends Error {
7
+ code;
8
+ constructor(code) {
9
+ super(code);
10
+ this.code = code;
11
+ }
12
+ }
13
+ exports.CourseError = CourseError;
14
+ function coursePoints(course) { return [course.start, ...course.marks, course.finish]; }
15
+ function parseCourse(payload) {
16
+ if (payload.length > 64 * 1024)
17
+ throw new CourseError('course_too_large');
18
+ let value;
19
+ try {
20
+ value = JSON.parse(payload.toString('utf8'));
21
+ }
22
+ catch {
23
+ throw new CourseError('course_invalid_json');
24
+ }
25
+ const doc = value;
26
+ if (!doc || doc.v !== 1 || !Number.isSafeInteger(doc.revision) || (doc.revision ?? 0) < 1
27
+ || typeof doc.updatedAt !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|[+-]\d{2}:\d{2})$/.test(doc.updatedAt) || !Number.isFinite(Date.parse(doc.updatedAt)))
28
+ throw new CourseError('course_invalid');
29
+ if (doc.action === 'clear') {
30
+ if (doc.courseId !== null)
31
+ throw new CourseError('course_invalid');
32
+ return { v: 1, action: 'clear', revision: doc.revision, courseId: null, updatedAt: doc.updatedAt };
33
+ }
34
+ if (doc.action !== 'activate' || !validText(doc.courseId, 120) || !validText(doc.name, 255)
35
+ || !Array.isArray(doc.marks) || doc.marks.length > 198 || !validPoint(doc.start) || !validPoint(doc.finish)
36
+ || !doc.marks.every(validPoint))
37
+ throw new CourseError('course_invalid');
38
+ const points = [doc.start, ...doc.marks, doc.finish];
39
+ if (new Set(points.map((point) => point.id)).size !== points.length)
40
+ throw new CourseError('course_duplicate_point_id');
41
+ if (doc.activeWaypointIndex !== undefined && (!Number.isSafeInteger(doc.activeWaypointIndex)
42
+ || doc.activeWaypointIndex < 0 || doc.activeWaypointIndex >= points.length))
43
+ throw new CourseError('course_invalid_point_index');
44
+ return {
45
+ v: 1, action: 'activate', revision: doc.revision, courseId: doc.courseId, name: doc.name, updatedAt: doc.updatedAt,
46
+ start: point(doc.start), marks: doc.marks.map(point), finish: point(doc.finish),
47
+ ...(Number.isSafeInteger(doc.racePlanId) ? { racePlanId: doc.racePlanId } : {}),
48
+ ...(doc.activeWaypointIndex !== undefined ? { activeWaypointIndex: doc.activeWaypointIndex } : {})
49
+ };
50
+ }
51
+ function point(value) { return { id: value.id, name: value.name, latitude: value.latitude, longitude: value.longitude, ...(value.notes !== undefined ? { notes: value.notes } : {}) }; }
52
+ function validText(value, maximum) { return typeof value === 'string' && value.trim().length > 0 && value.length <= maximum; }
53
+ function validPoint(value) {
54
+ const candidate = value;
55
+ return !!candidate && validText(candidate.id, 120) && validText(candidate.name, 255)
56
+ && (candidate.notes === undefined || (typeof candidate.notes === 'string' && candidate.notes.length <= 1000))
57
+ && Number.isFinite(candidate.latitude) && Math.abs(candidate.latitude) <= 90
58
+ && Number.isFinite(candidate.longitude) && Math.abs(candidate.longitude) <= 180;
59
+ }
60
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/courses/protocol.ts"],"names":[],"mappings":";;;AA4BA,oCAAmI;AACnI,kCAwBC;AA5BD,MAAa,WAAY,SAAQ,KAAK;IACf;IAArB,YAAqB,IAAY;QAAI,KAAK,CAAC,IAAI,CAAC,CAAA;QAA3B,SAAI,GAAJ,IAAI,CAAQ;IAAgB,CAAC;CACnD;AAFD,kCAEC;AACD,SAAgB,YAAY,CAAC,MAA4B,IAAmB,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC;AACnI,SAAgB,WAAW,CAAC,OAAe;IACzC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI;QAAE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC,CAAA;IACzE,IAAI,KAAc,CAAA;IAClB,IAAI,CAAC;QAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAA;IAAC,CAAC;IAC3G,MAAM,GAAG,GAAG,KAAkD,CAAA;IAC9D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;WACpF,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,0EAA0E,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAA;IACjO,IAAK,GAA2B,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QACpD,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAA;QAClE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAA;IACrG,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;WACtF,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;WACxG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAA;IAC1E,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACpD,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAA;IACvH,IAAI,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC;WACvF,GAAG,CAAC,mBAAmB,GAAG,CAAC,IAAI,GAAG,CAAC,mBAAmB,IAAI,MAAM,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,4BAA4B,CAAC,CAAA;IAClI,OAAO;QACL,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAK,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS;QACrH,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,MAAO,CAAC;QACjF,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,GAAG,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnG,CAAA;AACH,CAAC;AACD,SAAS,KAAK,CAAC,KAAkB,IAAiB,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA,CAAC,CAAC;AACjN,SAAS,SAAS,CAAC,KAAc,EAAE,OAAe,IAAqB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAA,CAAC,CAAC;AAC/J,SAAS,UAAU,CAAC,KAAc;IAChC,MAAM,SAAS,GAAG,KAAgC,CAAA;IAClD,OAAO,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC;WAC/E,CAAC,SAAS,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;WAC1G,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE;WACzE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,CAAA;AACnF,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  const node_fs_1 = require("node:fs");
6
6
  const node_path_1 = __importDefault(require("node:path"));
7
+ const course_store_1 = require("./courses/course-store");
8
+ const protocol_1 = require("./courses/protocol");
9
+ const native_course_1 = require("./courses/native-course");
7
10
  const schema_1 = require("./config/schema");
8
11
  const defaults_1 = require("./config/defaults");
9
12
  const factory_1 = require("./outbox/factory");
@@ -16,7 +19,7 @@ const profile_1 = require("./telemetry/profile");
16
19
  const profile_store_1 = require("./telemetry/profile-store");
17
20
  const sampler_1 = require("./telemetry/sampler");
18
21
  const mqtt_client_1 = require("./transport/mqtt-client");
19
- const state_machine_1 = require("./trips/state-machine");
22
+ const recording_store_1 = require("./trips/recording-store");
20
23
  const constructor = (app) => {
21
24
  const pluginVersion = '0.2.0-beta.2';
22
25
  let generation = 0;
@@ -25,7 +28,12 @@ const constructor = (app) => {
25
28
  let statusTimer;
26
29
  let outbox;
27
30
  let transport;
31
+ let courses;
32
+ let courseInitializationError;
33
+ let courseFailureAcknowledgement;
28
34
  let tripState;
35
+ let activeUploadMode = 'automatic';
36
+ let sampleOperation = Promise.resolve();
29
37
  let connectionState = 'unpaired';
30
38
  let activeProfile;
31
39
  let storageBackend = 'file';
@@ -39,9 +47,14 @@ const constructor = (app) => {
39
47
  description: 'Live vessel tracking and resilient Signal K telemetry for Wake Logger',
40
48
  schema: schema_1.configSchema,
41
49
  start(configuration) {
50
+ pairingAbortController?.abort();
51
+ associationAbortController?.abort();
52
+ // Stop all transmission immediately when a saved configuration restarts us.
53
+ const stopping = transport?.stop(false);
42
54
  const previous = initialization;
43
55
  const thisGeneration = ++generation;
44
56
  initialization = (async () => {
57
+ await stopping;
45
58
  await previous?.catch(() => undefined);
46
59
  await cleanupResources();
47
60
  if (thisGeneration === generation)
@@ -68,6 +81,48 @@ const constructor = (app) => {
68
81
  // Signal K protects routes registered directly on the plugin router with
69
82
  // administrator authentication. Do not downgrade this action via access().
70
83
  const adminRouter = router;
84
+ adminRouter.get?.('/course', async (_request, response, next) => {
85
+ try {
86
+ response.status(200).json({
87
+ ...(await courses?.status() ?? { desired: null, cachedCourse: null, acknowledgement: null, routePoints: [], native: { available: false, course: null, ownedRouteId: null, activeMatchesDesired: false, conflict: false } }),
88
+ uploadMode: activeUploadMode, connectionState, courseError: courseInitializationError
89
+ });
90
+ }
91
+ catch (error) {
92
+ next(error);
93
+ }
94
+ });
95
+ adminRouter.post('/course/activate', async (_request, response, next) => {
96
+ try {
97
+ if (!courses)
98
+ throw new protocol_1.CourseError('no_selected_course');
99
+ await courses.activate();
100
+ void transport?.publishCourseAcknowledgement().catch((error) => app.error(`Course acknowledgement deferred: ${safeError(error)}`));
101
+ response.status(200).json({ ...await courses.status(), uploadMode: activeUploadMode, connectionState });
102
+ }
103
+ catch (error) {
104
+ if (error instanceof protocol_1.CourseError)
105
+ response.status(409).json({ error: error.code });
106
+ else
107
+ next(error);
108
+ }
109
+ });
110
+ adminRouter.post('/course/map-readiness', async (request, response, next) => {
111
+ try {
112
+ if (!courses)
113
+ throw new protocol_1.CourseError('no_selected_course');
114
+ const body = request.body;
115
+ await courses.setMapReadiness(body?.revision, body?.status);
116
+ void transport?.publishCourseAcknowledgement().catch((error) => app.error(`Course acknowledgement deferred: ${safeError(error)}`));
117
+ response.status(200).json(await courses.status());
118
+ }
119
+ catch (error) {
120
+ if (error instanceof protocol_1.CourseError)
121
+ response.status(409).json({ error: error.code });
122
+ else
123
+ next(error);
124
+ }
125
+ });
71
126
  adminRouter.post('/forget-credentials', async (_request, response, next) => {
72
127
  try {
73
128
  generation += 1;
@@ -96,6 +151,9 @@ const constructor = (app) => {
96
151
  openapi: '3.0.3',
97
152
  info: { title: 'Wake Logger Signal K plugin', version: pluginVersion },
98
153
  paths: {
154
+ '/course': { get: { summary: 'Read cached and native course state', responses: { '200': { description: 'Course state' } } } },
155
+ '/course/map-readiness': { post: { summary: 'Report locally verified chart readiness for a course revision', responses: { '200': { description: 'Readiness saved' }, '409': { description: 'Invalid or stale revision' } } } },
156
+ '/course/activate': { post: { summary: 'Explicitly activate the selected cached course', responses: { '200': { description: 'Course active' }, '409': { description: 'No selected course or native course unavailable' } } } },
99
157
  '/forget-credentials': {
100
158
  post: {
101
159
  summary: 'Forget Wake Logger credentials while preserving all device outboxes',
@@ -115,6 +173,11 @@ const constructor = (app) => {
115
173
  sampleTimer = undefined;
116
174
  statusTimer = undefined;
117
175
  await transport?.stop();
176
+ await sampleOperation;
177
+ await courses?.close();
178
+ courses = undefined;
179
+ courseInitializationError = undefined;
180
+ courseFailureAcknowledgement = undefined;
118
181
  transport = undefined;
119
182
  await outbox?.close();
120
183
  outbox = undefined;
@@ -124,11 +187,12 @@ const constructor = (app) => {
124
187
  associationCheck = undefined;
125
188
  }
126
189
  async function initialise(config, thisGeneration) {
190
+ activeUploadMode = config.uploadMode;
127
191
  const dataDirectory = app.getDataDirPath();
128
192
  const credentialStore = new credentials_1.CredentialStore(node_path_1.default.join(dataDirectory, 'identity'));
129
193
  let credentials = await credentialStore.load();
130
194
  const lastPairingCodeFingerprint = await credentialStore.lastPairingCodeFingerprint();
131
- if ((0, credentials_1.shouldExchangePairingCode)(credentials, config.pairingCode, lastPairingCodeFingerprint)) {
195
+ if (config.uploadMode === 'automatic' && (0, credentials_1.shouldExchangePairingCode)(credentials, config.pairingCode, lastPairingCodeFingerprint)) {
132
196
  const controller = new AbortController();
133
197
  pairingAbortController = controller;
134
198
  try {
@@ -172,7 +236,7 @@ const constructor = (app) => {
172
236
  }
173
237
  if (!credentials) {
174
238
  connectionState = 'unpaired';
175
- app.setPluginStatus('Wake Logger: Not paired');
239
+ app.setPluginStatus(config.uploadMode === 'local_only' ? 'Wake Logger: Not paired — switch to automatic and pair before recording locally' : 'Wake Logger: Not paired');
176
240
  return;
177
241
  }
178
242
  if (generation !== thisGeneration)
@@ -180,11 +244,20 @@ const constructor = (app) => {
180
244
  await startTelemetry(config, credentials, credentialStore, dataDirectory, thisGeneration);
181
245
  }
182
246
  async function startTelemetry(config, credentials, credentialStore, dataDirectory, thisGeneration) {
247
+ courses = new course_store_1.CourseStore(node_path_1.default.join(dataDirectory, 'courses', credentials.deviceId, 'state.json'), new native_course_1.NativeCourseService(app));
248
+ try {
249
+ await courses.open();
250
+ }
251
+ catch (error) {
252
+ courses = undefined;
253
+ courseInitializationError = safeError(error);
254
+ app.error(`Wake Logger course cache unavailable; telemetry recording continues: ${courseInitializationError}`);
255
+ }
183
256
  const normaliser = new normaliser_1.TelemetryNormaliser();
184
257
  const tripFile = node_path_1.default.join(dataDirectory, 'trip-state.json');
185
- const trip = new state_machine_1.TripStateMachine(await readTripSnapshot(tripFile));
258
+ const trip = new recording_store_1.RecordingStore(node_path_1.default.join(dataDirectory, 'recordings', credentials.deviceId, 'state.json'));
259
+ await trip.open(await readTripSnapshot(tripFile));
186
260
  tripState = trip;
187
- let tripSnapshotJson = JSON.stringify(trip.currentState());
188
261
  // Each provisioned device owns an independent sequence space. A replacement
189
262
  // device must never replay the retired device's records under new credentials.
190
263
  const profileStore = new profile_store_1.TelemetryProfileStore(node_path_1.default.join(dataDirectory, 'profiles', credentials.deviceId));
@@ -192,7 +265,7 @@ const constructor = (app) => {
192
265
  const legacy = credentials.telemetryProfile;
193
266
  const profile = await profileStore.load() ?? credentialProfile ?? (0, profile_1.legacyProfile)(legacy?.sample_period_ms ?? config.samplePeriodMs, legacy?.batch_size);
194
267
  activeProfile = profile;
195
- const sampler = new sampler_1.PathSampler(profile);
268
+ const sampler = new sampler_1.PathSampler(profile, config.uploadMode === 'local_only' ? 'NORMAL' : 'OFFLINE');
196
269
  const selected = await (0, factory_1.createOutbox)(app, dataDirectory, credentials.deviceId, {
197
270
  maxBytes: config.maxOutboxMb * 1024 * 1024,
198
271
  maxAgeMs: config.maxOutboxDays * 24 * 60 * 60 * 1000,
@@ -200,6 +273,7 @@ const constructor = (app) => {
200
273
  }, credentials.outboxBinding?.backend);
201
274
  outbox = selected.store;
202
275
  storageBackend = selected.backend;
276
+ let nextSequence = (await outbox.stats()).currentSequence + 1;
203
277
  if (!credentials.outboxBinding) {
204
278
  credentials.outboxBinding = { version: 1, backend: selected.backend, initializedAt: Date.now() };
205
279
  await credentialStore.save(credentials);
@@ -216,6 +290,22 @@ const constructor = (app) => {
216
290
  if (state === 'authentication_failed')
217
291
  void confirmAssociation(credentials, thisGeneration);
218
292
  },
293
+ onCourse: async (payload) => {
294
+ if (courses)
295
+ return courses.receive(payload);
296
+ let revision = 0;
297
+ try {
298
+ revision = (0, protocol_1.parseCourse)(payload).revision;
299
+ }
300
+ catch { /* Report unavailable storage without accepting a new course. */ }
301
+ courseFailureAcknowledgement = { v: 1, revision, status: 'rejected', errorCode: 'course_storage_unavailable' };
302
+ return courseFailureAcknowledgement;
303
+ },
304
+ getCourseAcknowledgement: () => courses?.acknowledgement() ?? courseFailureAcknowledgement,
305
+ onRecordingAcks: async (acks) => {
306
+ sampleOperation = sampleOperation.then(() => trip.acknowledge(acks));
307
+ await sampleOperation;
308
+ },
219
309
  onMode: (mode) => sampler.updateMode(mode),
220
310
  onProfile: async (replacement) => {
221
311
  await profileStore.save(replacement);
@@ -225,37 +315,42 @@ const constructor = (app) => {
225
315
  debug: config.debugTelemetry ? (message) => app.debug(message) : undefined
226
316
  });
227
317
  stopSubscription = (0, subscriber_1.subscribeToTelemetry)(app, (delta) => normaliser.ingest(delta));
228
- const sample = () => {
318
+ const sample = async () => {
319
+ if (generation !== thisGeneration)
320
+ return;
229
321
  const now = Date.now();
230
322
  const draft = normaliser.takeSample(now, sampler.dueFields(now));
231
- if (!draft || !outbox || !transport)
323
+ if (!draft || !outbox)
232
324
  return;
233
- const evidence = trip.process(draft);
234
- draft.trackingSessionId = evidence?.trackingSessionId ?? trip.trackingSessionId();
235
- if (evidence)
236
- draft.evidence = evidence;
237
- const nextSnapshotJson = JSON.stringify(trip.currentState());
238
- if (nextSnapshotJson !== tripSnapshotJson) {
239
- tripSnapshotJson = nextSnapshotJson;
240
- void atomicWrite(tripFile, `${tripSnapshotJson}\n`).catch((error) => app.error(`Unable to persist Wake Logger trip state: ${safeError(error)}`));
325
+ await trip.prepare(draft, nextSequence);
326
+ let queued;
327
+ try {
328
+ queued = await outbox.append(credentials.deviceId, draft);
329
+ nextSequence = queued.sequence + 1;
330
+ }
331
+ catch (error) {
332
+ // Append may commit before a later maintenance error. Recover only on
333
+ // failure; scanning the complete offline queue every sample is costly.
334
+ nextSequence = (await outbox.stats()).currentSequence + 1;
335
+ throw error;
241
336
  }
242
- void outbox.append(credentials.deviceId, draft).then((sample) => {
243
- transport?.updateCurrent(sample);
244
- if (config.debugTelemetry)
245
- app.debug(`Queued Wake Logger sequence ${sample.sequence}`);
246
- }).catch((error) => app.error(`Unable to queue Wake Logger telemetry: ${safeError(error)}`));
337
+ transport?.updateCurrent(queued);
338
+ if (config.debugTelemetry)
339
+ app.debug(`Queued Wake Logger sequence ${queued.sequence}`);
247
340
  };
248
341
  const scheduleSample = () => {
249
342
  if (generation !== thisGeneration)
250
343
  return;
251
344
  sampleTimer = setTimeout(() => {
252
- sample();
253
- scheduleSample();
345
+ sampleOperation = sampleOperation.then(sample).catch((error) => app.error(`Unable to queue Wake Logger telemetry: ${safeError(error)}`)).then(scheduleSample);
254
346
  }, sampler.samplePeriodMs());
255
347
  };
256
348
  scheduleSample();
257
349
  statusTimer = setInterval(() => void updateStatus(), 10_000);
258
- transport.start();
350
+ if (config.uploadMode === 'automatic')
351
+ transport.start();
352
+ else
353
+ connectionState = 'recording_locally';
259
354
  await updateStatus();
260
355
  }
261
356
  async function updateStatus(detail) {
@@ -271,6 +366,8 @@ const constructor = (app) => {
271
366
  const extra = detail ? ` — ${detail}` : '';
272
367
  transport?.updateStatus({
273
368
  pluginVersion,
369
+ uploadMode: activeUploadMode,
370
+ recordings: tripState?.statusManifests(),
274
371
  connectionState,
275
372
  queueMessageCount: stats.messageCount,
276
373
  queueDiskBytes: stats.diskBytes,
@@ -289,6 +386,7 @@ const constructor = (app) => {
289
386
  return;
290
387
  }
291
388
  app.setPluginStatus(`Wake Logger: ${connectionState} — ${queue}${dropped}${sequence}${trip}${extra}`);
389
+ void transport?.publishCourseAcknowledgement().catch((error) => app.error(`Unable to report Wake Logger course: ${safeError(error)}`));
292
390
  }
293
391
  function confirmAssociation(credentials, thisGeneration) {
294
392
  if (associationCheck)
@@ -326,11 +424,6 @@ async function readTripSnapshot(target) {
326
424
  throw error;
327
425
  }
328
426
  }
329
- async function atomicWrite(target, contents) {
330
- const temporary = `${target}.tmp`;
331
- await node_fs_1.promises.writeFile(temporary, contents, { mode: 0o600 });
332
- await node_fs_1.promises.rename(temporary, target);
333
- }
334
427
  function safeError(error) {
335
428
  return (error instanceof Error ? error.message : String(error)).replace(/(password|token|secret)=\S+/gi, '$1=[redacted]').slice(0, 500);
336
429
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AACA,qCAAwC;AACxC,0DAA4B;AAC5B,4CAA8C;AAC9C,gDAA4E;AAC5E,8CAA+C;AAE/C,qEAAqE;AACrE,uDAAkI;AAClI,6DAA4E;AAC5E,qDAA0D;AAC1D,qDAA2D;AAC3D,iDAAiG;AACjG,6DAAiE;AACjE,iDAAiD;AACjD,yDAAmF;AACnF,yDAA2E;AAE3E,MAAM,WAAW,GAAsB,CAAC,GAAc,EAAU,EAAE;IAChE,MAAM,aAAa,GAAG,cAAc,CAAA;IACpC,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,gBAA0C,CAAA;IAC9C,IAAI,WAAuC,CAAA;IAC3C,IAAI,WAAuC,CAAA;IAC3C,IAAI,MAA+B,CAAA;IACnC,IAAI,SAA0C,CAAA;IAC9C,IAAI,SAAuC,CAAA;IAC3C,IAAI,eAAe,GAAoD,UAAU,CAAA;IACjF,IAAI,aAA2C,CAAA;IAC/C,IAAI,cAAc,GAAwB,MAAM,CAAA;IAChD,IAAI,cAAyC,CAAA;IAC7C,IAAI,sBAAmD,CAAA;IACvD,IAAI,0BAAuD,CAAA;IAC3D,IAAI,gBAA2C,CAAA;IAE/C,MAAM,MAAM,GAAW;QACrB,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,uEAAuE;QACpF,MAAM,EAAE,qBAAY;QACpB,KAAK,CAAC,aAAqB;YACzB,MAAM,QAAQ,GAAG,cAAc,CAAA;YAC/B,MAAM,cAAc,GAAG,EAAE,UAAU,CAAA;YACnC,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC3B,MAAM,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;gBACtC,MAAM,gBAAgB,EAAE,CAAA;gBACxB,IAAI,cAAc,KAAK,UAAU;oBAAE,MAAM,UAAU,CAAC,IAAA,sBAAW,EAAC,aAAa,CAAC,EAAE,cAAc,CAAC,CAAA;YACjG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBAC5B,IAAI,cAAc,KAAK,UAAU;oBAAE,OAAM;gBACzC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;gBAChC,GAAG,CAAC,cAAc,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAA;gBACnE,GAAG,CAAC,KAAK,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAA;YAC5D,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,KAAK,CAAC,IAAI;YACR,MAAM,OAAO,GAAG,cAAc,CAAA;YAC9B,UAAU,IAAI,CAAC,CAAA;YACf,sBAAsB,EAAE,KAAK,EAAE,CAAA;YAC/B,0BAA0B,EAAE,KAAK,EAAE,CAAA;YACnC,MAAM,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YACrC,MAAM,gBAAgB,EAAE,CAAA;YACxB,cAAc,GAAG,SAAS,CAAA;YAC1B,GAAG,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAA;QAC7C,CAAC;QACD,kBAAkB,CAAC,MAAM;YACvB,yEAAyE;YACzE,2EAA2E;YAC3E,MAAM,WAAW,GAAG,MAMnB,CAAA;YACD,WAAW,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;gBACzE,IAAI,CAAC;oBACH,UAAU,IAAI,CAAC,CAAA;oBACf,sBAAsB,EAAE,KAAK,EAAE,CAAA;oBAC/B,0BAA0B,EAAE,KAAK,EAAE,CAAA;oBACnC,MAAM,cAAc,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;oBAC5C,MAAM,gBAAgB,EAAE,CAAA;oBACxB,MAAM,KAAK,GAAG,IAAI,6BAAe,CAAC,mBAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;oBAC9E,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAA;oBACnC,cAAc,GAAG,SAAS,CAAA;oBAC1B,eAAe,GAAG,UAAU,CAAA;oBAC5B,GAAG,CAAC,eAAe,CAAC,6EAA6E,CAAC,CAAA;oBAClG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBACxB,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,eAAe,EAAE,MAAM,CAAC,QAAQ;wBAChC,iBAAiB,EAAE,IAAI;wBACvB,IAAI,EAAE,kDAAkD;qBACzD,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAAC,CAAC;YACjC,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;YACjB,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,OAAO,EAAE,aAAa,EAAE;YACtE,KAAK,EAAE;gBACL,qBAAqB,EAAE;oBACrB,IAAI,EAAE;wBACJ,OAAO,EAAE,qEAAqE;wBAC9E,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,yCAAyC,EAAE,EAAE;qBACjF;iBACF;aACF;SACF,CAAC;KACH,CAAA;IAED,KAAK,UAAU,gBAAgB;QAC7B,gBAAgB,EAAE,EAAE,CAAA;QACpB,gBAAgB,GAAG,SAAS,CAAA;QAC5B,IAAI,WAAW;YAAE,YAAY,CAAC,WAAW,CAAC,CAAA;QAC1C,IAAI,WAAW;YAAE,aAAa,CAAC,WAAW,CAAC,CAAA;QAC3C,WAAW,GAAG,SAAS,CAAA;QACvB,WAAW,GAAG,SAAS,CAAA;QACvB,MAAM,SAAS,EAAE,IAAI,EAAE,CAAA;QACvB,SAAS,GAAG,SAAS,CAAA;QACrB,MAAM,MAAM,EAAE,KAAK,EAAE,CAAA;QACrB,MAAM,GAAG,SAAS,CAAA;QAClB,SAAS,GAAG,SAAS,CAAA;QACrB,sBAAsB,GAAG,SAAS,CAAA;QAClC,0BAA0B,GAAG,SAAS,CAAA;QACtC,gBAAgB,GAAG,SAAS,CAAA;IAC9B,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,MAAoB,EAAE,cAAsB;QACpE,MAAM,aAAa,GAAG,GAAG,CAAC,cAAc,EAAE,CAAA;QAC1C,MAAM,eAAe,GAAG,IAAI,6BAAe,CAAC,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAA;QACjF,IAAI,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,CAAA;QAC9C,MAAM,0BAA0B,GAAG,MAAM,eAAe,CAAC,0BAA0B,EAAE,CAAA;QACrF,IAAI,IAAA,uCAAyB,EAAC,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,0BAA0B,CAAC,EAAE,CAAC;YAC3F,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,sBAAsB,GAAG,UAAU,CAAA;YACnC,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,IAAA,oCAAmB,EAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,eAAe,CAAC,cAAc,EAAE,EAAE;oBAC9H,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;wBAC9B,IAAI,UAAU,KAAK,cAAc;4BAAE,GAAG,CAAC,eAAe,CAAC,gCAAgC,OAAO,IAAI,OAAO,EAAE,CAAC,CAAA;oBAC9G,CAAC;oBACD,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;wBACrC,IAAI,UAAU,KAAK,cAAc;4BAAE,GAAG,CAAC,eAAe,CAAC,8BAA8B,OAAO,IAAI,OAAO,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;oBACpJ,CAAC;iBACF,CAAC,CAAA;gBACF,IAAI,UAAU,KAAK,cAAc;oBAAE,OAAM;gBACzC,WAAW,CAAC,sBAAsB,GAAG,IAAA,oCAAsB,EAAC,MAAM,CAAC,WAAW,CAAC,CAAA;gBAC/E,MAAM,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACvC,WAAW,GAAG,WAAW,CAAA;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,UAAU,KAAK,cAAc,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAM;gBACtE,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,eAAe,GAAG,UAAU,CAAA;oBAC5B,MAAM,OAAO,GAAG,KAAK,YAAY,6BAAY,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAA;oBACrE,MAAM,cAAc,GAAG,KAAK,YAAY,6BAAY,IAAI,KAAK,CAAC,SAAS,CAAA;oBACvE,GAAG,CAAC,eAAe,CACjB,OAAO;wBACL,CAAC,CAAC,yEAAyE;wBAC3E,CAAC,CAAC,cAAc;4BACd,CAAC,CAAC,uGAAuG;4BACzG,CAAC,CAAC,mCAAmC,SAAS,CAAC,KAAK,CAAC,4BAA4B,CACtF,CAAA;oBACD,OAAM;gBACR,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,gFAAgF,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YAC/G,CAAC;oBAAS,CAAC;gBACT,IAAI,sBAAsB,KAAK,UAAU;oBAAE,sBAAsB,GAAG,SAAS,CAAA;YAC/E,CAAC;QACH,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,eAAe,GAAG,UAAU,CAAA;YAC5B,GAAG,CAAC,eAAe,CAAC,yBAAyB,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QACD,IAAI,UAAU,KAAK,cAAc;YAAE,OAAM;QACzC,MAAM,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,CAAC,CAAA;IAC3F,CAAC;IAED,KAAK,UAAU,cAAc,CAAC,MAAoB,EAAE,WAA8B,EAAE,eAAgC,EAAE,aAAqB,EAAE,cAAsB;QACjK,MAAM,UAAU,GAAG,IAAI,gCAAmB,EAAE,CAAA;QAC5C,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAA;QAC5D,MAAM,IAAI,GAAG,IAAI,gCAAgB,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAA;QACnE,SAAS,GAAG,IAAI,CAAA;QAChB,IAAI,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAA;QAC1D,4EAA4E;QAC5E,+EAA+E;QAC/E,MAAM,YAAY,GAAG,IAAI,qCAAqB,CAAC,mBAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC1G,MAAM,iBAAiB,GAAG,IAAA,+BAAqB,EAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;QAC7E,MAAM,MAAM,GAAG,WAAW,CAAC,gBAAkF,CAAA;QAC7G,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,iBAAiB,IAAI,IAAA,uBAAa,EAAC,MAAM,EAAE,gBAAgB,IAAI,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;QACtJ,aAAa,GAAG,OAAO,CAAA;QACvB,MAAM,OAAO,GAAG,IAAI,qBAAW,CAAC,OAAO,CAAC,CAAA;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAY,EAAC,GAAG,EAAE,aAAa,EAAE,WAAW,CAAC,QAAQ,EAAE;YAC5E,QAAQ,EAAE,MAAM,CAAC,WAAW,GAAG,IAAI,GAAG,IAAI;YAC1C,QAAQ,EAAE,MAAM,CAAC,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;YACpD,YAAY,EAAE,mBAAQ,CAAC,YAAY;SACpC,EAAE,WAAW,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QACtC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAA;QACvB,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAA;QACjC,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;YAC/B,WAAW,CAAC,aAAa,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;YAChG,MAAM,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,UAAU,KAAK,cAAc;YAAE,OAAM;QACzC,SAAS,GAAG,IAAI,iCAAmB,CAAC,WAAW,EAAE,MAAM,EAAE;YACvD,OAAO;YACP,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;gBACzB,IAAI,eAAe,KAAK,gBAAgB;oBAAE,OAAM;gBAChD,eAAe,GAAG,KAAK,CAAA;gBACvB,KAAK,YAAY,CAAC,MAAM,CAAC,CAAA;gBACzB,IAAI,KAAK,KAAK,uBAAuB;oBAAE,KAAK,kBAAkB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;YAC7F,CAAC;YACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAC1C,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;gBAC/B,MAAM,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACpC,aAAa,GAAG,WAAW,CAAA;gBAC3B,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;YACpC,CAAC;YACD,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;SAC3E,CAAC,CAAA;QACF,gBAAgB,GAAG,IAAA,iCAAoB,EAAC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACjF,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;YAChE,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;gBAAE,OAAM;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACpC,KAAK,CAAC,iBAAiB,GAAG,QAAQ,EAAE,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAA;YACjF,IAAI,QAAQ;gBAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAA;YACvC,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAA;YAC5D,IAAI,gBAAgB,KAAK,gBAAgB,EAAE,CAAC;gBAC1C,gBAAgB,GAAG,gBAAgB,CAAA;gBACnC,KAAK,WAAW,CAAC,QAAQ,EAAE,GAAG,gBAAgB,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;YAClJ,CAAC;YACD,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC9D,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;gBAChC,IAAI,MAAM,CAAC,cAAc;oBAAE,GAAG,CAAC,KAAK,CAAC,+BAA+B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;YACxF,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,0CAA0C,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAC9F,CAAC,CAAA;QACD,MAAM,cAAc,GAAG,GAAG,EAAE;YAC1B,IAAI,UAAU,KAAK,cAAc;gBAAE,OAAM;YACzC,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,MAAM,EAAE,CAAA;gBACR,cAAc,EAAE,CAAA;YAClB,CAAC,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAA;QAC9B,CAAC,CAAA;QACD,cAAc,EAAE,CAAA;QAChB,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,YAAY,EAAE,EAAE,MAAM,CAAC,CAAA;QAC5D,SAAS,CAAC,KAAK,EAAE,CAAA;QACjB,MAAM,YAAY,EAAE,CAAA;IACtB,CAAC;IAED,KAAK,UAAU,YAAY,CAAC,MAAe;QACzC,IAAI,eAAe,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9C,GAAG,CAAC,eAAe,CAAC,yBAAyB,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QAClC,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,YAAY,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;QAC9F,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3E,MAAM,QAAQ,GAAG,SAAS,KAAK,CAAC,oBAAoB,IAAI,KAAK,CAAC,eAAe,EAAE,CAAA;QAC/E,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,SAAS,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1C,SAAS,EAAE,YAAY,CAAC;YACtB,aAAa;YACb,eAAe;YACf,iBAAiB,EAAE,KAAK,CAAC,YAAY;YACrC,cAAc,EAAE,KAAK,CAAC,SAAS;YAC/B,qBAAqB,EAAE,KAAK,CAAC,gBAAgB;YAC7C,iBAAiB,EAAE,KAAK,CAAC,YAAY;YACrC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;YAChD,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,KAAK;YAC9C,cAAc;YACd,SAAS,EAAE,aAAa,EAAE,SAAS;YACnC,eAAe,EAAE,aAAa,EAAE,QAAQ;YACxC,GAAG,SAAS,EAAE,gBAAgB,EAAE;SACjC,CAAC,CAAA;QACF,IAAI,eAAe,KAAK,gBAAgB,EAAE,CAAC;YACzC,GAAG,CAAC,eAAe,CAAC,2DAA2D,KAAK,GAAG,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAA;YAC5G,OAAM;QACR,CAAC;QACD,GAAG,CAAC,eAAe,CAAC,gBAAgB,eAAe,MAAM,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAA;IACvG,CAAC;IAED,SAAS,kBAAkB,CAAC,WAA8B,EAAE,cAAsB;QAChF,IAAI,gBAAgB;YAAE,OAAO,gBAAgB,CAAA;QAC7C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,0BAA0B,GAAG,UAAU,CAAA;QACvC,gBAAgB,GAAG,CAAC,KAAK,IAAI,EAAE;YAC7B,MAAM,MAAM,GAAG,MAAM,IAAA,2CAAsB,EAAC,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;YAC3E,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU,KAAK,cAAc,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAM;YAC9F,eAAe,GAAG,gBAAgB,CAAA;YAClC,gBAAgB,EAAE,EAAE,CAAA;YACpB,gBAAgB,GAAG,SAAS,CAAA;YAC5B,IAAI,WAAW;gBAAE,YAAY,CAAC,WAAW,CAAC,CAAA;YAC1C,WAAW,GAAG,SAAS,CAAA;YACvB,MAAM,SAAS,EAAE,IAAI,EAAE,CAAA;YACvB,MAAM,YAAY,EAAE,CAAA;QACtB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,IAAI,0BAA0B,KAAK,UAAU;gBAAE,0BAA0B,GAAG,SAAS,CAAA;YACrF,gBAAgB,GAAG,SAAS,CAAA;QAC9B,CAAC,CAAC,CAAA;QACF,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAc;IAC5C,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,kBAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAiB,CAAA;IAAC,CAAC;IAC5E,OAAO,KAAK,EAAE,CAAC;QACb,IAAK,KAA+B,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,YAAY,WAAW;YAAE,OAAO,SAAS,CAAA;QACzG,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,QAAgB;IACzD,MAAM,SAAS,GAAG,GAAG,MAAM,MAAM,CAAA;IACjC,MAAM,kBAAE,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACxD,MAAM,kBAAE,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,+BAA+B,EAAE,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AACzI,CAAC;AAED,iBAAS,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,16 @@ export interface TripEvidence {
25
25
  movementDurationSeconds?: number;
26
26
  };
27
27
  }
28
+ export interface RecordingManifest {
29
+ id: string;
30
+ startedAt: number;
31
+ firstSequence: number;
32
+ state: 'recording' | 'complete' | 'cancelled' | 'interrupted';
33
+ endedAt?: number;
34
+ lastSequence?: number;
35
+ }
28
36
  export interface TelemetryDraft {
37
+ recording?: RecordingManifest;
29
38
  capturedAt: number;
30
39
  receivedAt: number;
31
40
  trackingSessionId?: string;
@@ -45,13 +54,17 @@ export interface TelemetryBatch {
45
54
  droppedThrough?: number;
46
55
  samples: TelemetrySample[];
47
56
  }
57
+ export type RecordingAcknowledgement = Pick<RecordingManifest, 'id' | 'lastSequence' | 'state'>;
48
58
  export interface ApplicationAck {
59
+ recordingAcks?: RecordingAcknowledgement[];
49
60
  v: 1;
50
61
  deviceId: string;
51
62
  ackSequence: number;
52
63
  acknowledgedAt?: number;
53
64
  }
54
65
  export interface PluginStatusMetrics {
66
+ uploadMode?: 'automatic' | 'local_only';
67
+ recordings?: RecordingManifest[];
55
68
  pluginVersion: string;
56
69
  connectionState: string;
57
70
  queueMessageCount: number;