signalk-livedepth-plugin 0.2.0 → 0.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +67 -41
  3. package/dist/collector.d.ts +1 -1
  4. package/dist/collector.d.ts.map +1 -1
  5. package/dist/config.d.ts +3 -3
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +8 -3
  8. package/dist/config.js.map +1 -1
  9. package/dist/plotterext/manifest.d.ts +24 -0
  10. package/dist/plotterext/manifest.d.ts.map +1 -0
  11. package/dist/plotterext/manifest.js +78 -0
  12. package/dist/plotterext/manifest.js.map +1 -0
  13. package/dist/plotterext/provider.d.ts +7 -0
  14. package/dist/plotterext/provider.d.ts.map +1 -0
  15. package/dist/plotterext/provider.js +61 -0
  16. package/dist/plotterext/provider.js.map +1 -0
  17. package/dist/plugin.d.ts +9 -0
  18. package/dist/plugin.d.ts.map +1 -1
  19. package/dist/plugin.js +32 -10
  20. package/dist/plugin.js.map +1 -1
  21. package/dist/streams/live.d.ts +1 -1
  22. package/dist/streams/live.d.ts.map +1 -1
  23. package/dist/streams/live.js +1 -1
  24. package/dist/streams/live.js.map +1 -1
  25. package/dist/tiles/api.d.ts +21 -11
  26. package/dist/tiles/api.d.ts.map +1 -1
  27. package/dist/tiles/api.js +42 -28
  28. package/dist/tiles/api.js.map +1 -1
  29. package/dist/tiles/core/accumulator.d.ts +37 -0
  30. package/dist/tiles/core/accumulator.d.ts.map +1 -0
  31. package/dist/tiles/core/accumulator.js +75 -0
  32. package/dist/tiles/core/accumulator.js.map +1 -0
  33. package/dist/tiles/core/correction.d.ts +32 -0
  34. package/dist/tiles/core/correction.d.ts.map +1 -0
  35. package/dist/tiles/core/correction.js +43 -0
  36. package/dist/tiles/core/correction.js.map +1 -0
  37. package/dist/tiles/core/grid.d.ts +64 -0
  38. package/dist/tiles/core/grid.d.ts.map +1 -0
  39. package/dist/tiles/core/grid.js +127 -0
  40. package/dist/tiles/core/grid.js.map +1 -0
  41. package/dist/tiles/core/index.d.ts +7 -0
  42. package/dist/tiles/core/index.d.ts.map +1 -0
  43. package/dist/tiles/core/index.js +7 -0
  44. package/dist/tiles/core/index.js.map +1 -0
  45. package/dist/tiles/core/store.d.ts +37 -0
  46. package/dist/tiles/core/store.d.ts.map +1 -0
  47. package/dist/tiles/core/store.js +86 -0
  48. package/dist/tiles/core/store.js.map +1 -0
  49. package/dist/tiles/core/tile-source.d.ts +41 -0
  50. package/dist/tiles/core/tile-source.d.ts.map +1 -0
  51. package/dist/tiles/core/tile-source.js +86 -0
  52. package/dist/tiles/core/tile-source.js.map +1 -0
  53. package/dist/tiles/core/types.d.ts +11 -0
  54. package/dist/tiles/core/types.d.ts.map +1 -0
  55. package/dist/tiles/core/types.js +2 -0
  56. package/dist/tiles/core/types.js.map +1 -0
  57. package/dist/tiles/index.d.ts +1 -1
  58. package/dist/tiles/index.d.ts.map +1 -1
  59. package/dist/tiles/index.js +1 -1
  60. package/dist/tiles/index.js.map +1 -1
  61. package/dist/tiles/seed.d.ts +1 -1
  62. package/dist/tiles/seed.d.ts.map +1 -1
  63. package/dist/tiles/seed.js +1 -1
  64. package/dist/tiles/seed.js.map +1 -1
  65. package/dist/tiles/store.d.ts +1 -1
  66. package/dist/tiles/store.d.ts.map +1 -1
  67. package/dist/tiles/store.js +1 -1
  68. package/dist/tiles/store.js.map +1 -1
  69. package/dist/tiles/writer.d.ts +1 -1
  70. package/dist/tiles/writer.d.ts.map +1 -1
  71. package/dist/tiles/writer.js +1 -1
  72. package/dist/tiles/writer.js.map +1 -1
  73. package/dist/tsconfig.tsbuildinfo +1 -1
  74. package/package.json +27 -6
  75. package/public/config.html +14 -0
  76. package/public/index.html +15 -0
  77. package/public/js/config.js +901 -0
  78. package/public/js/config.js.map +7 -0
  79. package/public/js/render-worker.js +706 -0
  80. package/public/js/render-worker.js.map +7 -0
  81. package/public/js/renderer.js +1273 -0
  82. package/public/js/renderer.js.map +7 -0
  83. package/public/renderer.html +14 -0
  84. package/public/styles.css +110 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,67 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here, newest first. The
