homebridge-plugin-utils 2.0.0 → 2.2.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 (99) hide show
  1. package/build/tsconfig.json +15 -0
  2. package/dist/backpressure.d.ts +1 -1
  3. package/dist/backpressure.js +4 -4
  4. package/dist/backpressure.js.map +1 -1
  5. package/dist/cli/index.d.ts +93 -5
  6. package/dist/cli/index.js +296 -30
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/clock-double.js +2 -2
  9. package/dist/clock-double.js.map +1 -1
  10. package/dist/disposable-stack.d.ts +59 -0
  11. package/dist/disposable-stack.js +155 -0
  12. package/dist/disposable-stack.js.map +1 -0
  13. package/dist/docChrome.d.ts +263 -0
  14. package/dist/docChrome.js +364 -0
  15. package/dist/docChrome.js.map +1 -0
  16. package/dist/featureOptions-docs.d.ts +2 -2
  17. package/dist/featureOptions-docs.js +1 -1
  18. package/dist/featureOptions.d.ts +5 -5
  19. package/dist/featureOptions.js +6 -6
  20. package/dist/ffmpeg/exec.d.ts +2 -2
  21. package/dist/ffmpeg/exec.js +2 -2
  22. package/dist/ffmpeg/fmp4-builders.d.ts +77 -0
  23. package/dist/ffmpeg/fmp4-builders.js +163 -0
  24. package/dist/ffmpeg/fmp4-builders.js.map +1 -0
  25. package/dist/ffmpeg/index.d.ts +1 -0
  26. package/dist/ffmpeg/index.js +1 -0
  27. package/dist/ffmpeg/index.js.map +1 -1
  28. package/dist/ffmpeg/mp4-assembler.d.ts +45 -4
  29. package/dist/ffmpeg/mp4-assembler.js +45 -8
  30. package/dist/ffmpeg/mp4-assembler.js.map +1 -1
  31. package/dist/ffmpeg/mp4-parser.d.ts +1 -1
  32. package/dist/ffmpeg/mp4-parser.js +1 -1
  33. package/dist/ffmpeg/options.d.ts +17 -0
  34. package/dist/ffmpeg/options.js +50 -25
  35. package/dist/ffmpeg/options.js.map +1 -1
  36. package/dist/ffmpeg/process.d.ts +1 -1
  37. package/dist/ffmpeg/process.js +4 -4
  38. package/dist/ffmpeg/process.js.map +1 -1
  39. package/dist/ffmpeg/record.d.ts +26 -1
  40. package/dist/ffmpeg/record.js +12 -0
  41. package/dist/ffmpeg/record.js.map +1 -1
  42. package/dist/ffmpeg/recording-process-double.d.ts +13 -0
  43. package/dist/ffmpeg/recording-process-double.js +22 -0
  44. package/dist/ffmpeg/recording-process-double.js.map +1 -1
  45. package/dist/ffmpeg/rtp-parser.d.ts +1 -1
  46. package/dist/ffmpeg/rtp-parser.js +1 -1
  47. package/dist/ffmpeg/rtp.d.ts +4 -4
  48. package/dist/ffmpeg/rtp.js +7 -6
  49. package/dist/ffmpeg/rtp.js.map +1 -1
  50. package/dist/ffmpeg/stream.js +1 -1
  51. package/dist/ffmpeg/stream.js.map +1 -1
  52. package/dist/index.d.ts +3 -0
  53. package/dist/index.js +3 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/logclient/auth.d.ts +3 -3
  56. package/dist/logclient/auth.js +2 -2
  57. package/dist/logclient/auth.js.map +1 -1
  58. package/dist/logclient/cli-run.js +2 -2
  59. package/dist/logclient/cli-run.js.map +1 -1
  60. package/dist/logclient/cli.js +2 -2
  61. package/dist/logclient/client.js +2 -2
  62. package/dist/logclient/client.js.map +1 -1
  63. package/dist/logclient/rest.js +1 -1
  64. package/dist/logclient/socket-double.d.ts +1 -1
  65. package/dist/logclient/socket-double.js +1 -1
  66. package/dist/logclient/socket.js +5 -5
  67. package/dist/logclient/socket.js.map +1 -1
  68. package/dist/logclient/time-window.d.ts +1 -1
  69. package/dist/mqttClient.d.ts +1 -1
  70. package/dist/mqttClient.js +3 -3
  71. package/dist/mqttClient.js.map +1 -1
  72. package/dist/timer-registry.d.ts +100 -0
  73. package/dist/timer-registry.js +184 -0
  74. package/dist/timer-registry.js.map +1 -0
  75. package/dist/ui/featureOptions.js +6 -6
  76. package/dist/ui/pluginConfigSession.mjs +1 -1
  77. package/dist/ui/webUi-featureOptions/effects/persist.mjs +2 -2
  78. package/dist/ui/webUi-featureOptions/effects/theme.mjs +1 -1
  79. package/dist/ui/webUi-featureOptions/effects/tokens.mjs +1 -1
  80. package/dist/ui/webUi-featureOptions/rendering.mjs +2 -2
  81. package/dist/ui/webUi-featureOptions/selectors.mjs +3 -3
  82. package/dist/ui/webUi-featureOptions/state.mjs +72 -15
  83. package/dist/ui/webUi-featureOptions/store.mjs +1 -1
  84. package/dist/ui/webUi-featureOptions/utils.mjs +25 -1
  85. package/dist/ui/webUi-featureOptions/views/connectionError.mjs +28 -11
  86. package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +7 -0
  87. package/dist/ui/webUi-featureOptions/views/header.mjs +22 -5
  88. package/dist/ui/webUi-featureOptions/views/nav.mjs +39 -32
  89. package/dist/ui/webUi-featureOptions/views/options.mjs +13 -7
  90. package/dist/ui/webUi-featureOptions/views/search.mjs +2 -2
  91. package/dist/ui/webUi-featureOptions.mjs +109 -61
  92. package/dist/ui/webUi.mjs +48 -11
  93. package/dist/util.d.ts +118 -16
  94. package/dist/util.js +96 -14
  95. package/dist/util.js.map +1 -1
  96. package/dist/webui-loader.d.ts +80 -0
  97. package/dist/webui-loader.js +373 -0
  98. package/dist/webui-loader.js.map +1 -0
  99. package/package.json +10 -10
