prismcast 1.10.0 → 1.10.2
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.js +6 -2
- package/dist/app.js.map +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/tuning/hbo.js +31 -123
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.js +70 -7
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/video.js +1 -1
- package/dist/browser/video.js.map +1 -1
- package/dist/config/index.d.ts +6 -2
- package/dist/config/index.js +35 -21
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +26 -0
- package/dist/config/paths.js +51 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/presets.js +2 -2
- package/dist/config/presets.js.map +1 -1
- package/dist/config/profiles.js +6 -6
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/userChannels.js +1 -1
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.js +1 -1
- package/dist/hdhr/discover.js +3 -4
- package/dist/hdhr/discover.js.map +1 -1
- package/dist/identity.d.ts +2 -0
- package/dist/identity.js +19 -0
- package/dist/identity.js.map +1 -0
- package/dist/routes/cdp.d.ts +171 -0
- package/dist/routes/cdp.js +702 -0
- package/dist/routes/cdp.js.map +1 -0
- package/dist/routes/config/services.js +1 -1
- package/dist/routes/config/services.js.map +1 -1
- package/dist/routes/index.js +2 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/root/index.js +13 -19
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/status.js +11 -3
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/service/commands.context.js +2 -2
- package/dist/service/commands.context.js.map +1 -1
- package/dist/service/commands.d.ts +1 -1
- package/dist/service/commands.js +1 -10
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.context.js +2 -1
- package/dist/service/generators.context.js.map +1 -1
- package/dist/service/generators.js +4 -9
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/clients.js +3 -11
- package/dist/streaming/clients.js.map +1 -1
- package/dist/streaming/fmp4Segmenter.js +1 -1
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.js +1 -1
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/mpegts.js +1 -1
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/setup.js +6 -6
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.js +2 -4
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/utils/debugFilter.js +1 -0
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/fileLogger.js +3 -3
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/format.js +3 -3
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.js +53 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/markup.d.ts +12 -0
- package/dist/utils/markup.js +54 -0
- package/dist/utils/markup.js.map +1 -0
- package/dist/utils/morganStream.js +1 -1
- package/dist/utils/morganStream.js.map +1 -1
- package/dist/utils/network.d.ts +8 -0
- package/dist/utils/network.js +22 -0
- package/dist/utils/network.js.map +1 -0
- package/dist/utils/platform.d.ts +0 -27
- package/dist/utils/platform.js +0 -57
- package/dist/utils/platform.js.map +1 -1
- package/package.json +8 -6
- package/dist/utils/html.d.ts +0 -6
- package/dist/utils/html.js +0 -22
- package/dist/utils/html.js.map +0 -1
package/dist/identity.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* identity.ts: Project-wide identity constants for PrismCast.
|
|
4
|
+
*/
|
|
5
|
+
/* This module is the single source of truth for the values other modules need to refer to PrismCast by name: the reverse-DNS service identifier launchd plists
|
|
6
|
+
* and systemd units carry, and the human-readable product name UI surfaces display. It sits at the root of src/ - below config, utils, service, and every other
|
|
7
|
+
* subsystem - because both the path-resolution layer (config/paths.ts, which uses SERVICE_ID in the macOS LaunchAgents path) and the service-generation layer
|
|
8
|
+
* (service/generators.ts, which embeds both values in plist and unit files) consume it. Placing it inside either of those subsystems would force the other to
|
|
9
|
+
* import sideways across a boundary it otherwise respects; lifting it to a dedicated root-level identity module preserves the layering and gives the constants
|
|
10
|
+
* a home that names what they are rather than where they happened to first be used.
|
|
11
|
+
*/
|
|
12
|
+
// The reverse-DNS service identifier. macOS launchd uses this for the bundle name, the LaunchAgents plist file name, and the Label key inside the plist itself.
|
|
13
|
+
// Linux systemd and Windows Task Scheduler do not require reverse-DNS form, but the generators still quote this value in the unit/task definitions so users see
|
|
14
|
+
// a consistent identifier across platforms when inspecting or removing the installed service.
|
|
15
|
+
export const SERVICE_ID = "com.github.hjdhjd.prismcast";
|
|
16
|
+
// The human-readable product name. Surfaced in UI labels, in the service-install command output, and as the display name on platforms whose service managers
|
|
17
|
+
// distinguish "internal identifier" from "shown name" (Windows Task Scheduler being the clearest example).
|
|
18
|
+
export const SERVICE_NAME = "PrismCast";
|
|
19
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,gKAAgK;AAChK,gKAAgK;AAChK,8FAA8F;AAC9F,MAAM,CAAC,MAAM,UAAU,GAAG,6BAA6B,CAAC;AAExD,6JAA6J;AAC7J,2GAA2G;AAC3G,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import type { Browser } from "puppeteer-core";
|
|
2
|
+
import type { Express } from "express";
|
|
3
|
+
import type { Server as HttpServer } from "node:http";
|
|
4
|
+
import { WebSocket } from "ws";
|
|
5
|
+
/**
|
|
6
|
+
* Per-WebSocket CDP proxy state. One instance per attached client. Owns the browser-level CDPSession, the per-target sub-session map, and the lifecycle
|
|
7
|
+
* subscriptions to the Browser. Cleans up on WS close, target destruction, or browser disconnect. Exported for unit testing - production callers receive
|
|
8
|
+
* instances via the upgrade handler and do not construct them directly.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CdpProxySession {
|
|
11
|
+
private browserSession;
|
|
12
|
+
private connection;
|
|
13
|
+
private readonly sessions;
|
|
14
|
+
private readonly sessionToTargetId;
|
|
15
|
+
private readonly originalEmits;
|
|
16
|
+
private nextSessionSerial;
|
|
17
|
+
private discoverTargets;
|
|
18
|
+
private autoAttach;
|
|
19
|
+
private attached;
|
|
20
|
+
private onBrowserDisconnect;
|
|
21
|
+
private readonly ws;
|
|
22
|
+
private readonly browser;
|
|
23
|
+
constructor(ws: WebSocket, browser: Browser);
|
|
24
|
+
/**
|
|
25
|
+
* Initializes the per-connection CDP plumbing: registers the WebSocket lifecycle handlers, subscribes to the browser's disconnect event, opens a browser-level
|
|
26
|
+
* CDPSession, captures the underlying Connection, and subscribes to CDP target events. Any failure during async setup is caught by the WS close handler
|
|
27
|
+
* (registered first), which fires when `closeWith()` closes the socket and routes cleanup through the same path the happy-path teardown takes. This invariant
|
|
28
|
+
* - lifecycle handlers wired before any async operation that can fail - is what guarantees the session is torn down (including its disconnect listener)
|
|
29
|
+
* regardless of where setup aborts. Handler bodies are null-safe so an early message arriving before browserSession is set produces a clean error frame rather
|
|
30
|
+
* than a crash.
|
|
31
|
+
*/
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Closes the WS with a code/reason and triggers cleanup. Safe to call when the WS is already closed.
|
|
35
|
+
* @param code - WebSocket close code (1000 normal, 1001 going-away, 1011 internal-error).
|
|
36
|
+
* @param reason - Human-readable reason.
|
|
37
|
+
*/
|
|
38
|
+
closeWith(code: number, reason: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Handles a CDP message received over the WebSocket. Parses the JSON, dispatches to the browser-level or target-level handler, and forwards the response.
|
|
41
|
+
* Malformed JSON is silently dropped (the wire protocol has no error frame for that case at the client's level).
|
|
42
|
+
* @param data - The raw WebSocket message data.
|
|
43
|
+
*/
|
|
44
|
+
private handleClientMessage;
|
|
45
|
+
/**
|
|
46
|
+
* Dispatches a browser-level CDP command. Intercepts the Target domain to synthesize its semantics on top of Puppeteer's Browser API; passes everything else
|
|
47
|
+
* through to the browser session.
|
|
48
|
+
* @param msg - The parsed CDP request.
|
|
49
|
+
*/
|
|
50
|
+
private handleBrowserMessage;
|
|
51
|
+
/**
|
|
52
|
+
* Dispatches a message addressed to a specific sub-session. Looks up the CDPSession by synthetic sessionId and forwards. Unknown sessionId yields a CDP error
|
|
53
|
+
* response so the client sees a clean failure rather than silently dropping.
|
|
54
|
+
* @param msg - The parsed CDP request with a sessionId.
|
|
55
|
+
*/
|
|
56
|
+
private handleTargetMessage;
|
|
57
|
+
/**
|
|
58
|
+
* Forwards a CDP command to a session and sends the response (or error) back to the client. The sessionId on the response is the one the client provided so
|
|
59
|
+
* the client can correlate.
|
|
60
|
+
* @param msg - The parsed CDP request.
|
|
61
|
+
* @param session - The CDP session to forward to.
|
|
62
|
+
*/
|
|
63
|
+
private passthrough;
|
|
64
|
+
/**
|
|
65
|
+
* Handles Target.setDiscoverTargets. When enabled, emits Target.targetCreated for every existing target so the client's view of the world matches Chrome's;
|
|
66
|
+
* targetcreated / targetdestroyed events thereafter flow via the Browser event subscriptions.
|
|
67
|
+
* @param msg - The parsed CDP request.
|
|
68
|
+
*/
|
|
69
|
+
private handleSetDiscoverTargets;
|
|
70
|
+
/**
|
|
71
|
+
* Handles Target.setAutoAttach. When enabled, creates a per-target CDPSession for every existing target, generates a synthetic sessionId, and emits
|
|
72
|
+
* Target.attachedToTarget for each. Subsequent new targets attach via the targetcreated lifecycle hook.
|
|
73
|
+
* @param msg - The parsed CDP request.
|
|
74
|
+
*/
|
|
75
|
+
private handleSetAutoAttach;
|
|
76
|
+
/**
|
|
77
|
+
* Handles Target.attachToTarget. Looks up the target's info via the browser session, creates a Puppeteer CDPSession via Connection.createSession (the public
|
|
78
|
+
* API for attaching to a target by id), generates a synthetic sessionId, and returns it. The client uses that sessionId for subsequent messages.
|
|
79
|
+
* @param msg - The parsed CDP request.
|
|
80
|
+
*/
|
|
81
|
+
private handleAttachToTarget;
|
|
82
|
+
/**
|
|
83
|
+
* Attaches to a target given its TargetInfo: creates a Puppeteer CDPSession via Connection.createSession, generates a synthetic sessionId, wires event
|
|
84
|
+
* forwarding, and optionally emits Target.attachedToTarget for the client. Returns the sessionId so callers (manual attach via Target.attachToTarget) can
|
|
85
|
+
* include it in their response.
|
|
86
|
+
* @param targetInfo - The CDP TargetInfo identifying the target.
|
|
87
|
+
* @param options - emitEvent: whether to emit Target.attachedToTarget after attach (defaults to true; manual attach sets false and returns the sessionId via
|
|
88
|
+
* the original response).
|
|
89
|
+
* @returns The synthetic sessionId for the newly-attached session.
|
|
90
|
+
*/
|
|
91
|
+
private attachToTargetInfo;
|
|
92
|
+
/**
|
|
93
|
+
* Handles Target.detachFromTarget. Looks up the session by sessionId, detaches it, emits Target.detachedFromTarget, and removes from the map.
|
|
94
|
+
* @param msg - The parsed CDP request.
|
|
95
|
+
*/
|
|
96
|
+
private handleDetachFromTarget;
|
|
97
|
+
/**
|
|
98
|
+
* Detaches a sub-session by its synthetic sessionId, restoring the patched emit, calling CDPSession.detach() (best-effort - the session may already be gone if
|
|
99
|
+
* the target closed), and emitting Target.detachedFromTarget so the client's view is consistent.
|
|
100
|
+
* @param sessionId - The synthetic sessionId.
|
|
101
|
+
*/
|
|
102
|
+
private detachSessionById;
|
|
103
|
+
/**
|
|
104
|
+
* Handles the CDP `Target.targetCreated` event emitted by the browser session. When autoAttach is on, mints a Puppeteer CDPSession for the new target and emits
|
|
105
|
+
* a synthetic Target.attachedToTarget to the client. Whether the client also sees the Target.targetCreated event is decided by the wildcard forwarder (which
|
|
106
|
+
* gates Target.* events on this.discoverTargets).
|
|
107
|
+
* @param event - The CDP event payload.
|
|
108
|
+
*/
|
|
109
|
+
private handleCdpTargetCreated;
|
|
110
|
+
/**
|
|
111
|
+
* Handles the CDP `Target.targetDestroyed` event emitted by the browser session. Detaches every sub-session attached to this targetId and emits the
|
|
112
|
+
* corresponding Target.detachedFromTarget events. The targetId on the CDP event matches exactly what we stored in sessionToTargetId at attach time, so there is
|
|
113
|
+
* no fuzzy matching - this is the lookup the Puppeteer-level targetdestroyed event could not give us.
|
|
114
|
+
* @param event - The CDP event payload.
|
|
115
|
+
*/
|
|
116
|
+
private handleCdpTargetDestroyed;
|
|
117
|
+
/**
|
|
118
|
+
* Attaches a wildcard event listener to a CDPSession. Each CDP-domain event (matched by the "Domain.event" naming pattern - uppercase first letter, dot,
|
|
119
|
+
* lowercase next letter) is forwarded to the WS client after the session's own listeners have run, so any internal state mutation (e.g. cleanup driven by
|
|
120
|
+
* Target.targetDestroyed) is settled before the client sees the event. Target.* events are gated on this.discoverTargets so a client that has not subscribed
|
|
121
|
+
* to the Target domain does not receive its events even though our internal subscription stays on.
|
|
122
|
+
*
|
|
123
|
+
* Implementation note. CDPSession exposes no public "subscribe to every event" hook, so we monkey-patch the EventEmitter.emit method. The patch saves the
|
|
124
|
+
* original so detachEventListener can restore it cleanly. Order of operations inside the patch is: dispatch through original first (specific listeners fire,
|
|
125
|
+
* including the internal Target.* handlers we registered), then forward to the client. This ordering avoids the race where the client receives an event tied
|
|
126
|
+
* to state we haven't yet cleaned up.
|
|
127
|
+
*
|
|
128
|
+
* @param session - The CDP session to monitor.
|
|
129
|
+
* @param sessionId - The synthetic sessionId to include in the forwarded events (null for browser-level events).
|
|
130
|
+
*/
|
|
131
|
+
private attachEventListener;
|
|
132
|
+
/**
|
|
133
|
+
* Restores the original emit on a session, undoing attachEventListener. Called on detach / cleanup.
|
|
134
|
+
* @param session - The CDP session whose emit to restore.
|
|
135
|
+
*/
|
|
136
|
+
private detachEventListener;
|
|
137
|
+
/**
|
|
138
|
+
* Sends a CDP wire response back to the client.
|
|
139
|
+
* @param response - The response object.
|
|
140
|
+
*/
|
|
141
|
+
private sendResponse;
|
|
142
|
+
/**
|
|
143
|
+
* Sends a CDP wire event back to the client.
|
|
144
|
+
* @param event - The event object.
|
|
145
|
+
*/
|
|
146
|
+
private sendEvent;
|
|
147
|
+
/**
|
|
148
|
+
* Serializes a frame and writes it to the WS, swallowing errors that arise from a closed socket. We do not retry; if the WS is closed, the proxy session is
|
|
149
|
+
* already on its way to cleanup.
|
|
150
|
+
* @param frame - The frame to send.
|
|
151
|
+
*/
|
|
152
|
+
private sendRaw;
|
|
153
|
+
/**
|
|
154
|
+
* Detaches every sub-session, restores patched emits, and unsubscribes from the browser-disconnect event. Safe to call multiple times: detach of an
|
|
155
|
+
* already-detached CDPSession is a no-op, and the disconnect-listener field is cleared after the first removal so a repeat call is a no-op too. Triggered by
|
|
156
|
+
* WS close, WS error, or closeWith().
|
|
157
|
+
*/
|
|
158
|
+
cleanup(): Promise<void>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Configures the /cdp/json/version, /cdp/json, and /cdp/json/list discovery endpoints on the Express app. Each handler checks isCategoryEnabled("cdp") at request
|
|
162
|
+
* time and returns 404 when CDP is disabled, so the surface appears and disappears in sync with the toggle in /debug without requiring a restart.
|
|
163
|
+
* @param app - The Express application.
|
|
164
|
+
*/
|
|
165
|
+
export declare function setupCdpEndpoint(app: Express): void;
|
|
166
|
+
/**
|
|
167
|
+
* Attaches the WebSocket upgrade handler for /cdp/devtools/* paths to the given HTTP server. Called from startServer after app.listen() returns the server.
|
|
168
|
+
* Upgrades for paths outside /cdp/devtools/ are ignored (left to any other upgrade handler).
|
|
169
|
+
* @param server - The Node HTTP server.
|
|
170
|
+
*/
|
|
171
|
+
export declare function attachCdpUpgradeHandler(server: HttpServer): void;
|