prismcast 1.13.0 → 1.14.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/dist/app.d.ts +88 -6
- package/dist/app.js +287 -154
- package/dist/app.js.map +1 -1
- package/dist/browser/cdp.d.ts +6 -17
- package/dist/browser/cdp.js +6 -57
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/index.d.ts +106 -23
- package/dist/browser/index.js +292 -225
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/precaching.d.ts +25 -11
- package/dist/browser/precaching.js +245 -97
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tabCapture.js +3 -10
- package/dist/browser/tabCapture.js.map +1 -1
- package/dist/browser/tuning/comcastPolymer.js +13 -14
- package/dist/browser/tuning/comcastPolymer.js.map +1 -1
- package/dist/browser/tuning/hbo.js +34 -17
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/video.d.ts +1 -1
- package/dist/browser/video.js +3 -3
- package/dist/channels/index.js +5 -5
- package/dist/channels/index.js.map +1 -1
- package/dist/cliHelp.d.ts +11 -0
- package/dist/cliHelp.js +148 -0
- package/dist/cliHelp.js.map +1 -0
- package/dist/config/channelForm.js +5 -4
- package/dist/config/channelForm.js.map +1 -1
- package/dist/config/consistencyProbe.d.ts +2 -4
- package/dist/config/consistencyProbe.js +8 -51
- package/dist/config/consistencyProbe.js.map +1 -1
- package/dist/config/index.d.ts +107 -55
- package/dist/config/index.js +499 -267
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +13 -8
- package/dist/config/paths.js +21 -25
- package/dist/config/paths.js.map +1 -1
- package/dist/config/persistence.d.ts +57 -11
- package/dist/config/persistence.js +127 -44
- package/dist/config/persistence.js.map +1 -1
- package/dist/config/reactivity.d.ts +60 -36
- package/dist/config/reactivity.js +89 -116
- package/dist/config/reactivity.js.map +1 -1
- package/dist/config/services.d.ts +61 -26
- package/dist/config/services.js +137 -68
- package/dist/config/services.js.map +1 -1
- package/dist/config/streamSettings.d.ts +24 -0
- package/dist/config/streamSettings.js +17 -0
- package/dist/config/streamSettings.js.map +1 -0
- package/dist/config/userChannels.d.ts +60 -52
- package/dist/config/userChannels.js +138 -188
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +224 -61
- package/dist/config/userConfig.js +351 -134
- package/dist/config/userConfig.js.map +1 -1
- package/dist/hdhr/discover.d.ts +7 -1
- package/dist/hdhr/discover.js +12 -6
- package/dist/hdhr/discover.js.map +1 -1
- package/dist/hdhr/index.d.ts +51 -10
- package/dist/hdhr/index.js +108 -112
- package/dist/hdhr/index.js.map +1 -1
- package/dist/hdhr/udp.d.ts +11 -4
- package/dist/hdhr/udp.js +25 -20
- package/dist/hdhr/udp.js.map +1 -1
- package/dist/index.js +16 -143
- package/dist/index.js.map +1 -1
- package/dist/native/index.d.ts +1 -1
- package/dist/native/index.js +4 -3
- package/dist/native/index.js.map +1 -1
- package/dist/native/proxy.d.ts +1 -1
- package/dist/native/proxy.js +36 -28
- package/dist/native/proxy.js.map +1 -1
- package/dist/routes/cdp.d.ts +7 -6
- package/dist/routes/cdp.js +9 -8
- package/dist/routes/cdp.js.map +1 -1
- package/dist/routes/components.d.ts +23 -5
- package/dist/routes/components.js +21 -4
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/endpoints/browse.js +39 -29
- package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
- package/dist/routes/config/channels/endpoints/bulk.js +2 -6
- package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
- package/dist/routes/config/channels/endpoints/predefined.js +5 -15
- package/dist/routes/config/channels/endpoints/predefined.js.map +1 -1
- package/dist/routes/config/channels/endpoints/prefs.js +7 -6
- package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
- package/dist/routes/config/channels/endpoints/service.js +6 -5
- package/dist/routes/config/channels/endpoints/service.js.map +1 -1
- package/dist/routes/config/channels/endpoints/tags.js +4 -16
- package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
- package/dist/routes/config/channels/table.d.ts +2 -1
- package/dist/routes/config/channels/table.js +11 -13
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/http/envelope.d.ts +6 -3
- package/dist/routes/config/http/envelope.js +18 -5
- package/dist/routes/config/http/envelope.js.map +1 -1
- package/dist/routes/config/index.d.ts +21 -13
- package/dist/routes/config/index.js +47 -34
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/settings.d.ts +43 -6
- package/dist/routes/config/settings.js +225 -125
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/config/vocabulary.d.ts +24 -0
- package/dist/routes/config/vocabulary.js +33 -0
- package/dist/routes/config/vocabulary.js.map +1 -0
- package/dist/routes/debug.js +28 -13
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/root/content.js +33 -26
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/scripts/channels.js +23 -11
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/config.d.ts +1 -1
- package/dist/routes/root/scripts/config.js +127 -79
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/shared.js +34 -23
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.handlers.d.ts +8 -13
- package/dist/routes/root/scripts/status.handlers.js +35 -21
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/styles.js +13 -16
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/routes/services.js +12 -16
- package/dist/routes/services.js.map +1 -1
- package/dist/routes/theme.js +12 -12
- package/dist/routes/theme.js.map +1 -1
- package/dist/routes/ui.d.ts +4 -3
- package/dist/routes/ui.js +17 -13
- package/dist/routes/ui.js.map +1 -1
- package/dist/service/generators.js +12 -9
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/captureSession.d.ts +4 -4
- package/dist/streaming/captureSession.js +6 -7
- package/dist/streaming/captureSession.js.map +1 -1
- package/dist/streaming/codec.d.ts +12 -2
- package/dist/streaming/codec.js +40 -28
- package/dist/streaming/codec.js.map +1 -1
- package/dist/streaming/fmp4Segmenter.d.ts +14 -4
- package/dist/streaming/fmp4Segmenter.js +99 -79
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +21 -14
- package/dist/streaming/hls.js +148 -122
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +36 -13
- package/dist/streaming/hlsResume.js +68 -37
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/monitor.d.ts +5 -3
- package/dist/streaming/monitor.js +47 -37
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +29 -4
- package/dist/streaming/mp4Parser.js +49 -7
- package/dist/streaming/mp4Parser.js.map +1 -1
- package/dist/streaming/playlistBuilder.d.ts +1 -2
- package/dist/streaming/playlistBuilder.js +2 -3
- package/dist/streaming/playlistBuilder.js.map +1 -1
- package/dist/streaming/preroll.d.ts +43 -16
- package/dist/streaming/preroll.js +112 -62
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/pretune.d.ts +2 -2
- package/dist/streaming/pretune.js +11 -7
- package/dist/streaming/pretune.js.map +1 -1
- package/dist/streaming/recovery.d.ts +29 -2
- package/dist/streaming/recovery.js +43 -4
- package/dist/streaming/recovery.js.map +1 -1
- package/dist/streaming/registry.d.ts +13 -10
- package/dist/streaming/registry.js +6 -5
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +29 -20
- package/dist/streaming/setup.js +181 -170
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +24 -12
- package/dist/streaming/showInfo.js +120 -113
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +15 -10
- package/dist/streaming/statusEmitter.js +24 -20
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/config.d.ts +24 -13
- package/dist/types/config.js +5 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.js +2 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +2 -2
- package/dist/types/selection.d.ts +12 -10
- package/dist/types/streaming.d.ts +12 -5
- package/dist/types/streaming.js +12 -5
- package/dist/types/streaming.js.map +1 -1
- package/dist/utils/debugFilter.d.ts +3 -2
- package/dist/utils/debugFilter.js +7 -5
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/{hdhr → utils}/deviceId.d.ts +1 -1
- package/dist/{hdhr → utils}/deviceId.js +11 -29
- package/dist/utils/deviceId.js.map +1 -0
- package/dist/utils/errors.d.ts +7 -0
- package/dist/utils/errors.js +12 -3
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/fileLogger.d.ts +23 -12
- package/dist/utils/fileLogger.js +73 -41
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/httpErrors.d.ts +13 -0
- package/dist/utils/httpErrors.js +22 -0
- package/dist/utils/httpErrors.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts +9 -8
- package/dist/utils/logger.js +64 -20
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/markup.js +8 -3
- package/dist/utils/markup.js.map +1 -1
- package/dist/utils/plainObject.d.ts +6 -0
- package/dist/utils/plainObject.js +18 -0
- package/dist/utils/plainObject.js.map +1 -0
- package/dist/utils/runtimeIdentity.context.js +1 -29
- package/dist/utils/runtimeIdentity.context.js.map +1 -1
- package/dist/utils/runtimeIdentity.d.ts +17 -6
- package/dist/utils/runtimeIdentity.js +50 -17
- package/dist/utils/runtimeIdentity.js.map +1 -1
- package/package.json +5 -5
- package/dist/hdhr/deviceId.js.map +0 -1
package/dist/utils/logger.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
*
|
|
3
3
|
* logger.ts: Logging utilities with color-coded output for PrismCast.
|
|
4
4
|
*/
|
|
5
|
-
import { format, styleText } from "node:util";
|
|
5
|
+
import { format, inspect, styleText } from "node:util";
|
|
6
6
|
import { getStreamId, resolveContextShowName } from "./streamContext.js";
|
|
7
7
|
import { initDebugFilter, isAnyDebugEnabled, isCategoryEnabled } from "./debugFilter.js";
|
|
8
8
|
import { emitLogEntry } from "./logEmitter.js";
|
|
9
9
|
import { formatTimestamp } from "./format.js";
|
|
10
|
+
import { isPlainObject } from "./plainObject.js";
|
|
10
11
|
import { writeLogEntry } from "./fileLogger.js";
|
|
11
12
|
/* Terminal color choices for log output. Warnings appear in yellow and errors in red, making it easy to spot issues when scanning log output. Coloring is delegated
|
|
12
13
|
* to node:util.styleText so the SGR sequences are managed by the platform rather than hand-written escape codes.
|
|
@@ -31,7 +32,8 @@ export function isConsoleLogging() {
|
|
|
31
32
|
return useConsoleLogging;
|
|
32
33
|
}
|
|
33
34
|
/* Debug logging is controlled by the category-based filter system in debugFilter.ts. The --debug CLI flag enables all categories (equivalent to
|
|
34
|
-
* PRISMCAST_DEBUG=*),
|
|
35
|
+
* PRISMCAST_DEBUG=*), the PRISMCAST_DEBUG environment variable allows fine-grained category selection, and the /debug page sets the filter at runtime and
|
|
36
|
+
* persists it in the configuration.
|
|
35
37
|
*/
|
|
36
38
|
/**
|
|
37
39
|
* Enables or disables debug logging. When called with true, initializes the debug filter with wildcard (*) to enable all categories.
|
|
@@ -41,25 +43,57 @@ export function setDebugLogging(enabled) {
|
|
|
41
43
|
initDebugFilter(enabled ? "*" : "");
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
|
-
* Returns whether any debug
|
|
45
|
-
* @returns True if any debug
|
|
46
|
+
* Returns whether any debug filter pattern is configured. An exclude-only pattern counts, so a true answer does not mean a category is enabled.
|
|
47
|
+
* @returns True if any debug filter pattern is configured, including an exclude-only pattern, false otherwise.
|
|
46
48
|
*/
|
|
47
49
|
export function isDebugLogging() {
|
|
48
50
|
return isAnyDebugEnabled();
|
|
49
51
|
}
|
|
50
52
|
/* The LOG object provides a centralized logging interface with color-coded output and printf-style format strings. All methods accept a format string followed by
|
|
51
|
-
* optional arguments, using Node's util.format() for interpolation.
|
|
53
|
+
* optional arguments, using Node's util.format() for interpolation. The supported format specifiers are the ones FORMAT_SPECIFIER_PATTERN holds: %s (string),
|
|
54
|
+
* %d (number), %i (integer), %f (floating point), %j (JSON), %o and %O (object), and %c (CSS, consumed and ignored).
|
|
52
55
|
*
|
|
53
56
|
* Stream context is automatically detected via AsyncLocalStorage. When running within a stream context (established by runWithStreamContext()), log messages are
|
|
54
57
|
* automatically prefixed with the stream ID for correlation across concurrent streaming sessions.
|
|
55
58
|
*
|
|
56
59
|
* For logging outside a stream context (e.g., iterating over streams in a disconnect handler), use LOG.withStreamId() to create a bound logger.
|
|
57
60
|
*/
|
|
61
|
+
/* The format specifiers util.format() consumes an argument for. An escaped percent consumes nothing, so the count strips every escaped percent before it matches,
|
|
62
|
+
* and what remains mirrors util.format()'s own consumption: a message whose arguments outnumber its specifiers leaves its trailing arguments unconsumed, which is
|
|
63
|
+
* how logWithLevel tells a trailing context object from an argument a specifier renders. The pattern is global so String.prototype.match returns every
|
|
64
|
+
* occurrence, and it is read only through match, because a global pattern's own exec and test carry their position from one call to the next in lastIndex.
|
|
65
|
+
*/
|
|
66
|
+
const FORMAT_SPECIFIER_PATTERN = /%[sdifjoOc]/g;
|
|
67
|
+
// An escaped percent. util.format() renders it as one literal percent sign, and it consumes no argument.
|
|
68
|
+
const ESCAPED_PERCENT = "%%";
|
|
69
|
+
/**
|
|
70
|
+
* Counts the specifiers in a message that each consume an argument, with escaped percents removed first so "%%s" reads as a literal percent sign and an "s".
|
|
71
|
+
* @param message - The format string.
|
|
72
|
+
* @returns The number of argument-consuming specifiers in the message.
|
|
73
|
+
*/
|
|
74
|
+
function countFormatSpecifiers(message) {
|
|
75
|
+
return message.replaceAll(ESCAPED_PERCENT, "").match(FORMAT_SPECIFIER_PATTERN)?.length ?? 0;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Formats the sentence of a line whose trailing context object has been set aside, from the message and the arguments that precede the context.
|
|
79
|
+
* @param message - The format string.
|
|
80
|
+
* @param args - The arguments that precede the context object.
|
|
81
|
+
* @returns The formatted sentence, before normalization.
|
|
82
|
+
*/
|
|
83
|
+
function formatSentence(message, args) {
|
|
84
|
+
if (args.length > 0) {
|
|
85
|
+
return format(message, ...args);
|
|
86
|
+
}
|
|
87
|
+
// util.format() renders an escaped percent only when it is given an argument, and the context object is such an argument. A message that leaves no argument
|
|
88
|
+
// for the sentence has no specifier, so rendering its escaped percents is all util.format() would do to the sentence if the context went through it as well.
|
|
89
|
+
return message.replaceAll(ESCAPED_PERCENT, "%");
|
|
90
|
+
}
|
|
58
91
|
/* The logger commits to emitting exactly one sentence terminator on every non-debug line so callers do not have to reason about whether the format string or an
|
|
59
92
|
* interpolated value carries the punctuation. This encodes the "non-debug logs are complete sentences" project rule as logger behavior rather than as per-call-site
|
|
60
|
-
* discipline - a producer changing its message punctuation
|
|
93
|
+
* discipline - a producer changing its message punctuation cannot silently regress an interpolated log line, and the differing punctuation conventions
|
|
61
94
|
* between formatError (which strips trailing punctuation) and userMessage/validator strings (which carry it) become invisible to callers. Debug stays raw because
|
|
62
|
-
* debug is fragments by convention.
|
|
95
|
+
* debug is fragments by convention. The terminator closes the sentence, and a trailing context object follows it: a line in the house form, a complete sentence
|
|
96
|
+
* with its details in a context object, ends with the object rather than with a period after it.
|
|
63
97
|
*/
|
|
64
98
|
/**
|
|
65
99
|
* Normalizes a non-debug log message to exactly one terminal sentence terminator. Runs of trailing periods collapse to a single period (the double-period
|
|
@@ -98,8 +132,10 @@ function emitToSubscribers(level, message, categoryTag) {
|
|
|
98
132
|
emitLogEntry(entry);
|
|
99
133
|
}
|
|
100
134
|
/**
|
|
101
|
-
* Interpolates the format string against its arguments and normalizes non-debug messages to a single
|
|
102
|
-
*
|
|
135
|
+
* Interpolates the format string against its arguments and normalizes non-debug messages to a single sentence terminator, then hands the result to emitFormatted
|
|
136
|
+
* for prefixing, SSE emission, and output routing. A non-debug line whose last argument is a plain object that no specifier consumes carries that object as its
|
|
137
|
+
* context: the sentence is formatted from the message and the other arguments and normalized on its own, and the context follows its terminator as
|
|
138
|
+
* util.inspect() renders it. Debug messages skip normalization because debug output is fragments by convention.
|
|
103
139
|
* @param level - The log level (error, warn, info, debug).
|
|
104
140
|
* @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
|
|
105
141
|
* @param message - The format string.
|
|
@@ -108,15 +144,22 @@ function emitToSubscribers(level, message, categoryTag) {
|
|
|
108
144
|
* @param categoryTag - Optional debug category tag for category-filtered debug messages.
|
|
109
145
|
*/
|
|
110
146
|
function logWithLevel(level, color, message, args, explicitStreamId, categoryTag) {
|
|
111
|
-
const
|
|
147
|
+
const context = args.at(-1);
|
|
148
|
+
// A trailing plain object that the message's specifiers leave unconsumed is the line's context. On a non-debug line the terminator closes the sentence, formatted
|
|
149
|
+
// from the message and the other arguments, and the context follows it as util.inspect() renders it, the rendering util.format() gives an argument it does not
|
|
150
|
+
// consume. The plain-object test runs before the specifier count because it is the cheaper check and a line without a trailing object fails it at once.
|
|
151
|
+
if ((level !== "debug") && isPlainObject(context) && (args.length > countFormatSpecifiers(message))) {
|
|
152
|
+
emitFormatted(level, color, normalizeSentence(formatSentence(message, args.slice(0, -1))) + " " + inspect(context), explicitStreamId, categoryTag);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const formatted = args.length > 0 ? format(message, ...args) : message;
|
|
112
156
|
// Non-debug levels are guaranteed sentence-terminated; debug stays raw because debug is fragments by convention. The contract lives here, not at the call site.
|
|
113
|
-
|
|
114
|
-
emitFormatted(level, color, formatted, explicitStreamId, categoryTag);
|
|
157
|
+
emitFormatted(level, color, (level === "debug") ? formatted : normalizeSentence(formatted), explicitStreamId, categoryTag);
|
|
115
158
|
}
|
|
116
159
|
/**
|
|
117
160
|
* Emits an already-formatted message body through the full logger pipeline: stream-ID prefix composition, SSE subscriber emission, and console-or-file routing.
|
|
118
|
-
* Shared between logWithLevel (which normalizes first) and displayLine (which deliberately bypasses normalization for tabular display).
|
|
119
|
-
*
|
|
161
|
+
* Shared between logWithLevel (which normalizes first) and displayLine (which deliberately bypasses normalization for tabular display). One shared emitter keeps
|
|
162
|
+
* every caller from drifting on prefix shape, SSE routing, or color handling.
|
|
120
163
|
* @param level - The log level (drives console method routing and category tagging).
|
|
121
164
|
* @param color - Color name for styleText, or null for the default terminal color.
|
|
122
165
|
* @param formatted - The fully-prepared message body (post-normalization if applicable).
|
|
@@ -186,12 +229,13 @@ export function displayLine(message, ...args) {
|
|
|
186
229
|
}
|
|
187
230
|
export const LOG = {
|
|
188
231
|
/**
|
|
189
|
-
* Logs a debug message in cyan, filtered by category. Debug messages are only
|
|
190
|
-
* variable
|
|
232
|
+
* Logs a debug message in cyan, filtered by category. Debug messages are output only when the debug filter in debugFilter.ts enables the specified category.
|
|
233
|
+
* The filter is set by the PRISMCAST_DEBUG environment variable, by the --debug CLI flag (which enables all categories), or from the /debug page, whose filter
|
|
234
|
+
* is persisted in the configuration and applied at startup. Use this for verbose diagnostic information that would clutter normal logs.
|
|
191
235
|
*
|
|
192
236
|
* Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
|
|
193
237
|
* @param category - The debug category (e.g., "tuning:hulu", "recovery:tab", "streaming:segmenter").
|
|
194
|
-
* @param message - The format string (supports %s, %d, %j, %o).
|
|
238
|
+
* @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
|
|
195
239
|
* @param args - Values to interpolate into the format string.
|
|
196
240
|
*/
|
|
197
241
|
debug: function (category, message, ...args) {
|
|
@@ -205,7 +249,7 @@ export const LOG = {
|
|
|
205
249
|
* stream initialization errors. The red color provides immediate visual indication of serious problems requiring attention.
|
|
206
250
|
*
|
|
207
251
|
* Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
|
|
208
|
-
* @param message - The format string (supports %s, %d, %j, %o).
|
|
252
|
+
* @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
|
|
209
253
|
* @param args - Values to interpolate into the format string.
|
|
210
254
|
*/
|
|
211
255
|
error: function (message, ...args) {
|
|
@@ -216,7 +260,7 @@ export const LOG = {
|
|
|
216
260
|
* status updates.
|
|
217
261
|
*
|
|
218
262
|
* Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
|
|
219
|
-
* @param message - The format string (supports %s, %d, %j, %o).
|
|
263
|
+
* @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
|
|
220
264
|
* @param args - Values to interpolate into the format string.
|
|
221
265
|
*/
|
|
222
266
|
info: function (message, ...args) {
|
|
@@ -227,7 +271,7 @@ export const LOG = {
|
|
|
227
271
|
* recovered from, missing optional features, or degraded functionality.
|
|
228
272
|
*
|
|
229
273
|
* Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
|
|
230
|
-
* @param message - The format string (supports %s, %d, %j, %o).
|
|
274
|
+
* @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
|
|
231
275
|
* @param args - Values to interpolate into the format string.
|
|
232
276
|
*/
|
|
233
277
|
warn: function (message, ...args) {
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/markup.js
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
/* This module is the single source of truth for escape-style markup encoding. HTML escaping (used pervasively across the routes layer to embed user-provided
|
|
6
6
|
* values in server-rendered pages) and XML escaping (used by the macOS launchd plist generator and the HDHomeRun device description) cover the same reserved
|
|
7
7
|
* characters; only the apostrophe entity differs - HTML5 spells it ' and XML spells it '. Centralizing both surfaces over a shared regex and a
|
|
8
|
-
* Readonly entity map keeps the character class in one place so
|
|
8
|
+
* Readonly entity map per flavor keeps the character class in one place, so every flavor matches the same characters.
|
|
9
9
|
*/
|
|
10
|
-
// The shared character class for
|
|
10
|
+
// The shared character class for the HTML and XML escape sweeps. Defined once so every escape variant matches the same characters...each entity map still needs
|
|
11
|
+
// an entry for every character here, because escapeMarkup passes a matched character with no entry through unescaped.
|
|
11
12
|
const MARKUP_ENTITY_REGEX = /[&<>"']/g;
|
|
12
13
|
// HTML5 entity map. The apostrophe entity is ' because the named entity ' was only added to HTML5 (older browsers fall back to the numeric reference).
|
|
13
14
|
const HTML_ENTITIES = {
|
|
@@ -27,7 +28,7 @@ const XML_ENTITIES = {
|
|
|
27
28
|
};
|
|
28
29
|
/**
|
|
29
30
|
* Shared escape body for both HTML and XML. Returns the input with every character in MARKUP_ENTITY_REGEX replaced by its entity from the supplied table. The
|
|
30
|
-
* private factor here is intentional: it commits
|
|
31
|
+
* private factor here is intentional: it commits each public escaper to the same regex and the same Record-based lookup, so every flavor matches the same characters.
|
|
31
32
|
* @param value - The string to escape.
|
|
32
33
|
* @param entities - The entity table that owns the per-character substitution.
|
|
33
34
|
* @returns The escaped string.
|
|
@@ -52,6 +53,10 @@ export function escapeHtml(value) {
|
|
|
52
53
|
export function escapeXml(value) {
|
|
53
54
|
return escapeMarkup(value, XML_ENTITIES);
|
|
54
55
|
}
|
|
56
|
+
/* The status script's HANDLER_FUNCTIONS ships this function to the browser by its source, beside the badge builder that calls it, so its body references only its
|
|
57
|
+
* parameter, Object.entries and escapeHtml, each of which the browser holds by the same name. A call to any other helper leaves the shipped stream table throwing
|
|
58
|
+
* in the browser while every Node row passes, because the helper's binding exists only here.
|
|
59
|
+
*/
|
|
55
60
|
/**
|
|
56
61
|
* Serializes a record of HTML attribute names to values into the inline fragment suitable for embedding in an opening tag. Value semantics keep this tied
|
|
57
62
|
* to the way HTML actually shapes attributes: undefined and boolean false are omitted entirely; boolean true emits the attribute name alone (HTML5 boolean
|
package/dist/utils/markup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markup.js","sourceRoot":"","sources":["../../src/utils/markup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,
|
|
1
|
+
{"version":3,"file":"markup.js","sourceRoot":"","sources":["../../src/utils/markup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,gKAAgK;AAChK,sHAAsH;AACtH,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAEvC,gKAAgK;AAChK,MAAM,aAAa,GAAqC;IAEtD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF,wIAAwI;AACxI,MAAM,YAAY,GAAqC;IAErD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAa,EAAE,QAA0C;IAE7E,OAAO,KAAK,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IAEtC,OAAO,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IAErC,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,KAA6D;IAE1F,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAI,MAAM,CAAE,IAAI,EAAE,KAAK,CAAE,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAEnD,IAAG,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;YAE9C,SAAS;QACX,CAAC;QAED,IAAG,KAAK,KAAK,IAAI,EAAE,CAAC;YAElB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAErB,SAAS;QACX,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predicate: is the value a plain object (not array, not null, not a class instance like Date)?
|
|
3
|
+
* @param value - The candidate.
|
|
4
|
+
* @returns True if value is a plain object literal.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* plainObject.ts: Plain-object predicate for PrismCast.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Predicate: is the value a plain object (not array, not null, not a class instance like Date)?
|
|
7
|
+
* @param value - The candidate.
|
|
8
|
+
* @returns True if value is a plain object literal.
|
|
9
|
+
*/
|
|
10
|
+
export function isPlainObject(value) {
|
|
11
|
+
if ((value === null) || (typeof value !== "object") || Array.isArray(value)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
// Object.getPrototypeOf is typed as returning any in the standard lib. Cast through unknown so the comparisons below are type-safe.
|
|
15
|
+
const proto = Object.getPrototypeOf(value);
|
|
16
|
+
return (proto === null) || (proto === Object.prototype);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=plainObject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plainObject.js","sourceRoot":"","sources":["../../src/utils/plainObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAE1C,IAAG,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAE3E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oIAAoI;IACpI,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAY,CAAC;IAEtD,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -2,44 +2,16 @@ import { getBootSessionId } from "./bootSession.js";
|
|
|
2
2
|
import { isProcessRunning } from "./pid.js";
|
|
3
3
|
import { listProcesses } from "./processInspector.js";
|
|
4
4
|
import { systemClock } from "homebridge-plugin-utils";
|
|
5
|
-
/* The product-identity token searched for in a process's command line. This mirrors the package name / SERVICE_NAME identity; it lives as a local constant
|
|
6
|
-
* because the runtime-identity context must remain free of sideways imports into identity.ts. Matching is case-insensitive so launcher casing differences (e.g.
|
|
7
|
-
* the macOS app bundle versus the lowercase binary) do not cause a false negative.
|
|
8
|
-
*/
|
|
9
|
-
const PRISMCAST_COMMAND_TOKEN = "prismcast";
|
|
10
5
|
/**
|
|
11
6
|
* Builds the default RuntimeIdentityContext from real runtime I/O.
|
|
12
7
|
* @returns A RuntimeIdentityContext populated from the live process.
|
|
13
8
|
*/
|
|
14
9
|
export function createDefaultRuntimeIdentityContext() {
|
|
15
10
|
return {
|
|
11
|
+
commandLineOf: (pid) => listProcesses().find((entry) => entry.pid === pid)?.commandLine ?? null,
|
|
16
12
|
getBootSessionId: () => getBootSessionId(),
|
|
17
|
-
isPidOurProcess: (pid) => resolvePidIdentity(pid),
|
|
18
13
|
isProcessRunning,
|
|
19
14
|
now: () => systemClock.now()
|
|
20
15
|
};
|
|
21
16
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Resolves whether the live process at the given PID is genuinely a PrismCast instance by enumerating the OS process table and matching the product token in the
|
|
24
|
-
* row's command line. Returns true when the row's command line contains the token, false when it contains a non-empty command line without the token, and null
|
|
25
|
-
* when identity cannot be determined - the process table is empty (unsupported platform or enumeration failure), the PID is absent from it, or the matching
|
|
26
|
-
* row reports an empty command line (kernel threads, hidden command lines). The null cases all map upstream to the conservative held-live verdict.
|
|
27
|
-
* @param pid - The PID to identify.
|
|
28
|
-
* @returns True for a confirmed PrismCast process, false for a confirmed different process, null when identity cannot be determined.
|
|
29
|
-
*/
|
|
30
|
-
function resolvePidIdentity(pid) {
|
|
31
|
-
const processes = listProcesses();
|
|
32
|
-
const match = processes.find((entry) => entry.pid === pid);
|
|
33
|
-
// The PID is absent from the snapshot (it exited between the liveness check and this enumeration, or the platform returned an empty table). We cannot prove the
|
|
34
|
-
// process is unrelated, so identity is indeterminate.
|
|
35
|
-
if (match === undefined) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
const commandLine = match.commandLine.trim();
|
|
39
|
-
// An empty command line (kernel thread, process that hid its argv) gives us nothing to match against, so identity remains indeterminate.
|
|
40
|
-
if (commandLine === "") {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
return commandLine.toLowerCase().includes(PRISMCAST_COMMAND_TOKEN);
|
|
44
|
-
}
|
|
45
17
|
//# sourceMappingURL=runtimeIdentity.context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeIdentity.context.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtimeIdentity.context.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.context.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,mCAAmC;IAEjD,OAAO;QAEL,aAAa,EAAE,CAAC,GAAW,EAAoB,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,WAAW,IAAI,IAAI;QACzH,gBAAgB,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE;QAC1C,gBAAgB;QAChB,GAAG,EAAE,GAAW,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -4,13 +4,14 @@ import type { Nullable } from "../types/index.ts";
|
|
|
4
4
|
*/
|
|
5
5
|
export interface IdentityRecord {
|
|
6
6
|
readonly bootId: string;
|
|
7
|
+
readonly commandHash: Nullable<string>;
|
|
7
8
|
readonly pid: number;
|
|
8
9
|
readonly startedAt: string;
|
|
9
10
|
readonly version: string;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
|
-
* Discriminated union representing the on-disk state at a given path.
|
|
13
|
-
*
|
|
13
|
+
* Discriminated union representing the on-disk state at a given path. Each variant carries only the data its state has. claim() and release() test for
|
|
14
|
+
* held-live alone, so unless they are extended, claim() overwrites a new variant and release() leaves its file in place.
|
|
14
15
|
*/
|
|
15
16
|
export type IdentityState = {
|
|
16
17
|
kind: "free";
|
|
@@ -42,8 +43,8 @@ export type ClaimResult = {
|
|
|
42
43
|
* literal to drive each state-machine branch deterministically.
|
|
43
44
|
*/
|
|
44
45
|
export interface RuntimeIdentityContext {
|
|
46
|
+
readonly commandLineOf: (pid: number) => Nullable<string>;
|
|
45
47
|
readonly getBootSessionId: () => string;
|
|
46
|
-
readonly isPidOurProcess: (pid: number) => Nullable<boolean>;
|
|
47
48
|
readonly isProcessRunning: (pid: number) => boolean;
|
|
48
49
|
readonly now: () => number;
|
|
49
50
|
}
|
|
@@ -82,16 +83,26 @@ export declare function release(filePath: string, ctx?: RuntimeIdentityContext):
|
|
|
82
83
|
* @param filePath - The absolute path to the identity file.
|
|
83
84
|
*/
|
|
84
85
|
export declare function forceRelease(filePath: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Fingerprints a command line as the identity record stores it: the lowercase hex sha256 digest of the trimmed text. It is the one normalization of a command
|
|
88
|
+
* line, applied at the claim and at inspect alike, which is why it lives here rather than in the context: the platforms report surrounding whitespace
|
|
89
|
+
* differently, and trimming the claim's reading and inspect's reading alike keeps a holder's command line matching its own record.
|
|
90
|
+
* @param commandLine - The command line as the process table reported it, or null when the table had no row for the process.
|
|
91
|
+
* @returns The fingerprint, or null when there is no command line to fingerprint.
|
|
92
|
+
*/
|
|
93
|
+
export declare function fingerprintCommandLine(commandLine: Nullable<string>): Nullable<string>;
|
|
85
94
|
/**
|
|
86
95
|
* Serializes a record to its on-disk representation. The first line is the bare PID for backwards compatibility with shell tooling; subsequent lines are
|
|
87
|
-
* key=value pairs in deterministic order. The trailing newline keeps the file
|
|
96
|
+
* key=value pairs in deterministic order, the commandHash line written only when the record carries a fingerprint. The trailing newline keeps the file
|
|
97
|
+
* well-formed for POSIX text-file tools.
|
|
88
98
|
* @param record - The identity record to serialize.
|
|
89
99
|
* @returns The serialized payload.
|
|
90
100
|
*/
|
|
91
101
|
export declare function serializeRecord(record: IdentityRecord): string;
|
|
92
102
|
/**
|
|
93
|
-
* Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record
|
|
94
|
-
*
|
|
103
|
+
* Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record: a first line that is not a
|
|
104
|
+
* positive integer PID, or a boot session that is missing or empty. A commandHash that is not a well-formed fingerprint reads as absent rather than refusing the
|
|
105
|
+
* record, and unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
|
|
95
106
|
* @param raw - The raw file contents.
|
|
96
107
|
* @returns The parsed record, or null when the payload is unusable.
|
|
97
108
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { clearPidFile } from "./pid.js";
|
|
2
2
|
import { createDefaultRuntimeIdentityContext } from "./runtimeIdentity.context.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
3
4
|
import fs from "node:fs";
|
|
4
5
|
/**
|
|
5
6
|
* Inspects the identity file at the given path and reports the current state. Reads the file, parses the record, and combines boot session match with PID
|
|
@@ -18,8 +19,11 @@ export function inspect(filePath, ctx = createDefaultRuntimeIdentityContext()) {
|
|
|
18
19
|
if (error.code === "ENOENT") {
|
|
19
20
|
return { kind: "free" };
|
|
20
21
|
}
|
|
21
|
-
// Any other read error (EACCES, EIO, ...) is reported as malformed-with-empty-raw so
|
|
22
|
-
//
|
|
22
|
+
// Any other read error (EACCES, EIO, ...) is reported as malformed-with-empty-raw, so claim() takes the overwrite path rather than crashing. Like a record
|
|
23
|
+
// that fails to parse, this downgrade is made without proof that the holder is gone, a deliberate exception to the header's rule that unconfirmed identity
|
|
24
|
+
// keeps held-live: an unreadable file holds no record to confirm, so keeping held-live would refuse every startup until the file was repaired by hand. The
|
|
25
|
+
// overwrite either throws, when the temp write or the rename is refused, or replaces the file, and if a holder is still running behind it, this startup
|
|
26
|
+
// meets the port bind the concurrency note describes.
|
|
23
27
|
return { kind: "stale-malformed", raw: "" };
|
|
24
28
|
}
|
|
25
29
|
const record = parseRecord(raw);
|
|
@@ -32,12 +36,14 @@ export function inspect(filePath, ctx = createDefaultRuntimeIdentityContext()) {
|
|
|
32
36
|
if (!ctx.isProcessRunning(record.pid)) {
|
|
33
37
|
return { kind: "stale-dead-pid", record };
|
|
34
38
|
}
|
|
35
|
-
// The PID is alive and the boot session matches, but within a single boot the kernel can reassign a freed PID to
|
|
36
|
-
// SIGKILLed.
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
39
|
+
// The PID is alive and the boot session matches, but within a single boot the kernel can reassign a freed PID to another program after PrismCast was
|
|
40
|
+
// SIGKILLed. The record carries the fingerprint of its writer's command line, so a live process at that PID whose command line fingerprints differently is
|
|
41
|
+
// another program, the writer is gone, and the slot is stale. We classify that case as stale-dead-pid rather than a new branch because the operational meaning
|
|
42
|
+
// is identical and callers already overwrite that state. Only that positive proof downgrades the slot: a record with no fingerprint reads no process table, and
|
|
43
|
+
// a PID whose command line the table cannot report keeps the held-live verdict, because downgrading a possibly-live holder is the only path to two concurrent
|
|
44
|
+
// instances.
|
|
45
|
+
const liveHash = (record.commandHash === null) ? null : fingerprintCommandLine(ctx.commandLineOf(record.pid));
|
|
46
|
+
if ((liveHash !== null) && (liveHash !== record.commandHash)) {
|
|
41
47
|
return { kind: "stale-dead-pid", record };
|
|
42
48
|
}
|
|
43
49
|
return { kind: "held-live", record };
|
|
@@ -58,6 +64,7 @@ export function claim(filePath, metadata, ctx = createDefaultRuntimeIdentityCont
|
|
|
58
64
|
}
|
|
59
65
|
const record = {
|
|
60
66
|
bootId: ctx.getBootSessionId(),
|
|
67
|
+
commandHash: fingerprintCommandLine(ctx.commandLineOf(process.pid)),
|
|
61
68
|
pid: process.pid,
|
|
62
69
|
startedAt: new Date(ctx.now()).toISOString(),
|
|
63
70
|
version: metadata.version
|
|
@@ -89,21 +96,38 @@ export function release(filePath, ctx = createDefaultRuntimeIdentityContext()) {
|
|
|
89
96
|
export function forceRelease(filePath) {
|
|
90
97
|
clearPidFile(filePath, "identity");
|
|
91
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Fingerprints a command line as the identity record stores it: the lowercase hex sha256 digest of the trimmed text. It is the one normalization of a command
|
|
101
|
+
* line, applied at the claim and at inspect alike, which is why it lives here rather than in the context: the platforms report surrounding whitespace
|
|
102
|
+
* differently, and trimming the claim's reading and inspect's reading alike keeps a holder's command line matching its own record.
|
|
103
|
+
* @param commandLine - The command line as the process table reported it, or null when the table had no row for the process.
|
|
104
|
+
* @returns The fingerprint, or null when there is no command line to fingerprint.
|
|
105
|
+
*/
|
|
106
|
+
export function fingerprintCommandLine(commandLine) {
|
|
107
|
+
const text = commandLine?.trim() ?? "";
|
|
108
|
+
if (text === "") {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return createHash("sha256").update(text).digest("hex");
|
|
112
|
+
}
|
|
92
113
|
/**
|
|
93
114
|
* Serializes a record to its on-disk representation. The first line is the bare PID for backwards compatibility with shell tooling; subsequent lines are
|
|
94
|
-
* key=value pairs in deterministic order. The trailing newline keeps the file
|
|
115
|
+
* key=value pairs in deterministic order, the commandHash line written only when the record carries a fingerprint. The trailing newline keeps the file
|
|
116
|
+
* well-formed for POSIX text-file tools.
|
|
95
117
|
* @param record - The identity record to serialize.
|
|
96
118
|
* @returns The serialized payload.
|
|
97
119
|
*/
|
|
98
120
|
export function serializeRecord(record) {
|
|
99
121
|
return String(record.pid) + "\n" +
|
|
100
122
|
"bootId=" + record.bootId + "\n" +
|
|
123
|
+
((record.commandHash === null) ? "" : "commandHash=" + record.commandHash + "\n") +
|
|
101
124
|
"startedAt=" + record.startedAt + "\n" +
|
|
102
125
|
"version=" + record.version + "\n";
|
|
103
126
|
}
|
|
104
127
|
/**
|
|
105
|
-
* Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record
|
|
106
|
-
*
|
|
128
|
+
* Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record: a first line that is not a
|
|
129
|
+
* positive integer PID, or a boot session that is missing or empty. A commandHash that is not a well-formed fingerprint reads as absent rather than refusing the
|
|
130
|
+
* record, and unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
|
|
107
131
|
* @param raw - The raw file contents.
|
|
108
132
|
* @returns The parsed record, or null when the payload is unusable.
|
|
109
133
|
*/
|
|
@@ -118,11 +142,15 @@ export function parseRecord(raw) {
|
|
|
118
142
|
if (firstLine === undefined) {
|
|
119
143
|
return null;
|
|
120
144
|
}
|
|
121
|
-
|
|
122
|
-
|
|
145
|
+
// The PID is a required field, so a first line that is not all digits, or whose value is zero, names no process and the record is malformed. Reading the line
|
|
146
|
+
// whole, rather than by its leading digits, keeps a corrupt line from naming whatever PID its digits happen to spell.
|
|
147
|
+
const pidText = firstLine.trim();
|
|
148
|
+
const pid = Number(pidText);
|
|
149
|
+
if (!/^\d+$/.test(pidText) || (pid <= 0)) {
|
|
123
150
|
return null;
|
|
124
151
|
}
|
|
125
152
|
let bootId = null;
|
|
153
|
+
let commandHash = null;
|
|
126
154
|
let startedAt = "";
|
|
127
155
|
let version = "";
|
|
128
156
|
for (let i = 1; i < lines.length; i++) {
|
|
@@ -145,6 +173,11 @@ export function parseRecord(raw) {
|
|
|
145
173
|
bootId = value;
|
|
146
174
|
break;
|
|
147
175
|
}
|
|
176
|
+
// Only a sha256 digest in lowercase hex is a fingerprint fingerprintCommandLine could have written, so any other value reads as no fingerprint at all.
|
|
177
|
+
case "commandHash": {
|
|
178
|
+
commandHash = /^[0-9a-f]{64}$/.test(value) ? value : null;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
148
181
|
case "startedAt": {
|
|
149
182
|
startedAt = value;
|
|
150
183
|
break;
|
|
@@ -158,12 +191,12 @@ export function parseRecord(raw) {
|
|
|
158
191
|
}
|
|
159
192
|
}
|
|
160
193
|
}
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
if (bootId === null) {
|
|
194
|
+
// The boot session is the other required field. A file without one, or with an empty one, gives the state machine nothing to compare against the current
|
|
195
|
+
// boot, whether an external tool or a PrismCast that predates the identity record wrote it or it is corrupt, so it is treated as malformed.
|
|
196
|
+
if ((bootId === null) || (bootId === "")) {
|
|
164
197
|
return null;
|
|
165
198
|
}
|
|
166
|
-
return { bootId, pid, startedAt, version };
|
|
199
|
+
return { bootId, commandHash, pid, startedAt, version };
|
|
167
200
|
}
|
|
168
201
|
/**
|
|
169
202
|
* Persists a record to disk via atomic write (write-temp + rename). On POSIX rename is atomic within a filesystem; on Windows the rename is best-effort but
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeIdentity.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtimeIdentity.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prismcast",
|
|
3
3
|
"displayName": "PrismCast",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.14.0",
|
|
5
5
|
"description": "Browser-based live TV capture server for Channels DVR, Plex, and other streaming clients.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "HJD",
|
|
@@ -79,20 +79,20 @@
|
|
|
79
79
|
"morgan": "1.12.1",
|
|
80
80
|
"puppeteer-core": "24.43.1",
|
|
81
81
|
"puppeteer-stream": "3.0.23",
|
|
82
|
-
"ws": "8.
|
|
82
|
+
"ws": "8.22.0"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@stylistic/eslint-plugin": "5.10.0",
|
|
86
86
|
"@types/compression": "1.8.1",
|
|
87
87
|
"@types/express": "5.0.6",
|
|
88
88
|
"@types/morgan": "1.9.10",
|
|
89
|
-
"@types/node": "26.6.
|
|
90
|
-
"@types/ws": "8.18.
|
|
89
|
+
"@types/node": "26.6.4",
|
|
90
|
+
"@types/ws": "8.18.2",
|
|
91
91
|
"eslint": "9.39.2",
|
|
92
92
|
"happy-dom": "20.14.5",
|
|
93
93
|
"nodemon": "3.1.14",
|
|
94
94
|
"typescript": "5.9.3",
|
|
95
|
-
"typescript-eslint": "8.
|
|
95
|
+
"typescript-eslint": "8.71.1"
|
|
96
96
|
},
|
|
97
97
|
"allowScripts": {
|
|
98
98
|
"ffmpeg-for-homebridge": true
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deviceId.js","sourceRoot":"","sources":["../../src/hdhr/deviceId.ts"],"names":[],"mappings":"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"}
|