package/dist/util.d.ts CHANGED
@@ -8,8 +8,8 @@ import type { Logging } from "homebridge";
8
8
  * The canonical set of abort reasons used across `homebridge-plugin-utils`.
9
9
  *
10
10
  * Every long-lived resource class in the library exposes an {@link AbortSignal} whose abort reason is normally an {@link HbpuAbortError} carrying one of these names.
11
- * Consumers discriminate on the `.name` field. Platform errors produced by `AbortSignal.timeout()` and bare `controller.abort()` interoperate by matching names:
12
- * `TimeoutError` and `AbortError` from the platform both flow through the same discrimination paths unchanged.
11
+ * Consumers branch on the `.name` field. Platform errors produced by `AbortSignal.timeout()` and bare `controller.abort()` interoperate by matching names:
12
+ * `TimeoutError` and `AbortError` from the platform both flow through the same branching paths unchanged.
13
13
  *
14
14
  * @remarks When to use each reason:
15
15
  *
@@ -34,7 +34,7 @@ export interface HbpuAbortErrorOptions {
34
34
  */
35
35
  cause?: unknown;
36
36
  /**
37
- * Optional human-readable message. When omitted, the error's `message` defaults to the reason name, which is sufficient for discrimination-based handling.
37
+ * Optional human-readable message. When omitted, the error's `message` defaults to the reason name, which is sufficient for name-based handling.
38
38
  */
39
39
  message?: string;
40
40
  }
