@tidal-music/player-web-components 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/active-device-changed-BDbOSq7P-DQ6vFR_K.js +7 -0
  2. package/dist/active-device-mode-changed-OmLVES_4-zwN5exje.js +7 -0
  3. package/dist/audio-context-store-Bf50rcqa-DUuCXOzU.js +36 -0
  4. package/dist/basePlayer-D9LFxFnB-BNIKxMHD.js +380 -0
  5. package/dist/browserPlayer-BzBNrx-C-DjxeaFTq.js +170 -0
  6. package/dist/generate-guid-BMGZjV-R-D16yCCHx.js +1716 -0
  7. package/dist/index.js +368 -10
  8. package/dist/load-L6Urw8gV-CQAMBwcN.js +29443 -0
  9. package/dist/media-element-error-circuit-breaker-BUJbK6sd-DNlFckiw.js +22 -0
  10. package/dist/nativePlayer-DtYpfmo5-nNN5yO4E.js +232 -0
  11. package/dist/output-devices-CPJfYcO--BP7JMB6k.js +156 -0
  12. package/dist/pushkin-C7W2HCqN-BHqS8oLX.js +117 -0
  13. package/dist/pushkin-dg1sQNx0-CAPg-zq7.js +2 -0
  14. package/dist/shakaPlayer-CqIY64ST-BhwOXSvi.js +1448 -0
  15. package/dist/src/helpers.d.ts +18 -0
  16. package/dist/src/index.d.ts +7 -0
  17. package/dist/src/tidal-current-time.d.ts +9 -0
  18. package/dist/src/tidal-duration-time.d.ts +9 -0
  19. package/dist/src/tidal-play-trigger.d.ts +2 -0
  20. package/dist/src/tidal-progress-bar.d.ts +2 -0
  21. package/dist/src/tidal-video-view.d.ts +2 -0
  22. package/dist/state-BT7sE_jc-iVaBwnBC.js +210 -0
  23. package/package.json +15 -13
  24. package/dist/_commonjsHelpers-DaMA6jEr-DtILRGNx.js +0 -8
  25. package/dist/basePlayer-Rqi9yRuo-4eKn-Akv.js +0 -528
  26. package/dist/browserPlayer-CXURpXdL-DjOb2ySS.js +0 -259
  27. package/dist/index-DHnVYeec.js +0 -3391
  28. package/dist/index.d.ts +0 -24
  29. package/dist/nativePlayer-b92CavhC-CABrQPGS.js +0 -323
  30. package/dist/output-devices-CUurcKto-C_F_9nLk.js +0 -224
  31. package/dist/shakaPlayer-D0NCOzx8-Dd1YFBoR.js +0 -24403