4
+ format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
5
+ versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.3.0] - 2026-10-15
8
+
9
+ The LiveDepth chart layer, and the merge that brings everything into one
10
+ package. The chart layer needs a host that implements `overlays.image` —
11
+ Freeboard-SK **3.4.0-beta.0 or later**.
12
+
13
+ ### Added
14
+
15
+ - The **LiveDepth chart layer**: an image map overlay offered to
16
+ plotter-extensions chartplotters (Freeboard-SK 3.4.0-beta.0 or later), drawn
17
+ by a headless background runtime that shades the depth surface, draws isobaths
18
+ and
19
+ labels the shoals. It appears in the chartplotter's Chart list with show/hide
20
+ and opacity controls, and its settings open from the layer's row or the
21
+ LiveDepth toolbar button.
22
+
23
+ ### Changed
24
+
25
+ - The shared tile algorithm (`signalk-livedepth-tiles`) is folded into this
26
+ package under `src/tiles/core/`; that published package is no longer a
27
+ dependency.
28
+ - Bathymetry data is served from the extension's own top-level path
29
+ (`/plotterext/signalk-livedepth-plugin/bathymetry/…`) so a read-only user's
30
+ chartplotter can reach it; the one-time history rebuild stays an admin route.
31
+
32
+ ### Fixed
33
+
34
+ - The config schema no longer emits a `default: undefined`, which the server
35
+ dropped when storing the schema as JSON.
36
+ - Switching the depth source now takes effect: the live Signal K subscription
37
+ starts and stops with the source.
38
+ - The settings panel greys the history-only fields while the depth source is the
39
+ plugin's tiles, and shows depth values in the user's preferred unit.
40
+
41
+ ## [0.2.1] - 2026-10-14
42
+
43
+ ### Fixed
44
+
45
+ - Serve tiles as raw bytes, not JSON — express was JSON-encoding the `Uint8Array`
46
+ `encodeTile` returns, so a client decoded the JSON text as sparse records.
47
+ - Read the vessel length overall from `design.length`, so transducer correction
48
+ no longer reports it missing on servers that have it.
49
+
50
+ ## [0.2.0] - 2026-10-14
51
+
52
+ ### Added
53
+
54
+ - Transducer position correction.
55
+
56
+ ### Changed
57
+
58
+ - Trimmed the configuration to the depth path, the transducer's position, the
59
+ correction mode and the one-time history rebuild.
60
+
61
+ ## [0.1.0] - 2026-10-13
62
+
63
+ ### Added
64
+
65
+ - First release: build a gridded bathymetry tile store from the vessel's own
66
+ position and depth, serve it to a chart client, and seed it from the server's
67
+ History API.
package/README.md CHANGED
@@ -1,54 +1,80 @@
1
- # signalk-livedepth-plugin
1
+ # LiveDepth
2
2
 
3
- A Signal K server plugin that builds a **gridded bathymetry tile store** from the
4
- vessel's own position and depth, and serves it to a chart client's LiveDepth
5
- layer. It is the server side of Freeboard-SK's LiveDepth layer.
3
+ **LiveDepth builds and visualises a depth map from your own soundings, in real
4
+ time, as your vessel moves.** Everywhere you go, your depth sounder's readings
5
+ are turned into bathymetric data you can see on the chart — so the ground you've
6
+ already covered is there to look at the next time you're in the area.
6
7
 
7
8
  ## What it does
8
9
 
