signalk-container-helper 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -438,6 +438,8 @@ Adopt these even where you don't use the components:
438
438
  | `getContainerManager()` | Read the `globalThis.__signalk_containerManager` global |
439
439
  | `waitForContainerManager(opts)` | Two-phase wait (manager present → runtime settled); returns `{ manager, runtime }` so the two failure modes get distinct messages |
440
440
  | `waitForHttpReady(url, opts)` | Poll until 2xx or deadline (throws) |
441
+ | `retryForever(fn, opts)` | Retry until success — 15s doubling to a 120s ceiling, no attempt cap. `ManagedContainer` takes it as `readinessRetry`; exported standalone for work this library does not manage |
442
+ | `anySignal(signals)` | Compose several `AbortSignal`s into one that aborts when any does (`undefined` when none are given) |
441
443
  | `probeHttpHealth(url, opts)` | Retrying liveness probe with slow-response detection (never throws) |
442
444
  | `fetchWithTimeout(url, opts)` | `fetch` with an `AbortController` timeout |
443
445
  | `throwIfAborted(signal)` | Throw `ContainerHelperError` `cancelled` if the signal has fired — the check the lifecycle methods run between steps |
@@ -451,15 +453,16 @@ Adopt these even where you don't use the components:
451
453
 
452
454
  `ContainerHelperError.code` values thrown by `start()` / `applyUpdate()`:
453
455
 