@@ -0,0 +1,22 @@
1
+ import { a as e, n as t } from "./state-BT7sE_jc-iVaBwnBC.js";
2
+ import { t as n } from "./pushkin-C7W2HCqN-BHqS8oLX.js";
3
+ //#region ../player/dist/media-element-error-circuit-breaker-BUJbK6sd.js
4
+ var r = 6e4, i = (e) => {
5
+ console.error("HTMLMediaElement errored", e.target?.error ?? null);
6
+ }, a = () => {
7
+ console.error("HTMLMediaElement error limit reached, suppressing further errors"), e.dispatchError(new t("EUnexpected", "ME01"));
8
+ };
9
+ function o(e = {}) {
10
+ let { errorWindowMs: t = r, log: o = i, maxErrors: s = 10, now: c = () => n.now(), onLimitReached: l = a } = e, u = 0, d = 0;
11
+ return {
12
+ handleError(e) {
13
+ let n = c();
14
+ n - d >= t && (u = 0), d = n, u += 1, u <= s && o(e), u === s && l();
15
+ },
16
+ reset() {
17
+ u = 0, d = 0;
18
+ }
19
+ };
20
+ }
21
+ //#endregion
22
+ export { o as t };
@@ -0,0 +1,232 @@
1
+ import { a as e, i as t, n, t as r, u as i } from "./state-BT7sE_jc-iVaBwnBC.js";
2
+ import { t as a } from "./pushkin-C7W2HCqN-BHqS8oLX.js";
3
+ import { a as o } from "./load-L6Urw8gV-CQAMBwcN.js";
4
+ import { t as s } from "./active-device-mode-changed-OmLVES_4-zwN5exje.js";
5
+ import { t as c } from "./active-device-changed-BDbOSq7P-DQ6vFR_K.js";
6
+ import { n as l, r as u, t as d } from "./basePlayer-D9LFxFnB-BNIKxMHD.js";
7
+ //#region ../player/dist/nativePlayer-DtYpfmo5.js
8
+ var f = "active-device-disconnected";
9
+ function p() {
10
+ return new CustomEvent(f);
11
+ }
12
+ var m = {
13
+ file_checksum_mismatch: "NPO02",
14
+ no_such_file: "NPO01",
15
+ unreadable_file: "NPO03"
16
+ }, h = {
17
+ devicedisconnected: "NPD01",
18
+ deviceexclusivemodenotallowed: "NPD02",
19
+ deviceformatnotsupported: "NPD03",
20
+ devicelocked: "NPD04",
21
+ devicenotfound: "NPD05",
22
+ deviceunknownerror: "NPD00"
23
+ }, g, _ = class extends d {
24
+ #e = "default";
25
+ #t;
26
+ #n;
27
+ #r;
28
+ name = "nativePlayer";
29
+ playbackEngineHandlerAttached = !1;
30
+ constructor() {
31
+ super(), i("outputDevicesEnabled") && (async () => {
32
+ g = (await import("./output-devices-CPJfYcO--BP7JMB6k.js")).outputDevices, this.#n.listDevices();
33
+ })(), this.#n = window.NativePlayerComponent.Player(), this.playbackState = "IDLE", this.registerEventListeners(), this.#n.setVolume(100);
34
+ }
35
+ #i(t) {
36
+ e.dispatchError(new n("EUnexpected", h[t]));
37
+ }
38
+ #a(t) {
39
+ this.debugLog("handleMediaError", t.target);
40
+ let r = m[t.target.errorCode];
41
+ this.currentStreamingSessionId && o({
42
+ errorCode: r,
43
+ errorMessage: JSON.stringify(t.target),
44
+ streamingSessionId: this.currentStreamingSessionId
45
+ }), e.dispatchError(new n("EUnexpected", r));
46
+ }
47
+ #o(e) {
48
+ switch (this.debugLog("handleNativePlayerStateChange", e), e) {
49
+ case "active":
50
+ this.playbackState = "PLAYING";
51
+ break;
52
+ case "idle":
53
+ case "seeking":
54
+ this.playbackState = "STALLED";
55
+ break;
56
+ case "paused":
57
+ case "ready":
58
+ this.playbackState = "NOT_PLAYING";
59
+ break;
60
+ case "stopped":
61
+ this.playbackState = "NOT_PLAYING";
62
+ break;
63
+ case "uninitialized":
64
+ this.playbackState = "IDLE";
65
+ break;
66
+ default:
67
+ this.debugLog("No handling for state", e);
68
+ break;
69
+ }
70
+ }
71
+ async #s() {
72
+ this.debugLog("handleNetworkError");
73
+ let t = a.timestamp("streaming_metrics:playback_statistics:actualStartTimestamp");
74
+ if ((t === void 0 ? 0 : Math.abs(a.now() - t)) >= 36e5) {
75
+ let e = structuredClone(this.currentMediaProduct), t = this.currentTime;
76
+ this.finishCurrentMediaProduct("error"), e && (await this.hardReload(e, t), await this.play());
77
+ return;
78
+ }
79
+ await Promise.race([this.mediaStateChange("idle"), new Promise((e) => {
80
+ window.addEventListener("online", () => e("online"));
81
+ })]) === "idle" && e.dispatchError(new n("PENetwork", "NPN01"));
82
+ }
83
+ abandon() {
84
+ g?.deviceMode === "exclusive" && this.#n.selectSystemDevice();
85
+ }
86
+ getPosition() {
87
+ return this.currentTime;
88
+ }
89
+ async handleAutomaticTransitionToPreloadedMediaProduct() {
90
+ await this.nativeEvent("mediaduration"), this.#r = void 0;
91
+ let n = t.getMediaProductTransition(this.preloadedStreamingSessionId);
92
+ if (!n) {
93
+ console.warn("No media product transition saved for next item. Stopping playback."), this.playbackState = "NOT_PLAYING";
94
+ return;
95
+ }
96
+ let { mediaProduct: r, playbackContext: i } = n, a = {
97
+ ...i,
98
+ actualDuration: this.#t
99
+ };
100
+ this.preloadedStreamingSessionId && t.saveMediaProductTransition(this.preloadedStreamingSessionId, {
101
+ mediaProduct: r,
102
+ playbackContext: a
103
+ }), await this.mediaStateChange("active"), e.dispatchEvent(l(r, a)), this.currentStreamingSessionId = this.preloadedStreamingSessionId, this.mediaProductStarted(this.currentStreamingSessionId);
104
+ }
105
+ async load(n, r) {
106
+ this.debugLog("load", n), this.currentTime = n.assetPosition, this.startAssetPosition = n.assetPosition, await this.reset();
107
+ let { assetPosition: i, mediaProduct: a, playbackInfo: o, streamInfo: s } = n, { securityToken: c, streamFormat: d, streamUrl: f } = s;
108
+ this.currentStreamingSessionId = s.streamingSessionId, r === "explicit" && (this.playbackState = "NOT_PLAYING");
109
+ let p = this.nativeEvent("mediaduration");
110
+ if (d) this.#n.load(f, d, c);
111
+ else throw Error("Stream format is undefined.");
112
+ if (await p, this.currentStreamingSessionId !== s.streamingSessionId) return;
113
+ this.debugLog("load() duration is", this.#t), i !== 0 && i < this.#t ? (async () => {
114
+ await this.mediaStateChange("active"), this.currentStreamingSessionId === s.streamingSessionId && (await this.seek(i), this.currentTime = i);
115
+ })().catch(console.error) : this.currentTime = 0;
116
+ let m = u({
117
+ assetPosition: i,
118
+ duration: this.#t,
119
+ playbackInfo: o,
120
+ streamInfo: s
121
+ });
122
+ t.saveMediaProductTransition(s.streamingSessionId, {
123
+ mediaProduct: a,
124
+ playbackContext: m
125
+ }), this.debugLog("load() mediaProductTransition"), e.dispatchEvent(l(a, m)), this.debugLog("load() pb NOT_PLAYING"), this.debugLog("load() done");
126
+ }
127
+ mediaStateChange(e) {
128
+ return new Promise((t) => {
129
+ let n = (r) => {
130
+ r.target === e && (this.#n.removeEventListener("mediastate", n), t(r.target));
131
+ };
132
+ this.#n.addEventListener("mediastate", n);
133
+ });
134
+ }
135
+ nativeEvent(e) {
136
+ return new Promise((t) => {
137
+ let n = (r) => {
138
+ this.#n.removeEventListener(e, n), t(r);
139
+ };
140
+ this.#n.addEventListener(e, n);
141
+ });
142
+ }
143
+ async next(e) {
144
+ this.debugLog("next", e), this.hasNextItem() && await this.unloadPreloadedMediaProduct();
145
+ let { mediaProduct: n, playbackInfo: r, streamInfo: i } = e, { securityToken: a, streamFormat: o, streamUrl: s, streamingSessionId: c } = i;
146
+ this.preloadedStreamingSessionId = c, this.debugLog("preloading", s, "for", c), o ? (this.#n.preload(s, o, a), this.isActivePlayer || this.#n.pause()) : console.error("Stream format undefined for preload."), this.debugLog("preloading done");
147
+ let l = u({
148
+ assetPosition: 0,
149
+ duration: 0,
150
+ playbackInfo: r,
151
+ streamInfo: i
152
+ });
153
+ t.saveMediaProductTransition(c, {
154
+ mediaProduct: n,
155
+ playbackContext: l
156
+ }), this.#r = e;
157
+ }
158
+ pause() {
159
+ this.#n.pause();
160
+ }
161
+ async play() {
162
+ if (this.debugLog("play"), await this.maybeHardReload(), this.playbackState === "IDLE") {
163
+ this.debugLog("play()", this.playbackState, "returning early");
164
+ return;
165
+ }
166
+ this.setStateToXIfNotYInZMs(1e3, "PLAYING", "STALLED"), await this.updateOutputDevice(), this.mediaProductStarted(this.currentStreamingSessionId), this.debugLog("nativePlayer", "play()"), this.#n.play();
167
+ }
168
+ async playbackEngineEndedHandler(e) {
169
+ if (this.isActivePlayer) {
170
+ let { reason: t } = e.detail;
171
+ t === "completed" && (this.hasNextItem() ? await this.handleAutomaticTransitionToPreloadedMediaProduct() : (r.preloadedStreamingSessionId ? this.debugLog(`Switching player from ${this.name} to ${r.preloadPlayer?.name}`) : this.debugLog("No next item queued."), this.playbackState = "NOT_PLAYING"));
172
+ }
173
+ }
174
+ get ready() {
175
+ return Promise.resolve();
176
+ }
177
+ registerEventListeners() {
178
+ this.debugLog("registerEventListeners"), this.#n.addEventListener("mediacurrenttime", (e) => {
179
+ this.currentTime = Number(e.target);
180
+ }), this.#n.addEventListener("mediastate", (e) => {
181
+ e.target === "completed" ? this.finishCurrentMediaProduct("completed") : this.#o(e.target);
182
+ }), this.#n.addEventListener("devices", (e) => {
183
+ g ? g.addNativeDevices(e.target) : console.error("Output devices not loaded.");
184
+ }), this.#n.addEventListener("devicedisconnected", () => {
185
+ e.dispatchEvent(p()), this.#i("devicedisconnected");
186
+ }), this.#n.addEventListener("deviceexclusivemodenotallowed", () => this.#i("deviceexclusivemodenotallowed")), this.#n.addEventListener("deviceformatnotsupported", () => this.#i("deviceformatnotsupported")), this.#n.addEventListener("devicelocked", () => this.#i("devicelocked")), this.#n.addEventListener("devicenotfound", () => this.#i("devicenotfound")), this.#n.addEventListener("deviceunknownerror", () => this.#i("deviceunknownerror")), this.#n.addEventListener("mediaduration", (e) => {
187
+ this.#t = Number(e.target);
188
+ }), this.#n.addEventListener("mediaerror", (e) => this.#a(e)), this.#n.addEventListener("mediamaxconnectionsreached", () => {
189
+ this.#s().catch(console.error);
190
+ });
191
+ }
192
+ async reset({ keepPreload: e } = { keepPreload: !1 }) {
193
+ this.currentStreamingSessionId !== void 0 && (this.debugLog("reset"), e || await this.unloadPreloadedMediaProduct(), this.#n.stop(), this.playbackState !== "IDLE" && this.finishCurrentMediaProduct("skip"), this.detachPlaybackEngineEndedHandler(), this.currentStreamingSessionId = void 0, e || (this.preloadedStreamingSessionId = void 0), this.playbackState = "IDLE");
194
+ }
195
+ async seek(e) {
196
+ this.hasStarted() || await this.mediaStateChange("active"), this.seekStart(this.currentTime), this.currentTime = e, this.#n.seek(e), this.seekEnd(this.currentTime);
197
+ }
198
+ async skipToPreloadedMediaProduct() {
199
+ this.debugLog("skipToPreloadedMediaProduct", this.preloadedStreamingSessionId);
200
+ let e = this.currentStreamingSessionId === void 0;
201
+ if (this.preloadedStreamingSessionId && this.#r) {
202
+ let n = t.getMediaProductTransition(this.preloadedStreamingSessionId);
203
+ n && (this.#r.mediaProduct = n.mediaProduct), await this.load(this.#r, "implicit"), await this.updateOutputDevice(), e && (this.playbackState = "PLAYING"), this.playbackState === "IDLE" && (this.playbackState = "NOT_PLAYING");
204
+ return;
205
+ }
206
+ console.warn("No preloaded item in native player.");
207
+ }
208
+ async unloadPreloadedMediaProduct() {
209
+ this.debugLog("unloadPreloadedMediaProduct", this.preloadedStreamingSessionId), this.hasNextItem() && (this.cleanUpStoredPreloadInfo(), "cancelPreload" in this.#n ? this.#n.cancelPreload() : console.warn("cancelPreload not available. Update native player."));
210
+ }
211
+ updateDeviceMode() {
212
+ this.updateOutputDevice()?.catch(console.error), g && e.dispatchEvent(s(g.deviceMode));
213
+ }
214
+ updateOutputDevice() {
215
+ if (!g || (this.debugLog("updateOutputDevice", g.activeDevice), !g.activeDevice)) return Promise.resolve();
216
+ let { nativeDeviceId: t } = g.activeDevice;
217
+ if (this.outputDeviceType = g.activeDevice.type, t === "default") this.#e !== "default" && (this.#n.selectSystemDevice(), e.dispatchEvent(c("default")), this.#e = "default");
218
+ else if (t) {
219
+ let n = g.getNativeDevice(t);
220
+ n && (this.#n.selectDevice(n, g.deviceMode), e.dispatchEvent(c(g.activeDevice.id)), e.dispatchEvent(s(g.deviceMode)), this.#e = t);
221
+ } else throw Error(`Device with sinkId ${t} not found.`);
222
+ return Promise.resolve();
223
+ }
224
+ get volume() {
225
+ return i("desiredVolumeLevel");
226
+ }
227
+ set volume(e) {
228
+ this.debugLog("Setting volume to", e), this.#n.setVolume(e * 100);
229
+ }
230
+ };
231
+ //#endregion
232
+ export { _ as default };
@@ -0,0 +1,156 @@
1
+ import { a as e, t } from "./state-BT7sE_jc-iVaBwnBC.js";
2
+ import { i as n, n as r, r as i, t as a } from "./generate-guid-BMGZjV-R-D16yCCHx.js";
3
+ //#region ../player/dist/output-devices-CPJfYcO-.js
4
+ var o = /* @__PURE__ */ i(((e, t) => {
5
+ t.exports = (function() {
6
+ function e(e, t, n, r, i) {
7
+ return e < t || n < t ? e > n ? n + 1 : e + 1 : r === i ? t : t + 1;
8
+ }
9
+ return function(t, n) {
10
+ if (t === n) return 0;
11
+ if (t.length > n.length) {
12
+ var r = t;
13
+ t = n, n = r;
14
+ }
15
+ for (var i = t.length, a = n.length; i > 0 && t.charCodeAt(i - 1) === n.charCodeAt(a - 1);) i--, a--;
16
+ for (var o = 0; o < i && t.charCodeAt(o) === n.charCodeAt(o);) o++;
17
+ if (i -= o, a -= o, i === 0 || a < 3) return a;
18
+ var s = 0, c, l, u, d, f, p, m, h, g, _, v, y, b = [];
19
+ for (c = 0; c < i; c++) b.push(c + 1), b.push(t.charCodeAt(o + c));
20
+ for (var x = b.length - 1; s < a - 3;) for (g = n.charCodeAt(o + (l = s)), _ = n.charCodeAt(o + (u = s + 1)), v = n.charCodeAt(o + (d = s + 2)), y = n.charCodeAt(o + (f = s + 3)), p = s += 4, c = 0; c < x; c += 2) m = b[c], h = b[c + 1], l = e(m, l, u, g, h), u = e(l, u, d, _, h), d = e(u, d, f, v, h), p = e(d, f, p, y, h), b[c] = p, f = d, d = u, u = l, l = m;
21
+ for (; s < a;) for (g = n.charCodeAt(o + (l = s)), p = ++s, c = 0; c < x; c += 2) m = b[c], b[c] = p = e(m, l, p, g, b[c + 1]), l = m;
22
+ return p;
23
+ };
24
+ })();
25
+ })), s = /* @__PURE__ */ a(r(), 1), c = /* @__PURE__ */ a(o(), 1);
26
+ function l(e) {
27
+ return new CustomEvent("device-change", { detail: { devices: e } });
28
+ }
29
+ var u = s.default.parse(navigator.userAgent), d = class {
30
+ controllableVolume;
31
+ id;
32
+ name;
33
+ nativeDeviceId;
34
+ type;
35
+ webDeviceId;
36
+ constructor({ controllableVolume: e, name: t, nativeDeviceId: r, type: i, webDeviceId: a }) {
37
+ this.name = t, this.id = r === "default" && a === "default" ? "default" : n(), this.nativeDeviceId = r, this.webDeviceId = a, this.type = i, this.controllableVolume = e !== !1;
38
+ }
39
+ };
40
+ function f(e) {
41
+ if (m(e)) return "windowsCommunication";
42
+ if ("id" in e && e.id === "BuiltInSpeakerDevice") return "builtIn";
43
+ if ("type" in e && e.type === "airplay") return "airplay";
44
+ if ("label" in e) {
45
+ let t = e.label.toLowerCase();
46
+ if (t.includes("bluetooth")) return "bluetooth";
47
+ if (t.includes("displayport")) return "displayPort";
48
+ if (t.includes("hdmi")) return "hdmi";
49
+ if (t.includes("usb")) return "usb";
50
+ if (t.includes("built-in")) return "builtIn";
51
+ if (t.includes("airplay")) return "airplay";
52
+ }
53
+ }
54
+ function p(e, t) {
55
+ let n = t.toLowerCase(), r = e;
56
+ return n.includes("mac") && (r = (e.split("(")[0] ?? "").trim()), r;
57
+ }
58
+ function m(e) {
59
+ let t;
60
+ return "label" in e && (t = e.label), "name" in e && (t = e.name), t?.startsWith("Communications") ?? !1;
61
+ }
62
+ function h(e, t) {
63
+ if (t = p(t, u.os.name || ""), [...e].length === 0 || t === "") return;
64
+ let n = [...e].find((e) => e.name === t);
65
+ if (n) return n;
66
+ let r = [...e].filter((e) => t.includes(e.name) || e.name.includes(t)).map((e) => ({
67
+ device: e,
68
+ distance: (0, c.default)(e.name, t)
69
+ })).sort((e, t) => e.distance - t.distance).reverse();
70
+ if (r.length > 0) {
71
+ let e = r.pop();
72
+ if (e && e.distance <= 16) return e.device;
73
+ }
74
+ }
75
+ var g = new class {
76
+ #e;
77
+ #t;
78
+ #n = "shared";
79
+ #r;
80
+ #i;
81
+ #a;
82
+ outputDevices;
83
+ constructor() {
84
+ this.#i = /* @__PURE__ */ new Set(), this.#a = /* @__PURE__ */ new Set(), this.#r = new EventTarget(), this.#t = new d({
85
+ name: "System Default",
86
+ nativeDeviceId: "default",
87
+ type: "systemDefault",
88
+ webDeviceId: "default"
89
+ }), this.#e = this.#t, this.outputDevices = new Set([this.#t]), this.hydrateWebDevices().then().catch(console.error), navigator.mediaDevices.addEventListener("devicechange", () => {
90
+ this.hydrateWebDevices().then().catch(console.error);
91
+ }), this.#r.addEventListener("native-devices", ((e) => {
92
+ this.#i = new Set(e.detail), this.queueUpdate().then().catch(console.error);
93
+ })), this.#r.addEventListener("web-devices", ((e) => {
94
+ this.#a = new Set(e.detail), this.queueUpdate().then().catch(console.error);
95
+ }));
96
+ }
97
+ set activeDevice(e) {
98
+ this.#e = e, this.#n = "shared", t.activePlayer?.updateOutputDevice()?.catch(console.error);
99
+ }
100
+ get activeDevice() {
101
+ return this.#e;
102
+ }
103
+ addNativeDevices(e) {
104
+ this.#r.dispatchEvent(new CustomEvent("native-devices", { detail: e }));
105
+ }
106
+ addWebDevices(e) {
107
+ e = e.filter((e) => e.deviceId !== "default"), this.#r.dispatchEvent(new CustomEvent("web-devices", { detail: e }));
108
+ }
109
+ set deviceMode(e) {
110
+ let { activeDevice: n } = this, { activePlayer: r } = t;
111
+ n && r?.name === "nativePlayer" && this.deviceMode !== e && (this.#n = e, r.updateDeviceMode());
112
+ }
113
+ get deviceMode() {
114
+ return this.#n;
115
+ }
116
+ emitDeviceChange() {
117
+ e.dispatchEvent(l([...this.outputDevices]));
118
+ }
119
+ getNativeDevice(e) {
120
+ return [...this.#i].find((t) => t.id === e);
121
+ }
122
+ async hydrateWebDevices() {
123
+ let e = (await navigator.mediaDevices.enumerateDevices()).filter((e) => e.kind === "audiooutput");
124
+ this.addWebDevices(e);
125
+ }
126
+ mergeDevices() {
127
+ [...this.outputDevices].filter((e) => e.id !== "default").forEach((e) => {
128
+ e.nativeDeviceId = void 0, e.webDeviceId = void 0;
129
+ }), this.#i.forEach((e) => {
130
+ let t = h(this.outputDevices, e.name);
131
+ t ? (t.nativeDeviceId = e.id, t.controllableVolume = e.controllableVolume, t.type = f(e) || t.type) : this.outputDevices.add(new d({
132
+ controllableVolume: e.controllableVolume,
133
+ name: p(e.name, u.os.name || ""),
134
+ nativeDeviceId: e.id,
135
+ type: f(e)
136
+ }));
137
+ }), this.#a.forEach((e) => {
138
+ let t = h(this.outputDevices, e.label);
139
+ t ? (t.webDeviceId = e.deviceId, t.type = f(e) || t.type) : this.outputDevices.add(new d({
140
+ name: p(e.label, u.os.name || ""),
141
+ type: f(e),
142
+ webDeviceId: e.deviceId
143
+ }));
144
+ }), [...this.outputDevices].filter((e) => e.webDeviceId === void 0 && e.nativeDeviceId === void 0 || e.type === "airplay" || e.type === "windowsCommunication").forEach((e) => this.outputDevices.delete(e));
145
+ }
146
+ async queueUpdate() {
147
+ let e = new Promise((e) => this.#r.addEventListener("native-devices", ((t) => e(t.detail)), { once: !0 })), t = new Promise((e) => this.#r.addEventListener("web-devices", ((t) => e(t.detail)), { once: !0 }));
148
+ await Promise.any([
149
+ e,
150
+ t,
151
+ ((e) => new Promise((t) => setTimeout(() => t(), e)))(1e3)
152
+ ]), this.mergeDevices(), this.emitDeviceChange();
153
+ }
154
+ }();
155
+ //#endregion
156
+ export { g as outputDevices };
@@ -0,0 +1,117 @@
1
+ import { a as e, c as t, s as n, t as r, u as i } from "./state-BT7sE_jc-iVaBwnBC.js";
2
+ //#region ../player/dist/pushkin-C7W2HCqN.js
3
+ var a = new class {
4
+ #e;
5
+ #t = !1;
6
+ #n;
7
+ #r;
8
+ constructor(e) {
9
+ this.#r = new URL(e), this.synchronize();
10
+ }
11
+ now(e = Date.now()) {
12
+ return !this.#n || !this.#e ? (console.warn("TrueTime is not yet synchronized"), e) : this.#n + (e - this.#e);
13
+ }
14
+ async synchronize() {
15
+ if (!(this.#e && Math.abs(Date.now() - this.#e) < 36e5 || this.#t)) {
16
+ this.#t = !0;
17
+ try {
18
+ let e = await fetch(this.#r);
19
+ e.ok && e.headers.has("date") && (this.#n = new Date(e.headers.get("date")).getTime(), this.#e = Date.now());
20
+ } catch (e) {
21
+ console.error(e);
22
+ }
23
+ this.#t = !1;
24
+ }
25
+ }
26
+ timestamp(e, t) {
27
+ let n;
28
+ if (t) {
29
+ if (n = performance.getEntriesByName(e).find((e) => "detail" in e && e.detail === t), !n) throw ReferenceError(`There is no performance entry named "${e}" with detail "${t}"`);
30
+ } else n = performance.getEntriesByName(e).pop();
31
+ return n ? n.startTime : void 0;
32
+ }
33
+ }("https://api.tidal.com/v1/ping"), o = "streaming-privileges-revoked";
34
+ function s(e) {
35
+ return new CustomEvent(o, { detail: e });
36
+ }
37
+ var c;
38
+ async function l(e) {
39
+ let t = i("legacyApiUrl"), { url: n } = await (await fetch(t + "/rt/connect", {
40
+ headers: new Headers({
41
+ Authorization: "Bearer " + e,
42
+ "Content-Type": "application/json"
43
+ }),
44
+ method: "POST"
45
+ })).json();
46
+ return n;
47
+ }
48
+ function u(e) {
49
+ return new Promise((t) => {
50
+ e.addEventListener("open", () => t(), { once: !0 });
51
+ });
52
+ }
53
+ var d = class i {
54
+ #e;
55
+ #t;
56
+ #n;
57
+ #r;
58
+ constructor() {
59
+ this.#r = void 0, this.#t = this.#i(), e.addEventListener("user-action", () => {
60
+ this.connected && this.userAction().then().catch(console.error);
61
+ });
62
+ }
63
+ static async ensure() {
64
+ await n() && (c ? c.connected || await c.reconnect() : c = new i());
65
+ }
66
+ static async refresh() {
67
+ if (!await n()) return;
68
+ let e = await t();
69
+ c && e && c.reconnect().catch(console.error);
70
+ }
71
+ async #i() {
72
+ let e = await t();
73
+ if (!e) throw Error("No access token to connect to Pushkin.");
74
+ let n = await l(e);
75
+ n && (this.#r = new WebSocket(n), await u(this.#r), this.#n = ((e) => this.#s(e.data)), this.#e = () => this.#o(), this.#r.addEventListener("message", this.#n, !1), this.#r.addEventListener("closed", this.#e, !1), window.addEventListener("online", () => this.#o(), { once: !0 }));
76
+ }
77
+ async #a(e) {
78
+ if (!this.#r) throw Error("No socket connected. Did you forget to call connect method in Pushkin service first?");
79
+ this.#r.readyState !== WebSocket.OPEN && await this.#t, this.#r.send(JSON.stringify(e));
80
+ }
81
+ #o() {
82
+ this.#t = this.#i();
83
+ }
84
+ #s(t) {
85
+ let n = JSON.parse(t);
86
+ switch (n.type) {
87
+ case "PRIVILEGED_SESSION_NOTIFICATION":
88
+ e.dispatchEvent(s(String(n.payload.clientDisplayName))), r.activePlayer?.pause();
89
+ break;
90
+ case "RECONNECT":
91
+ this.reconnect().catch(console.error);
92
+ break;
93
+ default:
94
+ console.warn("Unhandled event from Pushkin: ", n);
95
+ break;
96
+ }
97
+ }
98
+ get connected() {
99
+ return this.#r && this.#r.readyState === WebSocket.OPEN;
100
+ }
101
+ reconnect() {
102
+ return this.#r ? (this.#n && this.#r.removeEventListener("message", this.#n), this.#e && this.#r.removeEventListener("closed", this.#e), this.#r.close(), this.#t = this.#i(), this.#t) : Promise.resolve();
103
+ }
104
+ async userAction() {
105
+ this.connected || await this.reconnect();
106
+ try {
107
+ await this.#a({
108
+ payload: { startedAt: a.now() },
109
+ type: "USER_ACTION"
110
+ });
111
+ } catch (e) {
112
+ console.error(e);
113
+ }
114
+ }
115
+ };
116
+ //#endregion
117
+ export { d as n, a as t };
@@ -0,0 +1,2 @@
1
+ import { n as e } from "./pushkin-C7W2HCqN-BHqS8oLX.js";
2
+ export { e as Pushkin };