9
- - Subscribes to the vessel's own `environment.depth.*` and `navigation.position`,
10
- and folds each sounding into a Web-Mercator XYZ tile store: 256-cell tiles,
11
- base level `z20` (≈0.15 m per cell), min-pooled down to `z4` (≈2.4 km per
12
- cell). A tile is stored sparsely — only the cells a sounding fell in — as a
13
- 5-byte record (`cx, cy, depthCm, count`) keeping the shallowest depth, so
14
- zooming out never deepens a shoal. The tile algorithm itself lives in
15
- [`signalk-livedepth-tiles`](https://www.npmjs.com/package/signalk-livedepth-tiles),
16
- shared with the chart client so both build identical tiles.
17
- - Serves the tiles over HTTP so a chart client can draw a depth surface for the
18
- area without replaying the raw track or interpolating at query time.
19
- - Can seed the store from the server's History API at the finest granularity it
20
- offers — a one-time, resumable rebuild for a store that already has a track.
21
-
22
- ## Routes
23
-
24
- Mounted by the server at `/plugins/signalk-livedepth-plugin`:
25
-
26
- | Route | Returns |
27
- | -------------------------------- | -------------------------------------------------------------------------------------- |
28
- | `GET /bathymetry/meta` | grid spec (base/min zoom, tile size, record size) and the depth path/offsets to mirror |
29
- | `GET /bathymetry/tiles/:z/:x/:y` | the sparse tile blob (`application/octet-stream`), or `404` |
30
- | `GET /bathymetry/seed` | admin only: status of the one-time history rebuild |
31
- | `POST /bathymetry/seed` | admin only: start the one-time history rebuild (`202`) |
32
-
33
- A client seeds its view from the tiles, then keeps its own copy current from the
34
- same Signal K stream.
35
-
36
- ## Configuration
37
-
38
- - **Path** — the `environment.depth.*` path to record.
39
- - **Depth Sounder / GPS Receiver** — the sensor offsets, and the source to pin
40
- each path to (so soundings from a second GPS don't smear the track).
41
- - **Rebuild from History** — a one-shot rebuild from the server's History API;
42
- it fires once when saved and clears itself when it finishes.
10
+ - **Records as you go.** Each depth reading is placed where your vessel was when
11
+ it was taken, building a picture of the seabed along your track. No surveying
12
+ needed — just your normal boating.
13
+ - **Draws it on the chart.** A compatible chartplotter (Freeboard-SK) shows the
14
+ depth as a shaded surface with depth-contour lines, so you can see the shape of
15
+ the ground and where it shallows.
16
+ - **Never hides a shoal.** Where readings overlap, the shallowest one wins, so
17
+ zooming out can't bury a shallow patch under the deeper water around it.
18
+ - **Live or accumulated.** Show your own recent track, or the depth map the
19
+ server has built up over time — extended live as you move.
20
+ - **Rebuild from history.** Already have a track recorded on the server? A
21
+ one-time rebuild fills the map in from it.
22
+
23
+ ## What you need
24
+
25
+ - A Signal K server with your depth sounder and GPS feeding it.
26
+ - A chartplotter that supports plotter extensions — **Freeboard-SK
27
+ 3.4.0-beta.0 or later**, or another host that supports the `overlays.image`
28
+ capability.
29
+ - The plugin enabled on the server (install it from the App Store, then switch it
30
+ on in the server's plugin settings).
31
+
32
+ ## Using it
33
+
34
+ Once enabled, **Live depth** appears in the chartplotter's Chart list, under
35
+ _Plugin layers_, with its own show/hide and opacity controls — saved just like a
36
+ chart's. Open **Layer settings** on its row (or the LiveDepth toolbar button) to
37
+ choose what it shows:
38
+
39
+ - **Show the layer** — on or off.
40
+ - **Depth source** — your own recent track, or the accumulated depth map.
41
+ - **Shade limit** — the depth the shading runs to; deeper water is left to the
42
+ chart.
43
+ - **Isobath interval** — how far apart the depth-contour lines are.
44
+ - **Grid cell**, **Merge band** — how readings are grouped into the dots on the
45
+ chart.
46
+ - **Max depth**, **Safety depth** — which readings are drawn, and which shallow
47
+ ones are marked individually.
48
+
49
+ Depth values are shown in your preferred units.
50
+
51
+ ## Server settings
52
+
53
+ - **Path** — which depth measurement to record (below surface, transducer or
54
+ keel).
55
+ - **Depth transducer** — where the sounder sits on the hull, so each reading is
56
+ placed at it rather than at the position the server reports.
57
+ - **Transducer position correction** — shift readings from the vessel's
58
+ reference point to the transducer (needs the server's own GNSS correction on).
59
+ - **Rebuild from history** — a one-time rebuild of the depth map from the track
60
+ the server already has.
61
+
62
+ ## How it works
63
+
64
+ The plugin runs on your Signal K server and turns each sounding into a
65
+ Web-Mercator depth map, keeping the shallowest reading for every spot. A
66
+ chartplotter that supports plotter extensions draws it as a map layer, rendering
67
+ in the browser. The plugin offers the layer to the chartplotter automatically —
68
+ there's nothing to configure on the chart side.
43
69
 
44
70
  ## Development
45
71
 
46
72
  ```bash
47
73
  npm install
48
- npm run build # tsc -b -> dist/
49
- npm test # vitest
74
+ npm run build # server code (dist/) + the chart-layer pages (public/)
75
+ npm test # vitest
50
76
  npm run format
51
77
  npm run lint
52
78
  ```
53
79
 
54
- Node `>=22.5` (the store uses the built-in `node:sqlite`).
80
+ Node `>=22.5`.
@@ -1,6 +1,6 @@
1
1
  import { Writable } from "stream";
2
2
  import { ServerAPI } from "@signalk/server-api";
3
- import { TransducerOffset } from "signalk-livedepth-tiles";
3
+ import { TransducerOffset } from "./tiles/core/index.js";
4
4
  import { Config } from "./config.js";
5
5
  export interface CollectorOptions {
6
6
  app: ServerAPI;
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,0CAkBlB"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,0CAkBlB"}
package/dist/config.d.ts CHANGED
@@ -29,7 +29,7 @@ export declare function schema(app: ServerAPI): {
29
29
  description: string;
30
30
  enum: readonly ["belowSurface", "belowTransducer", "belowKeel"];
31
31
  enumNames: string[];
32
- default: "belowKeel" | "belowSurface" | "belowTransducer" | undefined;
32
+ default?: "belowKeel" | "belowSurface" | "belowTransducer" | undefined;
33
33
  };
34
34
  sounder: {
35
35
  type: string;
@@ -41,13 +41,13 @@ export declare function schema(app: ServerAPI): {
41
41
  type: string;
42
42
  title: string;
43
43
  minimum: number;
44
- default: unknown;
44
+ default?: {} | null | undefined;
45
45
  };
46
46
  x: {
47
47
  type: string;
48
48
  title: string;
49
49
  description: string;
50
- default: unknown;
50
+ default?: {} | null | undefined;
51
51
  };
52
52
  };
53
53
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,MAAM,MAAM,GAAG;IACnB;0DACsD;IACtD,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC;;oEAEgE;IAChE,OAAO,EAAE;QACP,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF;kEAC8D;IAC9D,oBAAoB,EAAE,KAAK,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,CACH,CAAC;AAEX,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS;IAKjC,IAAI;IACJ,WAAW;IAEX,UAAU;QACR,IAAI;YACF,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YAKT,OAAO;;QAET,OAAO;YACL,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,QAAQ;YACR,UAAU;gBACR,CAAC;oBACC,IAAI;oBACJ,KAAK;oBACL,OAAO;oBACP,OAAO;;gBAET,CAAC;oBACC,IAAI;oBACJ,KAAK;oBACL,WAAW;oBACX,OAAO;;;;QAIb,oBAAoB;YAClB,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YACT,OAAO;;QAET,IAAI;YACF,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,GAAG;oBACD,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,UAAU;oBACR,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;EAOtB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,MAAM,MAAM,GAAG;IACnB;0DACsD;IACtD,IAAI,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC;;oEAEgE;IAChE,OAAO,EAAE;QACP,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF;kEAC8D;IAC9D,oBAAoB,EAAE,KAAK,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,iBAAiB,EACjB,WAAW,CACH,CAAC;AAEX,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiD7B,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,IAAI;YACJ,SAAS;YACT,OAAO;;;YAGP,IAAI;YACJ,KAAK;YACL,WAAW;YAEX,UAAU;gBACR,GAAG;oBACD,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;gBAGb,UAAU;oBACR,IAAI;oBACJ,OAAO;oBACP,KAAK;oBACL,WAAW;;;;;EAOtB"}
package/dist/config.js CHANGED
@@ -5,6 +5,11 @@ export const DepthPaths = [
5
5
  ];
6
6
  export function schema(app) {
7
7
  const defaultPath = DepthPaths.find((path) => app.getSelfPath(`environment.depth.${path}.value`));
8
+ // A `default` is attached only when present: `default: undefined` survives in
9
+ // the object but is dropped when the server stores the schema as JSON, which
10
+ // its plugin schema check flags as data loss.
11
+ const fromBow = app.getSelfPath("sensors.depth.fromBow.value");
12
+ const fromCenter = app.getSelfPath("sensors.depth.fromCenter.value");
8
13
  return {
9
14
  type: "object",
10
15
  description: "Build a gridded bathymetry tile store from the vessel's own position and depth, and serve it to a chart client's LiveDepth layer.",
@@ -19,7 +24,7 @@ export function schema(app) {
19
24
  "Depth below transducer",
20
25
  "Depth below keel",
21
26
  ],
22
- default: defaultPath,
27
+ ...(defaultPath === undefined ? {} : { default: defaultPath }),
23
28
  },
24
29
  sounder: {
25
30
  type: "object",
@@ -31,13 +36,13 @@ export function schema(app) {
31
36
  type: "number",
32
37
  title: "Distance of the transducer from the bow (meters)",
33
38
  minimum: 0,
34
- default: app.getSelfPath("sensors.depth.fromBow.value"),
39
+ ...(fromBow === undefined ? {} : { default: fromBow }),
35
40
  },
36
41
  x: {
37
42
  type: "number",
38
43
  title: "Distance of the transducer from the center (meters)",
39
44
  description: "+ve to starboard, -ve to port",
40
- default: app.getSelfPath("sensors.depth.fromCenter.value"),
45
+ ...(fromCenter === undefined ? {} : { default: fromCenter }),
41
46
  },
42
47
  },
43
48
  },
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,iBAAiB;IACjB,WAAW;CACH,CAAC;AAEX,MAAM,UAAU,MAAM,CAAC,GAAc;IACnC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3C,GAAG,CAAC,WAAW,CAAC,qBAAqB,IAAI,QAAQ,CAAC,CACnD,CAAC;IACF,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,mIAAmI;QACrI,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,OAAO;gBACd,WAAW,EACT,sIAAsI;gBACxI,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE;oBACT,qBAAqB;oBACrB,wBAAwB;oBACxB,kBAAkB;iBACnB;gBACD,OAAO,EAAE,WAAW;aACrB;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EACT,sHAAsH;gBACxH,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;gBACpB,UAAU,EAAE;oBACV,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,kDAAkD;wBACzD,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,6BAA6B,CAAC;qBACxD;oBACD,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,qDAAqD;wBAC5D,WAAW,EAAE,+BAA+B;wBAC5C,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,gCAAgC,CAAC;qBAC3D;iBACF;aACF;YACD,oBAAoB,EAAE;gBACpB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,gCAAgC;gBACvC,WAAW,EACT,2UAA2U;gBAC7U,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;gBACxB,SAAS,EAAE,CAAC,KAAK,EAAE,wCAAwC,CAAC;gBAC5D,OAAO,EAAE,KAAK;aACf;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EACT,iQAAiQ;gBACnQ,UAAU,EAAE;oBACV,GAAG,EAAE;wBACH,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,+CAA+C;wBACtD,WAAW,EACT,wGAAwG;qBAC3G;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG;wBACZ,KAAK,EAAE,8BAA8B;wBACrC,WAAW,EACT,kGAAkG;qBACrG;iBACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,iBAAiB;IACjB,WAAW;CACH,CAAC;AAEX,MAAM,UAAU,MAAM,CAAC,GAAc;IACnC,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3C,GAAG,CAAC,WAAW,CAAC,qBAAqB,IAAI,QAAQ,CAAC,CACnD,CAAC;IACF,8EAA8E;IAC9E,6EAA6E;IAC7E,8CAA8C;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,gCAAgC,CAAC,CAAC;IACrE,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EACT,mIAAmI;QACrI,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,OAAO;gBACd,WAAW,EACT,sIAAsI;gBACxI,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE;oBACT,qBAAqB;oBACrB,wBAAwB;oBACxB,kBAAkB;iBACnB;gBACD,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;aAC/D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EACT,sHAAsH;gBACxH,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;gBACpB,UAAU,EAAE;oBACV,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,kDAAkD;wBACzD,OAAO,EAAE,CAAC;wBACV,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;qBACvD;oBACD,CAAC,EAAE;wBACD,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,qDAAqD;wBAC5D,WAAW,EAAE,+BAA+B;wBAC5C,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;qBAC7D;iBACF;aACF;YACD,oBAAoB,EAAE;gBACpB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,gCAAgC;gBACvC,WAAW,EACT,2UAA2U;gBAC7U,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;gBACxB,SAAS,EAAE,CAAC,KAAK,EAAE,wCAAwC,CAAC;gBAC5D,OAAO,EAAE,KAAK;aACf;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EACT,iQAAiQ;gBACnQ,UAAU,EAAE;oBACV,GAAG,EAAE;wBACH,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,+CAA+C;wBACtD,WAAW,EACT,wGAAwG;qBAC3G;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,GAAG;wBACZ,KAAK,EAAE,8BAA8B;wBACrC,WAAW,EACT,kGAAkG;qBACrG;iBACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /** The providing plugin's id; also the plotterExtensions resource key. */
2
+ export declare const PLUGIN_ID = "signalk-livedepth-plugin";
3
+ /** Top-level, non-admin route the extension's pages and data are served from. */
4
+ export declare const ASSET_BASE = "/plotterext/signalk-livedepth-plugin";
5
+ /** The plotterExtensions manifest (see docs/api/plotter-extensions-api.md). */
6
+ export interface PlotterExtManifest {
7
+ name: string;
8
+ description: string;
9
+ version: string;
10
+ apiVersion: string;
11
+ requires: string[];
12
+ optional: string[];
13
+ buttons: unknown[];
14
+ panels: unknown[];
15
+ background: unknown[];
16
+ overlays: unknown[];
17
+ }
18
+ /** Build the extension manifest offered to a host chartplotter.
19
+ *
20
+ * One `image` overlay, drawn by a headless background runtime, placed above
21
+ * the charts and below the vessel/resources. A `mapToolbar` button opens the
22
+ * settings panel, which shares state with the runtime over the bus. */
23
+ export declare function buildManifest(version?: string): PlotterExtManifest;
24
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/plotterext/manifest.ts"],"names":[],"mappings":"AAIA,0EAA0E;AAC1E,eAAO,MAAM,SAAS,6BAA6B,CAAC;AACpD,iFAAiF;AACjF,eAAO,MAAM,UAAU,yCAA6B,CAAC;AAErD,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAeD;;;;uEAIuE;AACvE,wBAAgB,aAAa,CAAC,OAAO,SAAkB,GAAG,kBAAkB,CAsD3E"}
@@ -0,0 +1,78 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /** The providing plugin's id; also the plotterExtensions resource key. */
5
+ export const PLUGIN_ID = "signalk-livedepth-plugin";
6
+ /** Top-level, non-admin route the extension's pages and data are served from. */
7
+ export const ASSET_BASE = `/plotterext/${PLUGIN_ID}`;
8
+ /** The plugin's own version, read from its package.json. */
9
+ function pluginVersion() {
10
+ try {
11
+ const here = dirname(fileURLToPath(import.meta.url));
12
+ const pkg = JSON.parse(readFileSync(join(here, "..", "..", "package.json"), "utf8"));
13
+ return pkg.version ?? "0.0.0";
14
+ }
15
+ catch {
16
+ return "0.0.0";
17
+ }
18
+ }
19
+ /** Build the extension manifest offered to a host chartplotter.
20
+ *
21
+ * One `image` overlay, drawn by a headless background runtime, placed above
22
+ * the charts and below the vessel/resources. A `mapToolbar` button opens the
23
+ * settings panel, which shares state with the runtime over the bus. */
24
+ export function buildManifest(version = pluginVersion()) {
25
+ return {
26
+ name: "LiveDepth",
27
+ description: "Draw your recorded depth as a live depth map on the chart, shaded with depth contours.",
28
+ version,
29
+ apiVersion: "1",
30
+ requires: ["background.iframe", "overlays.image", "signalk.stream"],
31
+ optional: ["buttons", "panels.iframe", "units", "map", "nightMode"],
32
+ buttons: [
33
+ {
34
+ id: "open-livedepth-settings",
35
+ title: "LiveDepth",
36
+ slot: "mapToolbar",
37
+ icon: "water",
38
+ action: { type: "togglePanel", panel: "livedepth-settings" },
39
+ },
40
+ ],
41
+ panels: [
42
+ {
43
+ id: "livedepth-settings",
44
+ title: "LiveDepth",
45
+ type: "iframe",
46
+ url: `${ASSET_BASE}/config.html`,
47
+ lifecycle: "keepAlive",
48
+ },
49
+ ],
50
+ background: [
51
+ {
52
+ id: "renderer",
53
+ type: "iframe",
54
+ url: `${ASSET_BASE}/renderer.html`,
55
+ },
56
+ ],
57
+ overlays: [
58
+ {
59
+ id: "depth",
60
+ title: "Live depth",
61
+ type: "image",
62
+ runtime: "renderer",
63
+ band: "aboveCharts",
64
+ visible: true,
65
+ opacity: 0.85,
66
+ minZoom: 4,
67
+ // The Chart list's "Layer settings" button opens this panel, so the
68
+ // layer's settings sit with the layer, not only behind the toolbar
69
+ // button.
70
+ configPanel: "livedepth-settings",
71
+ // Isobaths and labels want the pixels; the host still clamps to its own
72
+ // memory budget.
73
+ preferredPixelRatio: 2,
74
+ },
75
+ ],
76
+ };
77
+ }
78
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/plotterext/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,SAAS,GAAG,0BAA0B,CAAC;AACpD,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,SAAS,EAAE,CAAC;AAgBrD,4DAA4D;AAC5D,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACrC,CAAC;QAC1B,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;uEAIuE;AACvE,MAAM,UAAU,aAAa,CAAC,OAAO,GAAG,aAAa,EAAE;IACrD,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,wFAAwF;QAC1F,OAAO;QACP,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,CAAC;QACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC;QACnE,OAAO,EAAE;YACP;gBACE,EAAE,EAAE,yBAAyB;gBAC7B,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,oBAAoB,EAAE;aAC7D;SACF;QACD,MAAM,EAAE;YACN;gBACE,EAAE,EAAE,oBAAoB;gBACxB,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,GAAG,UAAU,cAAc;gBAChC,SAAS,EAAE,WAAW;aACvB;SACF;QACD,UAAU,EAAE;YACV;gBACE,EAAE,EAAE,UAAU;gBACd,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,GAAG,UAAU,gBAAgB;aACnC;SACF;QACD,QAAQ,EAAE;YACR;gBACE,EAAE,EAAE,OAAO;gBACX,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC;gBACV,oEAAoE;gBACpE,mEAAmE;gBACnE,UAAU;gBACV,WAAW,EAAE,oBAAoB;gBACjC,wEAAwE;gBACxE,iBAAiB;gBACjB,mBAAmB,EAAE,CAAC;aACvB;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ServerAPI } from "@signalk/server-api";
2
+ /** Offer the plotter extension: register the read-only `plotterExtensions`
3
+ * resource and mount the extension's pages. Safe to call on every start — the
4
+ * provider is registered and the assets mounted once; `isRunning` reflects the
5
+ * plugin's current state so the extension leaves when the plugin is disabled. */
6
+ export declare function registerPlotterExtension(app: ServerAPI, isRunning: () => boolean): void;
7
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/plotterext/provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAYrD;;;iFAGiF;AACjF,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,MAAM,OAAO,GACvB,IAAI,CAgCN"}
@@ -0,0 +1,61 @@
1
+ import { createRequire } from "node:module";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { ASSET_BASE, PLUGIN_ID, buildManifest } from "./manifest.js";
5
+ let registered = false;
6
+ let mounted = false;
7
+ /** Offer the plotter extension: register the read-only `plotterExtensions`
8
+ * resource and mount the extension's pages. Safe to call on every start — the
9
+ * provider is registered and the assets mounted once; `isRunning` reflects the
10
+ * plugin's current state so the extension leaves when the plugin is disabled. */
11
+ export function registerPlotterExtension(app, isRunning) {
12
+ const a = app;
13
+ if (!registered) {
14
+ if (typeof a.registerResourceProvider === "function") {
15
+ a.registerResourceProvider({
16
+ type: "plotterExtensions",
17
+ methods: {
18
+ listResources: async () => isRunning() ? { [PLUGIN_ID]: buildManifest() } : {},
19
+ getResource: async (id) => {
20
+ if (!isRunning() || id !== PLUGIN_ID) {
21
+ throw new Error(`No such plotterExtensions resource: ${id}`);
22
+ }
23
+ return buildManifest();
24
+ },
25
+ setResource: async () => {
26
+ throw new Error(`${PLUGIN_ID} is a read-only provider`);
27
+ },
28
+ deleteResource: async () => {
29
+ throw new Error(`${PLUGIN_ID} is a read-only provider`);
30
+ },
31
+ },
32
+ });
33
+ registered = true;
34
+ a.debug(`${PLUGIN_ID}: plotter extension offered`);
35
+ }
36
+ else {
37
+ a.debug(`${PLUGIN_ID}: server has no resource provider registry`);
38
+ }
39
+ }
40
+ mountAssets(a);
41
+ }
42
+ /** Serve the extension's pages as a top-level static route. Express is provided
43
+ * by the server, so requiring it adds no runtime dependency of our own. */
44
+ function mountAssets(app) {
45
+ if (mounted || typeof app.use !== "function") {
46
+ return;
47
+ }
48
+ let serveStatic;
49
+ try {
50
+ serveStatic = createRequire(import.meta.url)("express").static;
51
+ }
52
+ catch {
53
+ app.debug(`${PLUGIN_ID}: express unavailable; cannot serve ${ASSET_BASE}`);
54
+ return;
55
+ }
56
+ const here = dirname(fileURLToPath(import.meta.url));
57
+ app.use(ASSET_BASE, serveStatic(join(here, "..", "..", "public")));
58
+ mounted = true;
59
+ app.debug(`${PLUGIN_ID}: extension assets served at ${ASSET_BASE}`);
60
+ }
61
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/plotterext/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAQrE,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB;;;iFAGiF;AACjF,MAAM,UAAU,wBAAwB,CACtC,GAAc,EACd,SAAwB;IAExB,MAAM,CAAC,GAAG,GAAmB,CAAC;IAE9B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,CAAC,wBAAwB,KAAK,UAAU,EAAE,CAAC;YACrD,CAAC,CAAC,wBAAwB,CAAC;gBACzB,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE;oBACP,aAAa,EAAE,KAAK,IAAI,EAAE,CACxB,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;oBACrD,WAAW,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;wBAChC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;4BACrC,MAAM,IAAI,KAAK,CAAC,uCAAuC,EAAE,EAAE,CAAC,CAAC;wBAC/D,CAAC;wBACD,OAAO,aAAa,EAAE,CAAC;oBACzB,CAAC;oBACD,WAAW,EAAE,KAAK,IAAI,EAAE;wBACtB,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,0BAA0B,CAAC,CAAC;oBAC1D,CAAC;oBACD,cAAc,EAAE,KAAK,IAAI,EAAE;wBACzB,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,0BAA0B,CAAC,CAAC;oBAC1D,CAAC;iBACF;aACF,CAAC,CAAC;YACH,UAAU,GAAG,IAAI,CAAC;YAClB,CAAC,CAAC,KAAK,CAAC,GAAG,SAAS,6BAA6B,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,CAAC,CAAC,KAAK,CAAC,GAAG,SAAS,4CAA4C,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,WAAW,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED;2EAC2E;AAC3E,SAAS,WAAW,CAAC,GAAiB;IACpC,IAAI,OAAO,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,IAAI,WAAmD,CAAC;IACxD,IAAI,CAAC;QACH,WAAW,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,MAE5C,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,uCAAuC,UAAU,EAAE,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,GAAG,IAAI,CAAC;IACf,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,gCAAgC,UAAU,EAAE,CAAC,CAAC;AACtE,CAAC"}
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,12 @@
1
1
  import { ServerAPI, Plugin } from "@signalk/server-api";
2
+ /** The vessel's length overall, for locating the reference point the server
3
+ * reports (the CCRP is midships).
4
+ *
5
+ * `design.length` is a compound-value node — `{ value: { overall, hull,
6
+ * waterline } }` — not a leaf, and `getSelfPath` is a `lodash.get` over the raw
7
+ * self model, so `design.length.overall` resolves to nothing. Read the node and
8
+ * take `.value.overall` (matching how the server's own GNSS corrector reads it).
9
+ * Handles `getSelfPath` returning either the value or its node. */
10
+ export declare function readLengthOverall(app: ServerAPI): number | undefined;
2
11
  export default function createPlugin(app: ServerAPI): Plugin;
3
12
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAuEtE,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAwG3D"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAgBtE;;;;;;;mEAOmE;AACnE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAWpE;AA+CD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAqH3D"}
package/dist/plugin.js CHANGED
@@ -3,16 +3,25 @@ import { schema } from "./config.js";
3
3
  import { createTileDB, createTileStore } from "./tiles/store.js";
4
4
  import { createTileWriter } from "./tiles/writer.js";
5
5
  import { seedFromHistory } from "./tiles/seed.js";
6
- import { registerBathymetryRoutes, } from "./tiles/api.js";
6
+ import { registerBathymetryRoutes, registerSeedRoutes, } from "./tiles/api.js";
7
+ import { registerPlotterExtension } from "./plotterext/provider.js";
7
8
  import { createCollector } from "./collector.js";
8
9
  /** The vessel's length overall, for locating the reference point the server
9
- * reports (the CCRP is midships). Handles `getSelfPath` returning either the
10
- * value or its node. */
11
- function readLengthOverall(app) {
12
- const node = app.getSelfPath("design.length.overall");
10
+ * reports (the CCRP is midships).
11
+ *
12
+ * `design.length` is a compound-value node — `{ value: { overall, hull,
13
+ * waterline } }` — not a leaf, and `getSelfPath` is a `lodash.get` over the raw
14
+ * self model, so `design.length.overall` resolves to nothing. Read the node and
15
+ * take `.value.overall` (matching how the server's own GNSS corrector reads it).
16
+ * Handles `getSelfPath` returning either the value or its node. */
17
+ export function readLengthOverall(app) {
18
+ const node = app.getSelfPath("design.length");
13
19
  const value = typeof node === "number" ? node : node?.value;
14
- return typeof value === "number" && Number.isFinite(value)
20
+ const overall = typeof value === "number"
15
21
  ? value
22
+ : value?.overall;
23
+ return typeof overall === "number" && Number.isFinite(overall) && overall > 0
24
+ ? overall
16
25
  : undefined;
17
26
  }
18
27
  /** The server's GNSS antenna correction mode; `off` unless configured. */
@@ -59,6 +68,8 @@ export default function createPlugin(app) {
59
68
  let config;
60
69
  let transducer;
61
70
  let seedStatus = { running: false };
71
+ let running = false;
72
+ let routesRegistered = false;
62
73
  const runSeed = async (resolution) => {
63
74
  if (seedStatus.running)
64
75
  return;
@@ -108,6 +119,17 @@ export default function createPlugin(app) {
108
119
  signal: abortController.signal,
109
120
  });
110
121
  app.setPluginStatus("Collecting depth into the bathymetry tile store");
122
+ running = true;
123
+ // Offer the chart layer to a host chartplotter, and serve the store the
124
+ // layer reads from a top-level, non-admin route.
125
+ registerPlotterExtension(app, () => running);
126
+ if (!routesRegistered) {
127
+ registerBathymetryRoutes(app, () => tileStore, () => ({
128
+ depthPath: config ? `environment.depth.${config.path}` : undefined,
129
+ transducer,
130
+ }));
131
+ routesRegistered = true;
132
+ }
111
133
  if (startConfig.seed?.run) {
112
134
  // One-time rebuild. Clear the trigger when it finishes (or fails) so it
113
135
  // doesn't fire again on the next start; an interrupted run resumes from
@@ -119,6 +141,7 @@ export default function createPlugin(app) {
119
141
  }
120
142
  },
121
143
  stop() {
144
+ running = false;
122
145
  abortController?.abort("Stopping signalk-livedepth-plugin");
123
146
  tileStore?.close();
124
147
  tileStore = undefined;
@@ -127,10 +150,9 @@ export default function createPlugin(app) {
127
150
  return schema(app);
128
151
  },
129
152
  registerWithRouter(router) {
130
- registerBathymetryRoutes(router, () => tileStore, () => ({
131
- depthPath: config ? `environment.depth.${config.path}` : undefined,
132
- transducer,
133
- }), seed);
153
+ // The one-time seed trigger stays admin-only, on the plugin's own router;
154
+ // the store the extension reads is served from the top-level route above.
155
+ registerSeedRoutes(router, seed);
134
156
  },
135
157
  };
136
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAU,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACL,wBAAwB,EACxB,kBAAkB,GAGnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;mEAOmE;AACnE,MAAM,UAAU,iBAAiB,CAAC,GAAc;IAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,eAAe,CACoB,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;IAC5D,MAAM,OAAO,GACX,OAAO,KAAK,KAAK,QAAQ;QACvB,CAAC,CAAC,KAAK;QACP,CAAC,CAAE,KAA0C,EAAE,OAAO,CAAC;IAC3D,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;QAC3E,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,0EAA0E;AAC1E,SAAS,kBAAkB,CAAC,GAAc;IACxC,mDAAmD;IACnD,OAAO,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,IAAI,KAAK,CAAC;AACvD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,uBAAuB,CAC9B,GAAc,EACd,MAAc;IAEd,IAAI,MAAM,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,kBAAkB,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;QACtC,GAAG,CAAC,cAAc,CAChB,0EAA0E;YACxE,uEAAuE;YACvE,uEAAuE;YACvE,2BAA2B,CAC9B,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,GAAG,CAAC,cAAc,CAChB,0DAA0D;YACxD,uEAAuE;YACvE,qCAAqC,CACxC,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC;QAC9C,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAc;IACjD,IAAI,eAAe,GAAgC,SAAS,CAAC;IAC7D,2EAA2E;IAC3E,6CAA6C;IAC7C,IAAI,SAAgC,CAAC;IACrC,IAAI,MAA0B,CAAC;IAC/B,IAAI,UAAwC,CAAC;IAC7C,IAAI,UAAU,GAAe,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAChD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,MAAM,OAAO,GAAG,KAAK,EAAE,UAAmB,EAAiB,EAAE;QAC3D,IAAI,UAAU,CAAC,OAAO;YAAE,OAAO;QAC/B,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC;QACnB,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG;YAAE,OAAO;QAE3B,UAAU,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/B,GAAG,CAAC,eAAe,CAAC,2CAA2C,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC;gBACrC,GAAG;gBACH,KAAK;gBACL,MAAM,EAAE,GAAG;gBACX,UAAU;gBACV,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,eAAe,EAAE,MAAM;gBAC/B,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;oBAChB,UAAU,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;oBAC/C,GAAG,CAAC,eAAe,CACjB,gCAAgC,CAAC,CAAC,MAAM,gBAAgB,CAAC,CAAC,MAAM,UAAU,CAC3E,CAAC;gBACJ,CAAC;aACF,CAAC,CAAC;YACH,UAAU,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YAC1C,GAAG,CAAC,eAAe,CACjB,gCAAgC,QAAQ,CAAC,MAAM,SAAS,CACzD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,cAAc,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,IAAI,GAAe,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC;IAEpE,OAAO;QACL,EAAE,EAAE,0BAA0B;QAC9B,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,8HAA8H;QAEhI,KAAK,CAAC,KAAK,CAAC,WAAmB,EAAE,OAAiC;YAChE,MAAM,GAAG,WAAW,CAAC;YACrB,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAE/C,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;YACxC,SAAS,GAAG,eAAe,CACzB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,yBAAyB,CAAC,CAAC,CACpE,CAAC;YACF,UAAU,GAAG,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAElD,eAAe,CAAC;gBACd,GAAG;gBACH,MAAM;gBACN,MAAM,EAAE,gBAAgB,CAAC,SAAS,CAAC;gBACnC,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,eAAe,CAAC,MAAM;aAC/B,CAAC,CAAC;YACH,GAAG,CAAC,eAAe,CAAC,iDAAiD,CAAC,CAAC;YAEvE,OAAO,GAAG,IAAI,CAAC;YACf,wEAAwE;YACxE,iDAAiD;YACjD,wBAAwB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,wBAAwB,CACtB,GAAG,EACH,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,CAAC;oBACL,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;oBAClE,UAAU;iBACX,CAAC,CACH,CAAC;gBACF,gBAAgB,GAAG,IAAI,CAAC;YAC1B,CAAC;YAED,IAAI,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;gBAC1B,wEAAwE;gBACxE,wEAAwE;gBACxE,0CAA0C;gBAC1C,KAAK,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAClD,OAAO,CAAC;oBACN,GAAG,WAAW;oBACd,IAAI,EAAE,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE;iBAC1C,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAI;YACF,OAAO,GAAG,KAAK,CAAC;YAChB,eAAe,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAC5D,SAAS,EAAE,KAAK,EAAE,CAAC;YACnB,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC;QAED,MAAM;YACJ,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,kBAAkB,CAAC,MAAoB;YACrC,0EAA0E;YAC1E,0EAA0E;YAC1E,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { ServerAPI } from "@signalk/server-api";
2
2
  import { PassThrough } from "stream";
3
- import { TransducerOffset } from "signalk-livedepth-tiles";
3
+ import { TransducerOffset } from "../tiles/core/index.js";
4
4
  import { Config } from "../config.js";
5
5
  /**
6
6
  * Subscribe to the vessel's own depth and pair each sounding with the last
@@ -1 +1 @@
1
- {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/streams/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAuB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,eAyE1B"}
1
+ {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/streams/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAuB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,eAyE1B"}