454
- | Code | Meaning |
455
- | --------------------- | --------------------------------------------------------------------------------------------------------- |
456
- | `manager-unavailable` | signalk-container never published its API within the budget |
457
- | `no-runtime` | Manager present, but no podman/docker was detected |
458
- | `invalid-tag` | Tag failed the `IMAGE_TAG_PATTERN` guard |
459
- | `address-unresolved` | No host:port could be found for the readiness port |
460
- | `not-ready` | The app never answered its health URL before the deadline |
461
- | `recreate-limbo` | Legacy update path removed the container but recreation failed — retry applies |
462
- | `cancelled` | The `AbortSignal` passed to the operation fired (see [Cancelling an operation](#cancelling-an-operation)) |
456
+ | Code | Meaning |
457
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
458
+ | `manager-unavailable` | signalk-container never published its API within the budget |
459
+ | `no-runtime` | Manager present, but no podman/docker was detected |
460
+ | `invalid-tag` | Tag failed the `IMAGE_TAG_PATTERN` guard |
461
+ | `address-unresolved` | No host:port could be found for the readiness port |
462
+ | `not-ready` | The app never answered its health URL before the deadline |
463
+ | `recreate-limbo` | Legacy update path removed the container but recreation failed — retry applies |
464
+ | `cancelled` | The `AbortSignal` passed to the operation fired, or a newer lifecycle operation superseded a retrying `start()` (see [Cancelling an operation](#cancelling-an-operation)) |
465
+ | `invalid-option` | An option could not produce sane behaviour — e.g. a non-finite or negative `retryForever` delay bound |
463
466
 
464
467
  All errors thrown by the helpers have already been surfaced through
465
468
  `app.setPluginError` (`reported: true`), so `startSafely` won't report them twice.
@@ -506,6 +509,54 @@ readiness — queue rather than interleave, so `stop` can no longer land between
506
509
  started something it just removed. Callers that already hold their own
507
510
  lifecycle lock see no change.
508
511
 
512
+ ### Retrying forever
513
+
514
+ `start()` throws once when bring-up fails, which is right for a plugin that
515
+ reports the problem and waits for a human. Where no human may be coming, pass
516
+ `readinessRetry`:
517
+
518
+ ```ts
519
+ const container = new ManagedContainer({
520
+ // …
521
+ readinessRetry: {
522
+ onAttemptFailed: (err, nextDelayMs) =>
523
+ app.setPluginError(
524
+ `Backup server unreachable: ${errMsg(err)} — retrying in ${Math.round(nextDelayMs / 1000)}s`,
525
+ ),
526
+ },
527
+ });
528
+
529
+ // Resolves only on success; rejects on cancellation, on an invalid delay
530
+ // bound, or if your onAttemptFailed callback itself throws.
531
+ const { address } = await container.start(tag, { signal });
532
+ ```
533
+
534
+ `start()` then retries the whole bring-up — 15s doubling to a 120s ceiling,
535
+ indefinitely. A container that lost a boot race should not stay down until
536
+ someone restarts the plugin; on a boat that can be weeks. Each attempt re-runs
537
+ `start()` whole, which is safe because `ensureRunning` is idempotent, and
538
+ necessary because a container that only just came up may bind a different host
539
+ port than the last attempt saw.
540
+
541
+ Use `onAttemptFailed` to keep the status line honest — the returned promise
542
+ stays pending either way, so without it an operator cannot tell "still
543
+ retrying" from "stuck".
544
+
545
+ Pair it with a `signal`: cancellation is the only exit besides success. Both
546
+ the per-call `signal` and `readinessRetry.signal` are honoured — aborting
547
+ either ends the loop, and an abort during a backoff settles immediately rather
548
+ than waiting the delay out.
549
+
550
+ Each attempt is serialized individually rather than the loop as a whole, so a
551
+ retry sleeping between attempts never blocks `stop()`. A later lifecycle
552
+ operation also retires the loop: a `start()` still retrying an old tag stands
553
+ down when `applyUpdate()` or `stop()` runs, instead of restarting the container
554
+ on the image the operator just moved away from.
555
+
556
+ `retryForever` is exported on its own for the same policy applied to work this
557
+ library does not manage — an external service a plugin points at but does not
558
+ own, for instance.
559
+
509
560
  ### Version compatibility
510
561
 
511
562
  The helpers feature-detect newer signalk-container capabilities:
@@ -550,9 +601,9 @@ This library is distributed through **npm with semver** — consumers `npm insta
550
601
 
551
602
  Releases are tag-triggered (`.github/workflows/publish.yml` fires on `v*` tags):
552
603
 
553
- 1. Bump `version` in `package.json`, add a matching `# vX.Y.Z` section to `CHANGELOG.md`, commit, and merge to `master`.
604
+ 1. Bump `version` in `package.json`, commit, and merge to `master`.
554
605
  2. Run `npm run release` — it tags `v<version>` and pushes the tag.
555
- 3. The workflow extracts that version's CHANGELOG.md section as the GitHub Release notes (and fails if the section is missing), then builds, tests, and runs `npm publish --provenance` (tags containing `alpha`/`beta`/`rc` publish under the matching dist-tag).
606
+ 3. The workflow creates a GitHub Release whose notes are generated from the PRs merged since the previous tag (grouped by `.github/release.yml`), then builds, tests, and runs `npm publish --provenance` (tags containing `alpha`/`beta`/`rc` publish under the matching dist-tag).
556
607
 
557
608
  Publishing uses [npm trusted publishing](https://docs.npmjs.com/trusted-publishers) (OIDC) — no npm token secret, but the package must list this repo's workflow as a trusted publisher on npmjs.com.
558
609
 
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export { AdoptedContainer } from "./adopted-container.js";
7
7
  export type { AdoptedContainerOptions } from "./adopted-container.js";
8
8
  export { buildVersionSource } from "./version-source.js";
9
9
  export type { VersionSourceSpec } from "./version-source.js";
10
+ export { retryForever, anySignal } from "./retry.js";
11
+ export type { RetryForeverOptions } from "./retry.js";
10
12
  export { fetchWithTimeout, waitForHttpReady, probeHttpHealth } from "./http.js";
11
13
  export type { FetchLike, FetchWithTimeoutOptions, WaitForHttpReadyOptions, ProbeHttpHealthOptions, HealthProbeResult, } from "./http.js";
12
14
  export { startSafely, throwIfAborted, errMsg, isValidImageTag, IMAGE_TAG_PATTERN, ContainerHelperError, } from "./util.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5E,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EACV,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChF,YAAY,EACV,SAAS,EACT,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5E,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EACV,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChF,YAAY,EACV,SAAS,EACT,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { getContainerManager, waitForContainerManager } from "./manager.js";
3
3
  export { ManagedContainer } from "./managed-container.js";
4
4
  export { AdoptedContainer } from "./adopted-container.js";
5
5
  export { buildVersionSource } from "./version-source.js";
6
+ export { retryForever, anySignal } from "./retry.js";
6
7
  export { fetchWithTimeout, waitForHttpReady, probeHttpHealth } from "./http.js";
7
8
  export { startSafely, throwIfAborted, errMsg, isValidImageTag, IMAGE_TAG_PATTERN, ContainerHelperError, } from "./util.js";
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQhF,OAAO,EACL,WAAW,EACX,cAAc,EACd,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQhF,OAAO,EACL,WAAW,EACX,cAAc,EACd,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,WAAW,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type { AppLike, ContainerConfig, ContainerManagerApi, ContainerState, EnsureRunningOptions, UpdateCheckResult } from "./types.js";
2
2
  import { type VersionSourceSpec } from "./version-source.js";
3
3
  import { type FetchLike } from "./http.js";
4
+ import { type RetryForeverOptions } from "./retry.js";
4
5
  export interface ReadinessOptions {
5
6
  /**
6
7
  * Container port to reach the app on — must also be declared in the
@@ -56,6 +57,21 @@ export interface ManagedContainerOptions {
56
57
  managerPollIntervalMs?: number;
57
58
  /** HTTP readiness of the app inside the container (optional). */
58
59
  readiness?: ReadinessOptions;
60
+ /**
61
+ * Retry the whole bring-up indefinitely instead of throwing on the first
62
+ * failure. Off by default: throwing once is the right shape for a plugin
63
+ * that reports and waits for a human.
64
+ *
65
+ * Set it when nobody may be available to restart the plugin — the boat case,
66
+ * where a transient boot race would otherwise leave the container down for
67
+ * weeks. `start()` then resolves only on success or rejects on cancellation,
68
+ * so pair it with `signal` and report progress via `onAttemptFailed`.
69
+ *
70
+ * Each attempt re-runs `start()` whole: `ensureRunning` is idempotent, and
71
+ * the address is re-resolved every time because a container that only just
72
+ * came up may bind a different host port.
73
+ */
74
+ readinessRetry?: RetryForeverOptions;
59
75
  /** Register with signalk-container's update-detection service (optional). */
60
76
  updates?: ManagedUpdateOptions;
61
77
  /** Passed through to ensureRunning/recreate (onVolumeIssue, logs, …). */
@@ -129,6 +145,12 @@ export declare class ManagedContainer {
129
145
  * Every consumer plugin had built its own lock for this; it belongs here.
130
146
  */
131
147
  private chain;
148
+ /**
149
+ * Bumped by every lifecycle operation. A retrying `start()` captures the
150
+ * value it began with and stands down once it no longer matches, so a stop
151
+ * or an update retires the loop instead of racing it.
152
+ */
153
+ private lifecycle;
132
154
  constructor(options: ManagedContainerOptions);
133
155
  /**
134
156
  * Queue `fn` behind any operation already in flight. Both settlement paths
@@ -1 +1 @@
1
- {"version":3,"file":"managed-container.d.ts","sourceRoot":"","sources":["../src/managed-container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"managed-container.d.ts","sourceRoot":"","sources":["../src/managed-container.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { getContainerManager, waitForContainerManager } from "./manager.js";
2
2
  import { buildVersionSource, } from "./version-source.js";
3
3
  import { waitForHttpReady } from "./http.js";
4
+ import { anySignal, retryForever } from "./retry.js";
4
5
  import { ContainerHelperError, errMsg, isValidImageTag, throwIfAborted, } from "./util.js";
5
6
  /**
6
7
  * Full lifecycle wrapper for a plugin-owned ("managed") container — the
@@ -22,6 +23,12 @@ export class ManagedContainer {
22
23
  * Every consumer plugin had built its own lock for this; it belongs here.
23
24
  */
24
25
  chain = Promise.resolve();
26
+ /**
27
+ * Bumped by every lifecycle operation. A retrying `start()` captures the
28
+ * value it began with and stands down once it no longer matches, so a stop
29
+ * or an update retires the loop instead of racing it.
30
+ */
31
+ lifecycle = 0;
25
32
  constructor(options) {
26
33
  this.options = options;
27
34
  }
@@ -114,7 +121,25 @@ export class ManagedContainer {
114
121
  * `startSafely` in a synchronous plugin.start().
115
122
  */
116
123
  async start(tag, options) {
117
- return this.serialize(() => this.startInner(tag, options?.signal));
124
+ const retry = this.options.readinessRetry;
125
+ if (!retry) {
126
+ return this.serialize(() => this.startInner(tag, options?.signal));
127
+ }
128
+ // Compose rather than choose: `readinessRetry.signal` is the instance-wide
129
+ // kill switch and `options.signal` cancels this call, so honouring only
130
+ // one silently ignores whichever the caller did not pass here.
131
+ const signal = anySignal([options?.signal, retry.signal]);
132
+ // A retry loop outlives the call that started it, so a later operation
133
+ // must be able to retire it. Without this, a start() still retrying an old
134
+ // tag keeps calling ensureRunning with that tag after applyUpdate() moved
135
+ // the container to a new one — silently reverting the operator's update.
136
+ const generation = ++this.lifecycle;
137
+ return retryForever(() => this.serialize(() => {
138
+ if (generation !== this.lifecycle) {
139
+ throw new ContainerHelperError("cancelled", "Superseded by a newer lifecycle operation.", true);
140
+ }
141
+ return this.startInner(tag, signal);
142
+ }), { ...retry, signal });
118
143
  }
119
144
  async startInner(tag, signal) {
120
145
  const { name, image, buildConfig, ensureOptions, managerTimeoutMs = 120_000, managerPollIntervalMs = 500, } = this.options;
@@ -268,6 +293,8 @@ export class ManagedContainer {
268
293
  * instantly without a pull. Never throws.
269
294
  */
270
295
  async stop() {
296
+ // Retires any retry loop still running; see the `lifecycle` field.
297
+ this.lifecycle++;
271
298
  return this.serialize(() => this.stopInner());
272
299
  }
273
300
  async stopInner() {
@@ -302,6 +329,9 @@ export class ManagedContainer {
302
329
  * re-resolved afterwards (non-fatal on failure).
303
330
  */
304
331
  async applyUpdate(tag, options) {
332
+ // A pending retry of the previous tag must not outlive this update and
333
+ // restart the container on the image the operator just moved away from.
334
+ this.lifecycle++;
305
335
  return this.serialize(() => this.applyUpdateInner(tag, options?.signal));
306
336
  }
307
337
  async applyUpdateInner(tag, signal) {
@@ -1 +1 @@
1
- {"version":3,"file":"managed-container.js","sourceRoot":"","sources":["../src/managed-container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"managed-container.js","sourceRoot":"","sources":["../src/managed-container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ export interface RetryForeverOptions {
2
+ /** First delay after a failure. Default 15_000. */
3
+ minDelayMs?: number;
4
+ /** Ceiling the doubling backoff saturates at. Default 120_000. */
5
+ maxDelayMs?: number;
6
+ /**
7
+ * Ends the loop. Rejects with `ContainerHelperError` code `"cancelled"`,
8
+ * already flagged reported so `startSafely` logs it instead of surfacing a
9
+ * plugin error for a stop the caller asked for.
10
+ */
11
+ signal?: AbortSignal;
12
+ /**
13
+ * Called after each failed attempt, before sleeping. This is where a
14
+ * consumer keeps its status line truthful while the loop runs — typically
15
+ * `setPluginError(\`… ${errMsg(err)} — retrying in ${nextDelayMs / 1000}s\`)`.
16
+ *
17
+ * Without it the caller has no way to distinguish "still retrying" from
18
+ * "stuck", since the returned promise stays pending either way. Throwing
19
+ * from this callback aborts the loop and propagates.
20
+ */
21
+ onAttemptFailed?: (err: unknown, nextDelayMs: number, attempt: number) => void;
22
+ }
23
+ /**
24
+ * One signal that aborts when any input does.
25
+ *
26
+ * Hand-rolled rather than `AbortSignal.any()`: v0.3.0 lowered the Node floor
27
+ * to 22 on the basis that this library touches no newer API, and reaching for
28
+ * one here would quietly walk that back.
29
+ *
30
+ * Returns the sole signal when only one is given (nothing to compose), and
31
+ * `undefined` when none is — so the common single-signal path allocates
32
+ * nothing.
33
+ */
34
+ export declare function anySignal(signals: Array<AbortSignal | undefined>): AbortSignal | undefined;
35
+ /**
36
+ * Run `fn` until it succeeds, backing off from `minDelayMs`, doubling to a
37
+ * `maxDelayMs` ceiling, retrying indefinitely.
38
+ *
39
+ * A container that lost a boot race should not stay broken until a human
40
+ * restarts the plugin. On a boat that human can be weeks away, so "give up and
41
+ * report" is the wrong terminal state for a transient failure — the plugin
42
+ * should still be trying when someone finally looks at it. That is why this
43
+ * has no attempt cap: the only exits are success and cancellation.
44
+ *
45
+ * The caller supplies the unit of work, so this composes with anything —
46
+ * `ManagedContainer.start()` for the container case, or a bare HTTP probe for
47
+ * a plugin pointed at a service it does not manage.
48
+ */
49
+ export declare function retryForever<T>(fn: () => Promise<T>, options?: RetryForeverOptions): Promise<T>;
50
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,CAChB,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,KACZ,IAAI,CAAC;CACX;AA8CD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,GACtC,WAAW,GAAG,SAAS,CA8BzB;AAkBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,CAAC,CAAC,CAiCZ"}
package/dist/retry.js ADDED
@@ -0,0 +1,135 @@
1
+ import { ContainerHelperError, throwIfAborted } from "./util.js";
2
+ /**
3
+ * Sleep that does not hold the process open.
4
+ *
5
+ * Deliberately not the shared `sleep` from util.ts: a retry loop that never
6
+ * gives up will almost always have a pending timer when Signal K shuts down,
7
+ * and a ref'd timer would keep the process alive waiting for a retry of
8
+ * something nobody is listening to any more.
9
+ */
10
+ function unrefSleep(ms, signal) {
11
+ return new Promise((resolve, reject) => {
12
+ const cancelled = () => new ContainerHelperError("cancelled", "Operation cancelled by the caller.", true);
13
+ // Already aborted: `addEventListener` would never fire, so the sleep would
14
+ // run to completion against a signal that is already dead. Reached when
15
+ // something between the loop's abort check and here aborts — notably an
16
+ // `onAttemptFailed` callback that gives up.
17
+ if (signal?.aborted) {
18
+ reject(cancelled());
19
+ return;
20
+ }
21
+ const timer = setTimeout(() => {
22
+ signal?.removeEventListener("abort", onAbort);
23
+ resolve();
24
+ }, ms);
25
+ // Node-only; a browser/edge runtime returns a plain number.
26
+ timer.unref?.();
27
+ // Without this the backoff runs to completion before the loop notices the
28
+ // abort — a `stop()` during a retry would stall for up to the full ceiling
29
+ // delay, which is exactly the wait cancellation exists to cut short.
30
+ function onAbort() {
31
+ clearTimeout(timer);
32
+ reject(cancelled());
33
+ }
34
+ if (signal)
35
+ signal.addEventListener("abort", onAbort, { once: true });
36
+ });
37
+ }
38
+ /**
39
+ * One signal that aborts when any input does.
40
+ *
41
+ * Hand-rolled rather than `AbortSignal.any()`: v0.3.0 lowered the Node floor
42
+ * to 22 on the basis that this library touches no newer API, and reaching for
43
+ * one here would quietly walk that back.
44
+ *
45
+ * Returns the sole signal when only one is given (nothing to compose), and
46
+ * `undefined` when none is — so the common single-signal path allocates
47
+ * nothing.
48
+ */
49
+ export function anySignal(signals) {
50
+ // Deduplicate: the same signal passed twice would overwrite its own entry in
51
+ // `handlers` below, leaking the listener the second registration replaced.
52
+ const present = [
53
+ ...new Set(signals.filter((s) => s !== undefined)),
54
+ ];
55
+ if (present.length === 0)
56
+ return undefined;
57
+ if (present.length === 1)
58
+ return present[0];
59
+ const controller = new AbortController();
60
+ // Check every signal before registering any listener, so an already-aborted
61
+ // one short-circuits without leaving listeners attached to its siblings.
62
+ const already = present.find((s) => s.aborted);
63
+ if (already) {
64
+ controller.abort(already.reason);
65
+ return controller.signal;
66
+ }
67
+ const handlers = new Map();
68
+ const abort = (reason) => {
69
+ for (const [s, handler] of handlers)
70
+ s.removeEventListener("abort", handler);
71
+ controller.abort(reason);
72
+ };
73
+ for (const s of present) {
74
+ const handler = () => abort(s.reason);
75
+ handlers.set(s, handler);
76
+ s.addEventListener("abort", handler, { once: true });
77
+ }
78
+ return controller.signal;
79
+ }
80
+ /**
81
+ * Reject a delay bound that could not produce a sane backoff.
82
+ *
83
+ * `setTimeout(NaN)` fires on the next tick, so an unvalidated NaN turns the
84
+ * loop into a hot spin against the container runtime rather than a backoff.
85
+ */
86
+ function requireDelay(name, value) {
87
+ if (!Number.isFinite(value) || value < 0) {
88
+ throw new ContainerHelperError("invalid-option", `${name} must be a non-negative finite number, got ${String(value)}`);
89
+ }
90
+ return value;
91
+ }
92
+ /**
93
+ * Run `fn` until it succeeds, backing off from `minDelayMs`, doubling to a
94
+ * `maxDelayMs` ceiling, retrying indefinitely.
95
+ *
96
+ * A container that lost a boot race should not stay broken until a human
97
+ * restarts the plugin. On a boat that human can be weeks away, so "give up and
98
+ * report" is the wrong terminal state for a transient failure — the plugin
99
+ * should still be trying when someone finally looks at it. That is why this
100
+ * has no attempt cap: the only exits are success and cancellation.
101
+ *
102
+ * The caller supplies the unit of work, so this composes with anything —
103
+ * `ManagedContainer.start()` for the container case, or a bare HTTP probe for
104
+ * a plugin pointed at a service it does not manage.
105
+ */
106
+ export async function retryForever(fn, options = {}) {
107
+ const { minDelayMs = 15_000, maxDelayMs = 120_000, signal, onAttemptFailed, } = options;
108
+ // Validate before the first attempt: a bad bound must fail loudly here
109
+ // rather than silently becoming a hot spin somewhere inside the loop.
110
+ requireDelay("minDelayMs", minDelayMs);
111
+ requireDelay("maxDelayMs", maxDelayMs);
112
+ // A caller that passes min > max means the ceiling; clamping beats doubling
113
+ // past it forever.
114
+ const ceiling = Math.max(minDelayMs, maxDelayMs);
115
+ let delay = minDelayMs;
116
+ for (let attempt = 1;; attempt++) {
117
+ throwIfAborted(signal);
118
+ try {
119
+ return await fn();
120
+ }
121
+ catch (err) {
122
+ // A cancelled attempt is the caller's own doing — surface it rather than
123
+ // treating it as a failure worth retrying, or the loop would outlive the
124
+ // stop that cancelled it.
125
+ if (err instanceof ContainerHelperError && err.code === "cancelled") {
126
+ throw err;
127
+ }
128
+ throwIfAborted(signal);
129
+ onAttemptFailed?.(err, delay, attempt);
130
+ await unrefSleep(delay, signal);
131
+ delay = Math.min(delay * 2, ceiling);
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts CHANGED
@@ -5,10 +5,23 @@ import type { AppLike } from "./types.js";
5
5
  */
6
6
  export declare const IMAGE_TAG_PATTERN: RegExp;
7
7
  export declare function isValidImageTag(tag: unknown): tag is string;
8
- /** Normalize an unknown thrown value into a printable message. */
8
+ /**
9
+ * Normalize an unknown thrown value into a printable message, following the
10
+ * `.cause` chain and flattening `AggregateError`.
11
+ *
12
+ * The naive `err.message` loses exactly the part an operator needs. undici's
13
+ * fetch rejects with a bare `TypeError: fetch failed` and hides the actionable
14
+ * syscall in `err.cause`, so every consumer polling a containerized app gets
15
+ * "fetch failed" instead of "connect ECONNREFUSED 127.0.0.1:3010". Node >= 20's
16
+ * Happy Eyeballs is worse: it rejects with an `AggregateError` carrying no
17
+ * message of its own, which renders as the literal string "AggregateError".
18
+ *
19
+ * Consumers cannot fix this downstream — this library renders errors to strings
20
+ * internally (readiness timeouts, `fail()`) before a consumer ever sees them.
21
+ */
9
22
  export declare function errMsg(err: unknown): string;
10
23
  export declare function sleep(ms: number): Promise<void>;
11
- export type ContainerHelperErrorCode = "manager-unavailable" | "no-runtime" | "invalid-tag" | "address-unresolved" | "not-ready" | "recreate-limbo" | "cancelled";
24
+ export type ContainerHelperErrorCode = "manager-unavailable" | "no-runtime" | "invalid-tag" | "address-unresolved" | "not-ready" | "recreate-limbo" | "cancelled" | "invalid-option";
12
25
  /**
13
26
  * Typed error thrown by ManagedContainer/AdoptedContainer operations.
14
27
  * `reported` is true when the helper already surfaced the message via
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAErD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAO3D;AAED,kEAAkE;AAClE,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE3C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,MAAM,MAAM,wBAAwB,GAChC,qBAAqB,GACrB,YAAY,GACZ,aAAa,GACb,oBAAoB,GACpB,WAAW,GACX,gBAAgB,GAChB,WAAW,CAAC;AAEhB;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,EAAE,OAAO,CAAC;gBAGhB,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,UAAQ;CAOnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAQ1E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAQzD"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAErD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAO3D;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE3C;AAoCD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,MAAM,MAAM,wBAAwB,GAChC,qBAAqB,GACrB,YAAY,GACZ,aAAa,GACb,oBAAoB,GACpB,WAAW,GACX,gBAAgB,GAChB,WAAW,GACX,gBAAgB,CAAC;AAErB;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,EAAE,OAAO,CAAC;gBAGhB,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,UAAQ;CAOnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAQ1E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAQzD"}
package/dist/util.js CHANGED
@@ -9,9 +9,60 @@ export function isValidImageTag(tag) {
9
9
  tag.length <= 128 &&
10
10
  IMAGE_TAG_PATTERN.test(tag));
11
11
  }
12
- /** Normalize an unknown thrown value into a printable message. */
12
+ /**
13
+ * How far to follow `.cause` / `AggregateError.errors` before giving up.
14
+ * Deep enough for the real chains (undici wraps twice), shallow enough that a
15
+ * pathological or cyclic graph cannot produce an unbounded status line.
16
+ */
17
+ const MAX_CAUSE_DEPTH = 4;
18
+ /**
19
+ * Normalize an unknown thrown value into a printable message, following the
20
+ * `.cause` chain and flattening `AggregateError`.
21
+ *
22
+ * The naive `err.message` loses exactly the part an operator needs. undici's
23
+ * fetch rejects with a bare `TypeError: fetch failed` and hides the actionable
24
+ * syscall in `err.cause`, so every consumer polling a containerized app gets
25
+ * "fetch failed" instead of "connect ECONNREFUSED 127.0.0.1:3010". Node >= 20's
26
+ * Happy Eyeballs is worse: it rejects with an `AggregateError` carrying no
27
+ * message of its own, which renders as the literal string "AggregateError".
28
+ *
29
+ * Consumers cannot fix this downstream — this library renders errors to strings
30
+ * internally (readiness timeouts, `fail()`) before a consumer ever sees them.
31
+ */
13
32
  export function errMsg(err) {
14
- return err instanceof Error ? err.message : String(err);
33
+ return describeError(err, 0);
34
+ }
35
+ function describeError(err, depth) {
36
+ if (err instanceof AggregateError && err.errors.length > 0) {
37
+ // The depth cap applies here too: `errors` arrays can nest, or be cyclic
38
+ // when something overrides the own property after construction.
39
+ if (depth >= MAX_CAUSE_DEPTH) {
40
+ return err.message || "AggregateError";
41
+ }
42
+ const inner = err.errors
43
+ .map((e) => describeError(e, depth + 1))
44
+ .join("; ");
45
+ // A Happy-Eyeballs AggregateError usually carries no message of its own.
46
+ const rendered = err.message && err.message !== "AggregateError"
47
+ ? `${err.message}: ${inner}`
48
+ : inner;
49
+ // An AggregateError can carry BOTH errors and its own cause. Dropping the
50
+ // cause here would swallow exactly the detail this function exists to
51
+ // surface, so append it rather than returning early.
52
+ const cause = err.cause;
53
+ if (cause !== undefined && cause !== null && depth < MAX_CAUSE_DEPTH) {
54
+ return `${rendered}: ${describeError(cause, depth + 1)}`;
55
+ }
56
+ return rendered;
57
+ }
58
+ if (err instanceof Error) {
59
+ const cause = err.cause;
60
+ if (cause !== undefined && cause !== null && depth < MAX_CAUSE_DEPTH) {
61
+ return `${err.message}: ${describeError(cause, depth + 1)}`;
62
+ }
63
+ return err.message;
64
+ }
65
+ return String(err);
15
66
  }
16
67
  export function sleep(ms) {
17
68
  return new Promise((resolve) => setTimeout(resolve, ms));
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,CAAC,MAAM,GAAG,CAAC;QACd,GAAG,CAAC,MAAM,IAAI,GAAG;QACjB,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,MAAM,CAAC,GAAY;IACjC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAWD;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAA2B;IACxC,QAAQ,CAAU;IAElB,YACE,IAA8B,EAC9B,OAAe,EACf,QAAQ,GAAG,KAAK;QAEhB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,EAA0B;IAClE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC1B,IAAI,GAAG,YAAY,oBAAoB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACxD,GAAG,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,GAAG,CAAC,cAAc,CAAC,mBAAmB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,oBAAoB,CAC5B,WAAW,EACX,oCAAoC,EACpC,IAAI,CACL,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-container-helper",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "Helper library for Signal K plugins that manage containers via the signalk-container plugin",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,6 @@
20
20
  "dist",
21
21
  "README.md",
22
22
  "SPEC.md",
23
- "CHANGELOG.md",
24
23
  "LICENSE"
25
24
  ],
26
25
  "scripts": {
package/CHANGELOG.md DELETED
@@ -1,128 +0,0 @@
1
- # v0.4.3
2
-
3
- - **`SelfDeploymentResult` is mirrored in full**, and `SelfDeploymentStatus`
4
- gains the `cgroup-controllers-incomplete` variant it was missing. The
5
- interface previously carried only `status` and `remediation` behind an
6
- `[key: string]: unknown` index signature, so it looked complete while
7
- typing every other field as `unknown` — a consumer reading
8
- `isContainerized`, the field `doctor.selfDeployment()` exists for, got
9
- neither a value nor an error. Ten fields were absent.
10
-
11
- Both types are now pinned in the contract test, which fails against the old
12
- shape. Found by a consumer whose own (correct) type disagreed with the
13
- mirror — see #27 for the coverage gap that let it drift.
14
-
15
- # v0.4.2
16
-
17
- - **`ContainerManagerApi.getContainerNofile` is mirrored** (signalk-container
18
- 1.25.3+), along with its `NofileLimits` return type. It reports the nofile
19
- limits a container is actually running with, which is how a plugin clears a
20
- stale "capped by the host" ulimit advisory once the container does get the
21
- full requested limit. Optional, so feature-detect it. Without this a
22
- consumer had to hand-declare the method and intersect it with the mirrored
23
- interface — the drift the mirror exists to prevent.
24
-
25
- # v0.4.1
26
-
27
- - **`CollapsibleSection` headers read as controls.** The header button
28
- inherited `sectionTitle`'s muted `#888`, so a collapsed section looked like
29
- a caption rather than something to click — a signalk-questdb user reported
30
- a config field as uneditable when it was only collapsed
31
- ([dirkwa/signalk-questdb#123](https://github.com/dirkwa/signalk-questdb/issues/123)).
32
- The chrome moves into two new exported styles, `sectionToggle` (which
33
- overrides the colour to `#555`, the same tone as `label`) and
34
- `sectionMarker` (an 11px disclosure triangle, up from 10px). Every panel
35
- using `CollapsibleSection` picks this up; nothing else changes.
36
-
37
- # v0.4.0
38
-
39
- - **`start()` and `applyUpdate()` accept an `AbortSignal`** via a new optional
40
- `OperationOptions` argument. (`stop()` does not: it has nothing cancellable,
41
- so accepting one would promise what it cannot deliver.) An aborted operation rejects with
42
- `ContainerHelperError` code `cancelled`, flagged `reported` so `startSafely`
43
- logs it rather than surfacing a plugin error for a stop the caller asked for.
44
-
45
- Cancellation is **cooperative**: signalk-container's `ensureRunning`,
46
- `recreate` and `stop` take no signal (only its one-off job API does), so a
47
- call already in flight runs to completion. The signal cancels everything
48
- around it — the manager-global wait, the drift probe, readiness polling, and
49
- each step boundary. Those are the waits with minute-scale deadlines, and
50
- cancelling them is what stops an abandoned start from continuing to work
51
- against a container the caller has already torn down.
52
-
53
- `waitForContainerManager` and `waitForHttpReady` take a `signal` too, so
54
- their poll loops exit promptly instead of running out their full budget.
55
- An aborted `waitForHttpReady` throws an `AbortError` (a `DOMException`,
56
- matching what `fetch` itself throws) rather than its deadline error — a
57
- caller that cancelled must be able to tell "I stopped this" from "the app
58
- never came up", or a container it deliberately tore down surfaces a
59
- readiness failure.
60
-
61
- - **Lifecycle operations are serialized per `ManagedContainer`.** An
62
- overlapping `start` and `stop` — a plugin restarted while its first start is
63
- still waiting on readiness — now queue instead of interleaving, so `stop`
64
- cannot land between `ensureRunning` and the readiness poll and leave the
65
- plugin believing it started something it just removed. Callers that already
66
- hold their own lifecycle lock see no behaviour change.
67
-
68
- Every consumer plugin had built this itself; it belongs in the library.
69
-
70
- # v0.3.1
71
-
72
- Maintenance release. One small change reaches the published package; the rest of
73
- the work since 0.3.0 was tooling and documentation that does not ship.
74
-
75
- - **`useStatusPoll` schedules its repeat poll through an explicit void wrapper** —
76
- `setTimeout(poll, intervalMs)` became `setTimeout(() => void poll(), intervalMs)`.
77
- Behaviour is unchanged: the surrounding effect already handled the async
78
- correctly, with `void` on the initial call, a `cancelled` guard before
79
- rescheduling, and `AbortController.abort()` on cleanup. This makes the
80
- intent explicit rather than fixing a live defect, and satisfies
81
- `@typescript-eslint/no-misused-promises`
82
- - **`fetchWithTimeout` drops an unnecessary `fetch as unknown as FetchLike`
83
- double assertion** — `fetch` already satisfies `FetchLike`. Type-only change;
84
- the emitted JavaScript is byte-identical
85
- - Internal, not shipped: eslint moved to the type-checked tier, which is what
86
- surfaced both items above; `package-lock.json` is no longer committed (CI
87
- generates one per run, matching the signalk-server pattern); `AGENTS.md` and
88
- `CLAUDE.md` document the repo's conventions and release process
89
-
90
- # v0.3.0
91
-
92
- - **Node floor lowered to `>=22`** (was `>=24`) — nothing in the library ever required Node 24: the main entry imports no Node builtins at all, and the only runtime globals it touches (`fetch`, `AbortController`, a plain `setTimeout`-based timeout in `fetchWithTimeout`, `URL`, `globalThis`) predate Node 22 comfortably. There is no `AbortSignal.any()` / `AbortSignal.timeout()`, no `node:sqlite`, and the compiler targets ES2023. The old floor was a policy value that consumers — Signal K plugins, which inherit their host server's Node — had to satisfy for no technical reason. This is a **minor**, not a patch: it widens the supported range and takes nothing away, so Node 24 consumers are unaffected
93
- - **The floor is now enforced rather than asserted** — CI builds, tests, and lints on a `["22", "24"]` matrix instead of Node 24 alone, and `@types/node` drops to `^22` so the typechecker fails on any Node 24-only API that gets introduced later. Previously the package claimed a floor that nothing verified
94
-
95
- # v0.2.2
96
-
97
- Maintenance release — dependency updates only, no changes to the library's public API or runtime behaviour.
98
-
99
- - **TypeScript 6** — the dev toolchain moves from `^5.5.0` to `^6.0.3`; the emitted declarations and ESM output are unchanged, and the full build, 96-test suite, and lint chain pass under the new compiler
100
- - **`signalk-container` type source bumped 1.23.2 → 1.25.2** — the contract test that pins this library's type mirror against `signalk-container/types` still passes, so the mirrored `ContainerManagerApi` / `ContainerConfig` / `UpdateServiceApi` surface has not drifted against the newer manager
101
- - Dev-dependency refresh: `eslint` 10.7.0 → 10.8.0, `typescript-eslint` 8.65.0 → 8.66.0, `globals` 17.7.0 → 17.9.0, `@types/react` 19.2.17 → 19.2.18
102
- - CI: `actions/checkout` and `actions/setup-node` bumped to v7 in the publish workflow
103
-
104
- # v0.2.1
105
-
106
- Docs-only release.
107
-
108
- - **README: "ESM plugins must build an ESM remote"** — Signal K injects each configurator panel's script tag based on the plugin's package.json `type` field, so `"type": "module"` plugins (like this library, and therefore most of its consumers) must build their panel as an ESM Module Federation container (`experiments.outputModule` + `output.module` + `library: { type: "module" }`); the classic `var` remote the CommonJS reference plugins use loads silently into module scope and fails at panel-open time with the misleading _'Module "…" is not available. Make sure the webapp is installed.'_ The new section documents the server's injection logic, both mismatch failure modes, the webpack recipe, a `get`/`init` verification one-liner, and links [signalk-piper](https://github.com/hoeken/signalk-piper) as a working ESM example — plus a matching panel-conventions bullet, and the "no changes to the standard webpack config" claim is now scoped to loaders
109
-
110
- # v0.2.0
111
-
112
- - **New `signalk-container-helper/ui` entrypoint** — browser-side React building blocks for plugin config panels, packaging the pieces the reference plugins (`signalk-grafana`, `signalk-questdb`, `mayara-server-signalk-plugin`) had each been hand-copying: the shared inline-style vocabulary (`panelStyles`, `stateColors`), components (`StatusCard`, `VersionSelect`, `UpdateControls`, `Button`, `CollapsibleSection`, and friends), fetch-and-poll hooks (`useStatusPoll`, `useVersions`, `useUpdateFlow`) with self-scheduling polls and stale-response drops, version-dropdown view logic (`deriveVersionsView`) that handles both structured and legacy `/api/versions` shapes and falls back to the running tag so a rate-limited GitHub fetch never blanks the select, and `formatUpdateMessage` typed against `UpdateCheckResult` to match `registerUpdateRoutes`' contract
113
- - The UI entry ships as tsc-compiled `React.createElement` ESM (no JSX) so panel webpack builds that exclude `node_modules` from babel-loader can bundle it directly; `react` (≥ 17) is a new **optional** peer dependency that resolves to the Admin UI's Module Federation shared singleton — the main entry remains Node-only and zero-dependency
114
- - **Type mirror** — added `ContainerConfig.devices` and `ContainerConfig.groupAdd`, mirroring signalk-container 1.24.0 (older manager versions silently ignore both fields)
115
-
116
- # v0.1.0
117
-
118
- Initial release — a typed, zero-dependency helper library for Signal K plugin developers whose plugins run containers through the [signalk-container](https://github.com/dirkwa/signalk-container) plugin, packaging the integration patterns extracted from `signalk-backup`, `mayara-server-signalk-plugin`, `signalk-doctor`, and `signalk-updater`.
119
-
120
- - **`ManagedContainer`** — the full owned-container lifecycle: image-tag validation, `ensureRunning`, waiting for the app inside the container to answer HTTP, update-detection registration, `/api/update/check` + `/api/update/apply` routes, log access, and clean shutdown
121
- - **`AdoptedContainer`** — update registration and update checks for containers the plugin doesn't own
122
- - **Manager discovery** — `getContainerManager` plus `waitForContainerManager`, a two-phase wait (manager present → runtime settled) that keeps the two failure modes distinct in error reporting
123
- - **Declarative update sources** — `buildVersionSource` resolves a GitHub-releases, Docker-Hub-tags, or custom spec against the manager's update service
124
- - **HTTP utilities** — `fetchWithTimeout`, `waitForHttpReady` (poll until 2xx or deadline), and `probeHttpHealth` (retrying liveness probe with slow-response detection that never throws)
125
- - **Startup helper** — `startSafely` wraps async plugin startup so failures are caught and reported even though Signal K doesn't await `start()`
126
- - **Typed errors** — `ContainerHelperError` with stable error codes, plus the `errMsg` and `isValidImageTag` guards
127
- - **Type mirror of signalk-container's public API** — `ContainerManagerApi`, `ContainerConfig`, `UpdateServiceApi`, and friends, verified against `signalk-container/types` (≥ 1.23.2) by a contract test so the mirror can't silently drift
128
- - Ships as an ES module and requires Node ≥ 24