@@ -73,7 +73,7 @@ export interface HbpuAbortErrorOptions {
73
73
  */
74
74
  export declare class HbpuAbortError extends Error {
75
75
  /**
76
- * The discriminator. Matches one of {@link HbpuAbortReason}.
76
+ * The tag. Matches one of {@link HbpuAbortReason}.
77
77
  */
78
78
  readonly name: HbpuAbortReason;
79
79
  /**
@@ -87,7 +87,7 @@ export declare class HbpuAbortError extends Error {
87
87
  /**
88
88
  * Type guard: returns `true` if `error` is an {@link HbpuAbortError}.
89
89
  *
90
- * Use this to discriminate HBPU's canonical abort errors from arbitrary thrown values, without nesting `instanceof` checks.
90
+ * Use this to distinguish HBPU's canonical abort errors from arbitrary thrown values, without nesting `instanceof` checks.
91
91
  *
92
92
  * @param error - The value to test.
93
93
  *
@@ -101,7 +101,7 @@ export declare function isHbpuAbortError(error: unknown): error is HbpuAbortErro
101
101
  * `error.cause` and related fields without further casts.
102
102
  *
103
103
  * Collapses the common "is this an HBPU abort, and was it this specific reason?" question into a single call, avoiding the `instanceof` + `.name` nesting that appears
104
- * throughout consuming code. The generic parameter `R` preserves the specific reason string in the narrowed type so callers that discriminate further by name get the
104
+ * throughout consuming code. The generic parameter `R` preserves the specific reason string in the narrowed type so callers that distinguish further by name get the
105
105
  * literal narrowed form automatically.
106
106
  *
107
107
  * @typeParam R - The specific reason being matched. Defaulted by inference from `reason`.
@@ -118,7 +118,7 @@ export declare function isHbpuAbortReason<R extends HbpuAbortReason>(error: unkn
118
118
  /**
119
119
  * Test whether an abort reason indicates a timeout. Matches both the canonical {@link HbpuAbortError} with `"timeout"` name - produced by project watchdogs
120
120
  * ({@link Watchdog}, the inactivity monitors on `FfmpegProcess` / `RtpDemuxer` / `Mp4SegmentAssembler`) - and the platform {@link DOMException}/`Error` whose
121
- * `.name === "TimeoutError"` - produced by `AbortSignal.timeout()`. Consumers discriminate on a single predicate regardless of which code path originated the timeout.
121
+ * `.name === "TimeoutError"` - produced by `AbortSignal.timeout()`. Consumers branch on a single predicate regardless of which code path originated the timeout.
122
122
  *
123
123
  * Exists because every long-lived resource class exposes an `isTimedOut` getter with identical branching logic; routing all of them through this single predicate
124
124
  * enforces one taxonomy and eliminates drift if the project ever needs to add, say, a third timeout shape (e.g., an upstream-framework cancellation).
@@ -185,7 +185,7 @@ export declare function isTimeoutReason(reason: unknown): boolean;
185
185
  * // Abort-driven action goes here.
186
186
  * });
187
187
  *
188
- * // `return await promise` (not a bare `return promise`) is load-bearing inside an async function. `using` disposes when the enclosing function body finishes
188
+ * // `return await promise` (not a bare `return promise`) is required inside an async function. `using` disposes when the enclosing function body finishes
189
189
  * // executing, and without an `await` the body finishes synchronously at the `return` statement - even though the returned promise is still pending. The
190
190
  * // listener would therefore be removed the instant the function returned, well before the promise settles. Adding `await` creates a suspension point that
191
191
  * // keeps the `using` scope alive until the promise actually settles, which is what the "scope-bound registration" pattern relies on.
@@ -354,28 +354,28 @@ export interface HomebridgePluginLogging {
354
354
  * @param message - The message string, with optional format specifiers.
355
355
  * @param parameters - Optional parameters for message formatting.
356
356
  */
357
- debug: (message: string, ...parameters: unknown[]) => void;
357
+ readonly debug: (message: string, ...parameters: unknown[]) => void;
358
358
  /**
359
359
  * Logs an error-level message.
360
360
  *
361
361
  * @param message - The message string, with optional format specifiers.
362
362
  * @param parameters - Optional parameters for message formatting.
363
363
  */
364
- error: (message: string, ...parameters: unknown[]) => void;
364
+ readonly error: (message: string, ...parameters: unknown[]) => void;
365
365
  /**
366
366
  * Logs an info-level message.
367
367
  *
368
368
  * @param message - The message string, with optional format specifiers.
369
369
  * @param parameters - Optional parameters for message formatting.
370
370
  */
371
- info: (message: string, ...parameters: unknown[]) => void;
371
+ readonly info: (message: string, ...parameters: unknown[]) => void;
372
372
  /**
373
373
  * Logs a warning-level message.
374
374
  *
375
375
  * @param message - The message string, with optional format specifiers.
376
376
  * @param parameters - Optional parameters for message formatting.
377
377
  */
378
- warn: (message: string, ...parameters: unknown[]) => void;
378
+ readonly warn: (message: string, ...parameters: unknown[]) => void;
379
379
  }
380
380
  /**
381
381
  * A shippable no-op {@link HomebridgePluginLogging}: every method accepts the logging signature and discards its arguments. A module-scope singleton - the methods are
@@ -393,6 +393,31 @@ export declare const noOpLog: HomebridgePluginLogging;
393
393
  * @category Utilities
394
394
  */
395
395
  export type Logger = HomebridgePluginLogging | Logging;
396
+ /**
397
+ * Derive a prefixed {@link HomebridgePluginLogging} from a base logger. Each level prepends the supplied prefix and the family's ": " separator to the
398
+ * message and passes the message and its parameters through to the base logger unchanged, so formatting happens exactly once, at the sink, behind
399
+ * whatever gates the sink applies. The prefix is a supplier evaluated on every call: identity that can change at runtime (a renamed accessory, a
400
+ * retitled controller) flows into the very next line without any re-wiring, and a captured string can never freeze it.
401
+ *
402
+ * Printf-style tokens behave as if the caller had written the prefix into its own format string: the composed prefix-plus-message string is what meets
403
+ * the parameters at the sink.
404
+ *
405
+ * @param base - The logger that receives the prefixed calls and owns formatting and gating.
406
+ * @param prefix - Supplier for the prefix, evaluated on every call.
407
+ *
408
+ * @returns A {@link HomebridgePluginLogging} whose four levels route to the corresponding levels of `base`.
409
+ *
410
+ * @example
411
+ *
412
+ * ```ts
413
+ * const log = prefixedLog(platformLog, () => this.name);
414
+ *
415
+ * log.info("Connected to %s.", address);
416
+ * ```
417
+ *
418
+ * @category Utilities
419
+ */
420
+ export declare function prefixedLog(base: Logger, prefix: () => string): HomebridgePluginLogging;
396
421
  export { formatBps, formatBytes, formatMs, formatPercent, formatSeconds } from "./formatters.ts";
397
422
  /**
398
423
  * Render an arbitrary thrown value as a clean log-suffix string. Real `Error` instances surface their `.message`; everything else is coerced through `String(...)`.
@@ -590,9 +615,9 @@ export declare function composeSignals(...signals: (AbortSignal | undefined)[]):
590
615
  * Supervise a detached, signal-bound async loop: run the loop, resolve quietly when it ends or its signal aborts, and route any genuine fault to a caller-supplied
591
616
  * handler exactly once.
592
617
  *
593
- * Resilient background loops - membership observers, reachability probes, telemetry firehoses - all share one subtle, correctness-critical invariant: a throw is a
618
+ * Resilient background loops - membership observers, reachability probes, telemetry firehoses - all share one subtle, correctness-critical rule: a throw is a
594
619
  * *fault* only when we did not cause it. When the bound signal is aborted, a throw is the orderly unwinding of a loop the caller already tore down, so it is swallowed
595
- * silently. Any other throw is a genuine fault and is handed to `onError` exactly once. Hand-copying that swallow-on-abort-versus-surface-once discrimination across
620
+ * silently. Any other throw is a genuine fault and is handed to `onError` exactly once. Hand-copying that swallow-on-abort-versus-surface-once distinction across
596
621
  * call sites that share no ancestor is how it drifts apart; owning it in one generic primitive is how it stays consistent.
597
622
  *
598
623
  * The home is here, beside {@link composeSignals}, because the envelope is fully generic - it carries no logging policy, no message wording, and makes no detachment
@@ -674,6 +699,83 @@ export declare function superviseLoop(options: {
674
699
  * @category Utilities
675
700
  */
676
701
  export declare function loopFaultReporter(log: HomebridgePluginLogging, label: string): (error: unknown) => void;
702
+ /**
703
+ * The minimal completion-callback shape {@link guardedDispatch} guards. HomeKit's camera-delegate callbacks (snapshot, prepare-stream, stream-request) each answer with
704
+ * an optional leading `Error` and, in some cases, an optional trailing payload; every one is structurally assignable to this error-first shape, so `guardedDispatch`
705
+ * serves them all without importing any HomeKit or hap-nodejs type. A richer callback that also carries a success payload is preserved through the generic parameter on
706
+ * {@link guardedDispatch}, which keeps the caller's exact signature while still guarding it.
707
+ *
708
+ * @category Utilities
709
+ */
710
+ export type DispatchCallback = (error?: Error) => void;
711
+ /**
712
+ * Run an async handler that HomeKit invokes without awaiting - a camera-delegate method whose interface return type is `void` - so a rejection can never float as an
713
+ * unhandled rejection and the delegate's completion callback is answered exactly once.
714
+ *
715
+ * HomeKit's camera-delegate methods (snapshot, prepare-stream, stream-request) are declared to return `void` yet are naturally written as `async`. Calling an async
716
+ * method in that position discards its promise: a rejection surfaces as a process-level unhandled rejection, and if the method faulted before answering its callback,
717
+ * HomeKit waits forever for a response that never comes. `guardedDispatch` closes both gaps. It owns a once-guard around the real callback and hands the guarded callback
718
+ * to `handler`, so however the handler behaves - answered then faulted, faulted before answering, or answered twice by mistake - the real callback fires exactly once:
719
+ * the first answer wins; a fault after an answer is logged and the earlier answer stands; a fault before any answer is delivered to HomeKit through the callback itself.
720
+ * The handler's promise is marked observed through {@link markHandled}, so nothing floats.
721
+ *
722
+ * @typeParam C - The caller's exact callback signature. Constrained to {@link DispatchCallback} (error-first) so any HomeKit delegate callback fits, while
723
+ * preserving a richer signature - one that also passes a snapshot buffer or stream response - for the handler to answer with.
724
+ * @param options - Dispatch inputs.
725
+ * @param options.callback - The real completion callback HomeKit supplied. It is wrapped in a once-guard and never invoked more than once.
726
+ * @param options.handler - The async work, given the guarded callback to answer with. A rejection, or a synchronous throw, is caught: while the callback is still open
727
+ * it receives the error, otherwise the error is logged.
728
+ * @param options.label - A short human-readable name for the operation (for example `"snapshot request"`), interpolated into the failure log line.
729
+ * @param options.log - The logger a post-answer fault is reported through.
730
+ *
731
+ * @example
732
+ *
733
+ * ```ts
734
+ * import { guardedDispatch } from "homebridge-plugin-utils";
735
+ *
736
+ * // A snapshot delegate HomeKit calls without awaiting. The method itself returns void; the async work and its one-shot callback are handed to guardedDispatch.
737
+ * public handleSnapshotRequest(request: SnapshotRequest, callback: SnapshotRequestCallback): void {
738
+ *
739
+ * guardedDispatch({ callback, handler: (answer) => this.snapshot(request, answer), label: "snapshot request", log: this.log });
740
+ * }
741
+ * ```
742
+ *
743
+ * @category Utilities
744
+ */
745
+ export declare function guardedDispatch<C extends DispatchCallback>(options: {
746
+ callback: C;
747
+ handler: (callback: C) => Promise<void>;
748
+ label: string;
749
+ log: Logger;
750
+ }): void;
751
+ /**
752
+ * Run an async, callback-less handler that HomeKit (or any caller) invokes without awaiting, so a rejection can never float as an unhandled rejection. With no callback
753
+ * to carry a failure back, a fault is simply logged.
754
+ *
755
+ * @param options - Dispatch inputs.
756
+ * @param options.handler - The async work to run. A rejection, or a synchronous throw, is caught and logged.
757
+ * @param options.label - A short human-readable name for the operation (for example `"recording activation"`), interpolated into the failure log line.
758
+ * @param options.log - The logger a fault is reported through.
759
+ *
760
+ * @example
761
+ *
762
+ * ```ts
763
+ * import { guardedDispatch } from "homebridge-plugin-utils";
764
+ *
765
+ * // A recording-state update HomeKit calls without awaiting. There is no callback, so a fault is logged rather than reported back to HomeKit.
766
+ * public updateRecordingActive(active: boolean): void {
767
+ *
768
+ * guardedDispatch({ handler: () => this.applyRecordingActive(active), label: "recording activation", log: this.log });
769
+ * }
770
+ * ```
771
+ *
772
+ * @category Utilities
773
+ */
774
+ export declare function guardedDispatch(options: {
775
+ handler: () => Promise<void>;
776
+ label: string;
777
+ log: Logger;
778
+ }): void;
677
779
  /**
678
780
  * Options for {@link runWithAbort}. At least one of `signal` or `timeout` must be provided so there is always an abort mechanism. TypeScript enforces this at compile
679
781
  * time through a discriminated union - the "no abort mechanism" case is unrepresentable.
@@ -790,12 +892,12 @@ export declare class Watchdog implements Disposable {
790
892
  arm(): void;
791
893
  /**
792
894
  * Cancel any pending fire without aborting anything and without marking the watchdog as permanently dead. Subsequent `arm()` calls continue to work. Safe to call
793
- * when no arm is pending - the method is idempotent.
895
+ * when no arm is pending - repeat calls are no-ops.
794
896
  */
795
897
  clear(): void;
796
898
  /**
797
899
  * `Disposable` implementation. Clears any pending fire AND permanently disables the watchdog: after this runs, `arm()` is a no-op and no further `onFire` calls can
798
- * occur. This is the contract `using watchdog = new Watchdog(...)` relies on - the resource is dead when the block exits, not merely quiescent. Idempotent; repeated
900
+ * occur. This is the contract `using watchdog = new Watchdog(...)` relies on - the resource is dead when the block exits, not merely quiescent. Repeated
799
901
  * disposal is a no-op. Because the class does not own an abort controller, disposal does not signal anything to the rest of the system.
800
902
  */
801
903
  [Symbol.dispose](): void;
package/dist/util.js CHANGED
@@ -66,7 +66,7 @@ const NEVER_ABORTED_SIGNAL = new AbortController().signal;
66
66
  const MARK_HANDLED_NOOP = () => { };
67
67
  // Shared no-op `Disposable` returned by {@link onAbort} on the pre-aborted branch (where no listener was registered and there is nothing to remove). Hoisted to
68
68
  // module scope so every pre-aborted call reuses one instance instead of allocating a fresh object + arrow pair - matching the established pattern for other shared
69
- // module-scope constants in this file (`NEVER_ABORTED_SIGNAL`, `MARK_HANDLED_NOOP`). Safe to share because the disposer is stateless, idempotent, and side-effect
69
+ // module-scope constants in this file (`NEVER_ABORTED_SIGNAL`, `MARK_HANDLED_NOOP`). Safe to share because the disposer is stateless, repeatable, and side-effect
70
70
  // free: `[Symbol.dispose]()` can be invoked any number of times from any call site without interference.
71
71
  const NO_OP_DISPOSABLE = { [Symbol.dispose]: () => { } };
72
72
  /**
@@ -104,7 +104,7 @@ const NO_OP_DISPOSABLE = { [Symbol.dispose]: () => { } };
104
104
  */
105
105
  export class HbpuAbortError extends Error {
106
106
  /**
107
- * The discriminator. Matches one of {@link HbpuAbortReason}.
107
+ * The tag. Matches one of {@link HbpuAbortReason}.
108
108
  */
109
109
  name;
110
110
  /**
@@ -121,7 +121,7 @@ export class HbpuAbortError extends Error {
121
121
  /**
122
122
  * Type guard: returns `true` if `error` is an {@link HbpuAbortError}.
123
123
  *
124
- * Use this to discriminate HBPU's canonical abort errors from arbitrary thrown values, without nesting `instanceof` checks.
124
+ * Use this to distinguish HBPU's canonical abort errors from arbitrary thrown values, without nesting `instanceof` checks.
125
125
  *
126
126
  * @param error - The value to test.
127
127
  *
@@ -137,7 +137,7 @@ export function isHbpuAbortError(error) {
137
137
  * `error.cause` and related fields without further casts.
138
138
  *
139
139
  * Collapses the common "is this an HBPU abort, and was it this specific reason?" question into a single call, avoiding the `instanceof` + `.name` nesting that appears
140
- * throughout consuming code. The generic parameter `R` preserves the specific reason string in the narrowed type so callers that discriminate further by name get the
140
+ * throughout consuming code. The generic parameter `R` preserves the specific reason string in the narrowed type so callers that distinguish further by name get the
141
141
  * literal narrowed form automatically.
142
142
  *
143
143
  * @typeParam R - The specific reason being matched. Defaulted by inference from `reason`.
@@ -154,7 +154,7 @@ export function isHbpuAbortReason(error, reason) {
154
154
  /**
155
155
  * Test whether an abort reason indicates a timeout. Matches both the canonical {@link HbpuAbortError} with `"timeout"` name - produced by project watchdogs
156
156
  * ({@link Watchdog}, the inactivity monitors on `FfmpegProcess` / `RtpDemuxer` / `Mp4SegmentAssembler`) - and the platform {@link DOMException}/`Error` whose
157
- * `.name === "TimeoutError"` - produced by `AbortSignal.timeout()`. Consumers discriminate on a single predicate regardless of which code path originated the timeout.
157
+ * `.name === "TimeoutError"` - produced by `AbortSignal.timeout()`. Consumers branch on a single predicate regardless of which code path originated the timeout.
158
158
  *
159
159
  * Exists because every long-lived resource class exposes an `isTimedOut` getter with identical branching logic; routing all of them through this single predicate
160
160
  * enforces one taxonomy and eliminates drift if the project ever needs to add, say, a third timeout shape (e.g., an upstream-framework cancellation).
@@ -228,7 +228,7 @@ export function isTimeoutReason(reason) {
228
228
  * // Abort-driven action goes here.
229
229
  * });
230
230
  *
231
- * // `return await promise` (not a bare `return promise`) is load-bearing inside an async function. `using` disposes when the enclosing function body finishes
231
+ * // `return await promise` (not a bare `return promise`) is required inside an async function. `using` disposes when the enclosing function body finishes
232
232
  * // executing, and without an `await` the body finishes synchronously at the `return` statement - even though the returned promise is still pending. The
233
233
  * // listener would therefore be removed the instant the function returned, well before the promise settles. Adding `await` creates a suspension point that
234
234
  * // keeps the `using` scope alive until the promise actually settles, which is what the "scope-bound registration" pattern relies on.
@@ -247,7 +247,7 @@ export function onAbort(signal, handler) {
247
247
  }
248
248
  signal.addEventListener("abort", handler, { once: true });
249
249
  // The returned handle lets scope-bound observers remove themselves deterministically when the scope exits, preventing listener accumulation on long-lived signals
250
- // that serve many short-lived waits. `removeEventListener` is idempotent - calling it after the listener has already fired (and been auto-removed by `{ once: true }`)
250
+ // that serve many short-lived waits. `removeEventListener` does nothing - calling it after the listener has already fired (and been auto-removed by `{ once: true }`)
251
251
  // is a safe no-op.
252
252
  return { [Symbol.dispose]: () => signal.removeEventListener("abort", handler) };
253
253
  }
@@ -292,6 +292,40 @@ export const noOpLog = {
292
292
  info: () => { },
293
293
  warn: () => { }
294
294
  };
295
+ /**
296
+ * Derive a prefixed {@link HomebridgePluginLogging} from a base logger. Each level prepends the supplied prefix and the family's ": " separator to the
297
+ * message and passes the message and its parameters through to the base logger unchanged, so formatting happens exactly once, at the sink, behind
298
+ * whatever gates the sink applies. The prefix is a supplier evaluated on every call: identity that can change at runtime (a renamed accessory, a
299
+ * retitled controller) flows into the very next line without any re-wiring, and a captured string can never freeze it.
300
+ *
301
+ * Printf-style tokens behave as if the caller had written the prefix into its own format string: the composed prefix-plus-message string is what meets
302
+ * the parameters at the sink.
303
+ *
304
+ * @param base - The logger that receives the prefixed calls and owns formatting and gating.
305
+ * @param prefix - Supplier for the prefix, evaluated on every call.
306
+ *
307
+ * @returns A {@link HomebridgePluginLogging} whose four levels route to the corresponding levels of `base`.
308
+ *
309
+ * @example
310
+ *
311
+ * ```ts
312
+ * const log = prefixedLog(platformLog, () => this.name);
313
+ *
314
+ * log.info("Connected to %s.", address);
315
+ * ```
316
+ *
317
+ * @category Utilities
318
+ */
319
+ export function prefixedLog(base, prefix) {
320
+ // Compose the prefixed format string once per call: the live prefix, the family's ": " separator, and the caller's message, in that order.
321
+ const prefixed = (message) => prefix() + ": " + message;
322
+ return {
323
+ debug: (message, ...parameters) => base.debug(prefixed(message), ...parameters),
324
+ error: (message, ...parameters) => base.error(prefixed(message), ...parameters),
325
+ info: (message, ...parameters) => base.info(prefixed(message), ...parameters),
326
+ warn: (message, ...parameters) => base.warn(prefixed(message), ...parameters)
327
+ };
328
+ }
295
329
  // Re-export the magnitude-and-percentage formatters from the browser-safe `formatters.ts` module. `featureOptions.ts` imports them directly from there (so it can
296
330
  // ship into `dist/ui/` without dragging in any of util.ts's Node-only imports); util.ts surfaces them here so server-side consumers see the same public API they
297
331
  // always did. The single SSOT is `formatters.ts`; this file is just a forwarding seam.
@@ -366,7 +400,7 @@ export function defaultRetryBackoff(attempt) {
366
400
  */
367
401
  export async function retry(operation, options = {}) {
368
402
  const { attempts = 3, backoff = defaultRetryBackoff, shouldRetry, signal } = options;
369
- // Reject nonsensical attempt counts at the library boundary so the "attempts >= 1" invariant the loop relies on is enforced rather than latent.
403
+ // Reject nonsensical attempt counts at the library boundary so the "attempts >= 1" guarantee the loop relies on is enforced rather than latent.
370
404
  if (attempts < 1) {
371
405
  throw new Error("retry: `attempts` must be >= 1.");
372
406
  }
@@ -578,9 +612,9 @@ export function composeSignals(...signals) {
578
612
  * Supervise a detached, signal-bound async loop: run the loop, resolve quietly when it ends or its signal aborts, and route any genuine fault to a caller-supplied
579
613
  * handler exactly once.
580
614
  *
581
- * Resilient background loops - membership observers, reachability probes, telemetry firehoses - all share one subtle, correctness-critical invariant: a throw is a
615
+ * Resilient background loops - membership observers, reachability probes, telemetry firehoses - all share one subtle, correctness-critical rule: a throw is a
582
616
  * *fault* only when we did not cause it. When the bound signal is aborted, a throw is the orderly unwinding of a loop the caller already tore down, so it is swallowed
583
- * silently. Any other throw is a genuine fault and is handed to `onError` exactly once. Hand-copying that swallow-on-abort-versus-surface-once discrimination across
617
+ * silently. Any other throw is a genuine fault and is handed to `onError` exactly once. Hand-copying that swallow-on-abort-versus-surface-once distinction across
584
618
  * call sites that share no ancestor is how it drifts apart; owning it in one generic primitive is how it stays consistent.
585
619
  *
586
620
  * The home is here, beside {@link composeSignals}, because the envelope is fully generic - it carries no logging policy, no message wording, and makes no detachment
@@ -629,7 +663,7 @@ export async function superviseLoop(options) {
629
663
  await loop(signal);
630
664
  }
631
665
  catch (error) {
632
- // The one invariant this primitive centralizes: discriminate orderly teardown from a genuine fault. An aborted signal means this throw is the loop unwinding in
666
+ // The one rule this primitive centralizes: distinguish orderly teardown from a genuine fault. An aborted signal means this throw is the loop unwinding in
633
667
  // response to a teardown we initiated, so it is expected and is swallowed silently. Otherwise the loop faulted on its own, and we surface it through `onError`
634
668
  // exactly once. Either branch resolves the returned promise rather than rejecting it, so a detached caller never produces an unhandled rejection.
635
669
  if (signal.aborted) {
@@ -677,6 +711,54 @@ export function loopFaultReporter(log, label) {
677
711
  // period is normalized to one and the wording matches every other error log in the package rather than being re-derived at this call site.
678
712
  return (error) => log.error("HomeKit updates for %s stopped unexpectedly and will not resume until the Homebridge plugin restarts: %s.", label, formatErrorMessage(error));
679
713
  }
714
+ export function guardedDispatch(options) {
715
+ const { label, log } = options;
716
+ // The callback-less path: with no completion callback to carry a failure, run the handler and log any fault. A synchronous throw and an asynchronous rejection both
717
+ // surface through the same `await` inside the inner async function, matching the swallow-or-surface envelope `superviseLoop` uses. The `in` check tells the two arities
718
+ // apart: the callback-less member has no `callback` property at all, so it narrows here while the callback member falls through below.
719
+ if (!("callback" in options)) {
720
+ const { handler } = options;
721
+ void markHandled((async () => {
722
+ try {
723
+ await handler();
724
+ }
725
+ catch (error) {
726
+ log.error("The %s handler failed: %s.", label, formatErrorMessage(error));
727
+ }
728
+ })());
729
+ return;
730
+ }
731
+ // The callback path: wrap the real callback so it fires exactly once, forwarding whatever arguments the handler answers with. The `answered` flag is owned here, not by
732
+ // the handler, so a well-behaved answer, a double answer, and a post-answer fault all converge on a single delivery.
733
+ const { callback, handler } = options;
734
+ // The guarded callback's fire state lives on a mutable cell rather than a bare captured boolean so both the guard closure and the fault handler below read the same
735
+ // value. A bare `let` would flow-narrow to its `false` initializer at the read site - the only assignment to `true` is inside the closure - hiding the post-answer
736
+ // case we must distinguish; a property read resets that narrowing after the intervening call.
737
+ const callbackState = { answered: false };
738
+ // A fresh arrow cannot be inferred as the caller's opaque generic `C`, so the assertion restores that identity. The body honors `C`'s own parameters through
739
+ // `Parameters<C>`, so the guard forwards the handler's exact answer - an error, or an error plus a payload - to the real callback unchanged.
740
+ const answerOnce = ((...args) => {
741
+ if (callbackState.answered) {
742
+ return;
743
+ }
744
+ callbackState.answered = true;
745
+ callback(...args);
746
+ });
747
+ void markHandled((async () => {
748
+ try {
749
+ await handler(answerOnce);
750
+ }
751
+ catch (error) {
752
+ // A fault after the callback already answered cannot change HomeKit's answer, so it is logged and the earlier answer stands. A fault before any answer is delivered
753
+ // to HomeKit through the still-open callback, the single most useful place for it to surface.
754
+ if (callbackState.answered) {
755
+ log.error("The %s handler failed after it had already responded to HomeKit: %s.", label, formatErrorMessage(error));
756
+ return;
757
+ }
758
+ answerOnce((error instanceof Error) ? error : new Error(formatErrorMessage(error)));
759
+ }
760
+ })());
761
+ }
680
762
  /**
681
763
  * Run an abortable operation with signal-based cancellation.
682
764
  *
@@ -813,7 +895,7 @@ export class Watchdog {
813
895
  // Null the handle first so a re-entrant `clear()` inside `onFire` is a cheap no-op and so observers inspecting `#timer` post-fire see the correct state.
814
896
  this.#timer = undefined;
815
897
  // Lose a tight race against a concurrent abort cleanly: if the signal fired between timer scheduling and the callback running, the aborted state already
816
- // expresses the outcome and `onFire` is redundant at best, double-teardown at worst. Disposal sets the same invariant through a different gate.
898
+ // expresses the outcome and `onFire` is redundant at best, double-teardown at worst. Disposal sets the same state through a different gate.
817
899
  if (this.#disposed || this.#signal.aborted) {
818
900
  return;
819
901
  }
@@ -822,7 +904,7 @@ export class Watchdog {
822
904
  }
823
905
  /**
824
906
  * Cancel any pending fire without aborting anything and without marking the watchdog as permanently dead. Subsequent `arm()` calls continue to work. Safe to call
825
- * when no arm is pending - the method is idempotent.
907
+ * when no arm is pending - repeat calls are no-ops.
826
908
  */
827
909
  clear() {
828
910
  if (this.#timer !== undefined) {
@@ -832,7 +914,7 @@ export class Watchdog {
832
914
  }
833
915
  /**
834
916
  * `Disposable` implementation. Clears any pending fire AND permanently disables the watchdog: after this runs, `arm()` is a no-op and no further `onFire` calls can
835
- * occur. This is the contract `using watchdog = new Watchdog(...)` relies on - the resource is dead when the block exits, not merely quiescent. Idempotent; repeated
917
+ * occur. This is the contract `using watchdog = new Watchdog(...)` relies on - the resource is dead when the block exits, not merely quiescent. Repeated
836
918
  * disposal is a no-op. Because the class does not own an abort controller, disposal does not signal anything to the rest of the system.
837
919
  */
838
920
  [Symbol.dispose]() {
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The opening marker of the auto-generated webUI boot region. Follows the family's uniform marked-region template (see `docChrome.ts`); the text doubles as an
3
+ * in-document warning not to edit the region by hand.
4
+ *
5
+ * @category WebUI Loader
6
+ */
7
+ export declare const WEBUI_LOADER_BEGIN = "<!-- WEBUI LOADER:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
8
+ /**
9
+ * The closing marker of the auto-generated webUI boot region. See {@link WEBUI_LOADER_BEGIN}.
10
+ *
11
+ * @category WebUI Loader
12
+ */
13
+ export declare const WEBUI_LOADER_END = "<!-- WEBUI LOADER:END -->";
14
+ /**
15
+ * The validated shape of a plugin's webUI loader config: the entry module the loader dynamically imports, and the list of hand-authored modules (the entry aside) that
16
+ * sit outside the package's hashed versioning and therefore each need a cache-bust.
17
+ *
18
+ * @category WebUI Loader
19
+ */
20
+ export interface WebUiLoaderConfig {
21
+ readonly bust: readonly string[];
22
+ readonly entry: string;
23
+ }
24
+ /**
25
+ * Read and validate the plugin's webUI loader config comment from an `index.html`. The comment is the plugin's sole declaration - its entry module and its cache-bust
26
+ * list - and everything else about the rendered region is a family constant or a fact the CLI supplies, so this is where a mistake in that declaration surfaces with a
27
+ * message naming the file and the defect.
28
+ *
29
+ * Rejects, each with a framed error naming `htmlPath`: an absent config comment, a duplicated one (the region it drives would be ambiguous), an unterminated one,
30
+ * invalid JSON, a mis-shaped object (a missing/non-string `entry`, or a `bust` that is not a string array), and a config comment sitting INSIDE the marked region (the
31
+ * first stamp would erase it, so it must live outside the marker pair).
32
+ *
33
+ * @param html - The full `index.html` text.
34
+ * @param htmlPath - The path the html was read from, named in every diagnostic.
35
+ *
36
+ * @returns The validated {@link WebUiLoaderConfig}.
37
+ *
38
+ * @throws `Error` naming `htmlPath` and the defect for an absent, duplicated, unterminated, invalid-JSON, mis-shaped, or inside-the-region config comment.
39
+ *
40
+ * @category WebUI Loader
41
+ */
42
+ export declare function parseWebUiLoaderConfig(html: string, htmlPath: string): WebUiLoaderConfig;
43
+ /**
44
+ * Render the webUI boot region from the plugin's config plus the destination and package facts the CLI supplies. The region carries, in boot order, a hidden status
45
+ * panel, a classic-script boot monitor, and the importmap/cache-bust module loader. The loader reproduces the proven runtime semantics of the hand-authored block: a
46
+ * single `Date.now()` cache-bust stamp shared across the page load, a `bust()` helper that resolves a path against `import.meta.url` and appends the stamp, a
47
+ * `cache: "no-store"` fetch of the manifest, an importmap, and a dynamic import of the entry, all wrapped in a stage-instrumented `try`/`catch` that routes a boot
48
+ * failure to the monitor with the stage that failed, without adding any await or work to the happy path.
49
+ *
50
+ * The catch classifies by stage. A manifest-stage failure reports directly, with no capability probe: the importmap is not injected yet, so probing resolution there
51
+ * would misroute every ordinary delivery failure into the browser bucket. At the import stage the map is injected, so an engine without `import.meta.resolve` predates
52
+ * the loader's floor, and a probe of the injected prefix that throws proves the map never applied - either is the browser bucket - while a resolving probe leaves the
53
+ * failure in the delivery bucket. The probe proves the map applied, not that the delivered module content is sound: a top-level throw inside a delivered module is
54
+ * indistinguishable from a fetch failure here and knowingly folds into the delivery bucket, where the panel's raw error line disambiguates it for support.
55
+ *
56
+ * Every importmap module entry keeps the BARE module path as its KEY with the busted URL as its VALUE - the entry module ITSELF plus every declared `bust` entry, so
57
+ * the most important module (the entry) is never served stale. The trailing-slash `<packageName>/` prefix entry maps the bare package specifier to the hashed-versioned
58
+ * subdir, and transitive imports inherit it through relative-URL resolution.
59
+ *
60
+ * `libPath` is the destination-relative segment the CLI derives from its `dest` basename (`"./lib/"` for the family convention), so the manifest fetch path and the
61
+ * prefix URL are path-correct for any destination rather than a hardcoded `./lib/` that is only coincidentally right for one plugin.
62
+ *
63
+ * @param args
64
+ * @param args.bust - The hand-authored modules (the entry aside) that each need a cache-bust.
65
+ * @param args.entry - The entry module the loader dynamically imports; it is cache-busted alongside the `bust` list.
66
+ * @param args.libPath - The destination-relative segment (e.g. `"./lib/"`) the manifest fetch and the importmap prefix resolve against.
67
+ * @param args.packageName - The mirrored package's name; the importmap prefix maps `<packageName>/` to the hashed-versioned subdir, and the import-stage probe resolves
68
+ * `<packageName>/webUi.mjs` against it.
69
+ *
70
+ * @returns The marked-region content - the status panel, the boot monitor, and the `<script type="module">` loader - to splice between the marker pair.
71
+ *
72
+ * @category WebUI Loader
73
+ */
74
+ export declare function renderWebUiBootRegion({ bust, entry, libPath, packageName }: {
75
+ bust: readonly string[];
76
+ entry: string;
77
+ libPath: string;
78
+ packageName: string;
79
+ }): string;
80
+ //# sourceMappingURL=webui-loader.d.ts.map