@moq/watch 0.2.5 → 0.2.7

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/element.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { Time } from "@moq/lite";
2
2
  import * as Moq from "@moq/lite";
3
3
  import { MultiBackend } from "./backend";
4
4
  import { Broadcast } from "./broadcast";
5
- import { type Latency, Sync } from "./sync";
5
+ import type { Latency } from "./sync";
6
6
  declare const OBSERVED: readonly ["url", "name", "paused", "volume", "muted", "reload", "latency", "jitter"];
7
7
  type Observed = (typeof OBSERVED)[number];
8
8
  export default class MoqWatch extends HTMLElement {
@@ -10,7 +10,6 @@ export default class MoqWatch extends HTMLElement {
10
10
  static observedAttributes: readonly ["url", "name", "paused", "volume", "muted", "reload", "latency", "jitter"];
11
11
  connection: Moq.Connection.Reload;
12
12
  broadcast: Broadcast;
13
- sync: Sync;
14
13
  backend: MultiBackend;
15
14
  signals: Moq.Signals.Effect;
16
15
  constructor();
package/element.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE5C,QAAA,MAAM,QAAQ,sFAAuF,CAAC;AACtG,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAQ1C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;;IAChD,MAAM,CAAC,kBAAkB,uFAAY;IAGrC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAGlC,SAAS,EAAE,SAAS,CAAC;IAGrB,IAAI,OAAc;IAGlB,OAAO,EAAE,YAAY,CAAC;IAMtB,OAAO,qBAAgB;;IAsGvB,iBAAiB;IAMjB,oBAAoB;IAUpB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiCzF,IAAI,GAAG,IAAI,GAAG,GAAG,SAAS,CAEzB;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,EAEtC;IAED,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAEzB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAEtC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAEvB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,yCAAyC;IACzC,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK,CAEvB;IAED,oDAAoD;IACpD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;CACD;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,WAAW,EAAE,QAAQ,CAAC;KACtB;CACD"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,QAAA,MAAM,QAAQ,sFAAuF,CAAC;AACtG,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAQ1C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;;IAChD,MAAM,CAAC,kBAAkB,uFAAY;IAGrC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAGlC,SAAS,EAAE,SAAS,CAAC;IAGrB,OAAO,EAAE,YAAY,CAAC;IAMtB,OAAO,qBAAgB;;IAsGvB,iBAAiB;IAMjB,oBAAoB;IAUpB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiCzF,IAAI,GAAG,IAAI,GAAG,GAAG,SAAS,CAEzB;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,EAEtC;IAED,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAEzB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAEtC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAEvB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAExB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,yCAAyC;IACzC,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK,CAEvB;IAED,oDAAoD;IACpD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;CACD;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,WAAW,EAAE,QAAQ,CAAC;KACtB;CACD"}
package/element.js CHANGED
@@ -1,15 +1,13 @@
1
1
  import * as o from "@moq/lite";
2
2
  import { Signal as c, Effect as l } from "@moq/signals";
3
- import { i as d, B as u, h } from "./broadcast-CZkbruBC.js";
4
- const b = ["url", "name", "paused", "volume", "muted", "reload", "latency", "jitter"], m = new FinalizationRegistry((r) => r.close());
5
- class g extends HTMLElement {
6
- static observedAttributes = b;
3
+ import { B as d, h as u } from "./broadcast-BMWX8K5V.js";
4
+ const h = ["url", "name", "paused", "volume", "muted", "reload", "latency", "jitter"], b = new FinalizationRegistry((r) => r.close());
5
+ class m extends HTMLElement {
6
+ static observedAttributes = h;
7
7
  // The connection to the moq-relay server.
8
8
  connection;
9
9
  // The broadcast being watched.
10
10
  broadcast;
11
- // Used to sync audio and video playback at a target latency.
12
- sync = new d();
13
11
  // The backend that powers this element.
14
12
  backend;
15
13
  // Set when the element is connected to the DOM.
@@ -17,9 +15,9 @@ class g extends HTMLElement {
17
15
  // Expose the Effect class, so users can easily create effects scoped to this element.
18
16
  signals = new l();
19
17
  constructor() {
20
- super(), m.register(this, this.signals), this.connection = new o.Connection.Reload({
18
+ super(), b.register(this, this.signals), this.connection = new o.Connection.Reload({
21
19
  enabled: this.#t
22
- }), this.signals.cleanup(() => this.connection.close()), this.broadcast = new u({
20
+ }), this.signals.cleanup(() => this.connection.close()), this.broadcast = new d({
23
21
  connection: this.connection.established,
24
22
  announced: this.connection.announced,
25
23
  enabled: this.#t
@@ -28,7 +26,7 @@ class g extends HTMLElement {
28
26
  this.signals.run((e) => {
29
27
  const a = e.get(this.connection.established)?.rtt;
30
28
  t.set(a ? e.get(a) : void 0);
31
- }), this.backend = new h({
29
+ }), this.backend = new u({
32
30
  broadcast: this.broadcast,
33
31
  rtt: t
34
32
  }), this.signals.cleanup(() => this.backend.close());
@@ -147,8 +145,8 @@ class g extends HTMLElement {
147
145
  this.backend.latency.set(t);
148
146
  }
149
147
  }
150
- customElements.define("moq-watch", g);
148
+ customElements.define("moq-watch", m);
151
149
  export {
152
- g as default
150
+ m as default
153
151
  };
154
152
  //# sourceMappingURL=element.js.map
package/element.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import type { Time } from \"@moq/lite\";\nimport * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { MultiBackend } from \"./backend\";\nimport { Broadcast } from \"./broadcast\";\nimport { type Latency, Sync } from \"./sync\";\n\nconst OBSERVED = [\"url\", \"name\", \"paused\", \"volume\", \"muted\", \"reload\", \"latency\", \"jitter\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\n// Close everything when this element is garbage collected.\n// This is primarily to avoid a console.warn that we didn't close() before GC.\n// There's no destructor for web components so this is the best we can do.\nconst cleanup = new FinalizationRegistry<Effect>((signals) => signals.close());\n\n// An optional web component that wraps a <canvas>\nexport default class MoqWatch extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\t// The connection to the moq-relay server.\n\tconnection: Moq.Connection.Reload;\n\n\t// The broadcast being watched.\n\tbroadcast: Broadcast;\n\n\t// Used to sync audio and video playback at a target latency.\n\tsync = new Sync();\n\n\t// The backend that powers this element.\n\tbackend: MultiBackend;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\n\t// Expose the Effect class, so users can easily create effects scoped to this element.\n\tsignals = new Effect();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tcleanup.register(this, this.signals);\n\n\t\tthis.connection = new Moq.Connection.Reload({\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.connection.close());\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tannounced: this.connection.announced,\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Flatten the RTT signal from the connection for the backend.\n\t\tconst rtt = new Signal<number | undefined>(undefined);\n\t\tthis.signals.run((effect) => {\n\t\t\tconst conn = effect.get(this.connection.established);\n\t\t\tconst rttSignal = conn?.rtt;\n\t\t\trtt.set(rttSignal ? effect.get(rttSignal) : undefined);\n\t\t});\n\n\t\tthis.backend = new MultiBackend({\n\t\t\tbroadcast: this.broadcast,\n\t\t\trtt,\n\t\t});\n\t\tthis.signals.cleanup(() => this.backend.close());\n\n\t\t// Watch to see if the canvas element is added or removed.\n\t\tconst setElement = () => {\n\t\t\tconst canvas = this.querySelector(\"canvas\") as HTMLCanvasElement | undefined;\n\t\t\tconst video = this.querySelector(\"video\") as HTMLVideoElement | undefined;\n\t\t\tif (canvas && video) {\n\t\t\t\tthrow new Error(\"Cannot have both canvas and video elements\");\n\t\t\t}\n\t\t\tthis.backend.element.set(canvas ?? video);\n\t\t};\n\n\t\tconst observer = new MutationObserver(setElement);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetElement();\n\n\t\t// Optionally update attributes to match the library state.\n\t\t// This is kind of dangerous because it can create loops.\n\t\t// NOTE: This only runs when the element is connected to the DOM, which is not obvious.\n\t\t// This is because there's no destructor for web components to clean up our effects.\n\t\tthis.signals.run((effect) => {\n\t\t\tconst url = effect.get(this.connection.url);\n\t\t\tif (url) {\n\t\t\t\tthis.setAttribute(\"url\", url.toString());\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"url\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst name = effect.get(this.broadcast.name);\n\t\t\tthis.setAttribute(\"name\", name.toString());\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.backend.audio.muted);\n\t\t\tif (muted) {\n\t\t\t\tthis.setAttribute(\"muted\", \"\");\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"muted\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst paused = effect.get(this.backend.paused);\n\t\t\tif (paused) {\n\t\t\t\tthis.setAttribute(\"paused\", \"true\");\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"paused\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst volume = effect.get(this.backend.audio.volume);\n\t\t\tthis.setAttribute(\"volume\", volume.toString());\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst latency = effect.get(this.backend.latency);\n\t\t\tif (latency === \"real-time\") {\n\t\t\t\tthis.setAttribute(\"latency\", \"real-time\");\n\t\t\t} else {\n\t\t\t\tconst jitter = Math.floor(effect.get(this.backend.jitter));\n\t\t\t\tthis.setAttribute(\"latency\", jitter.toString());\n\t\t\t}\n\t\t});\n\t}\n\n\t// Annoyingly, we have to use these callbacks to figure out when the element is connected to the DOM.\n\t// This wouldn't be so bad if there was a destructor for web components to clean up our effects.\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t\tthis.style.display = \"block\";\n\t\tthis.style.position = \"relative\";\n\t}\n\n\tdisconnectedCallback() {\n\t\t// Stop everything but don't actually cleanup just in case we get added back to the DOM.\n\t\tthis.#enabled.set(false);\n\t}\n\n\t#setLatencyNumber(value: string | null) {\n\t\tconst parsed = value ? Number.parseFloat(value) : Number.NaN;\n\t\tthis.backend.latency.set((Number.isFinite(parsed) ? parsed : 100) as Time.Milli);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (name === \"url\") {\n\t\t\tthis.connection.url.set(newValue ? new URL(newValue) : undefined);\n\t\t} else if (name === \"name\") {\n\t\t\tthis.broadcast.name.set(Moq.Path.from(newValue ?? \"\"));\n\t\t} else if (name === \"paused\") {\n\t\t\tthis.backend.paused.set(newValue !== null);\n\t\t} else if (name === \"volume\") {\n\t\t\tconst volume = newValue ? Number.parseFloat(newValue) : 0.5;\n\t\t\tthis.backend.audio.volume.set(volume);\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.backend.audio.muted.set(newValue !== null);\n\t\t} else if (name === \"reload\") {\n\t\t\tthis.broadcast.reload.set(newValue !== null);\n\t\t} else if (name === \"latency\") {\n\t\t\tif (!newValue || newValue === \"real-time\") {\n\t\t\t\tthis.backend.latency.set(\"real-time\");\n\t\t\t} else {\n\t\t\t\tthis.#setLatencyNumber(newValue);\n\t\t\t}\n\t\t} else if (name === \"jitter\") {\n\t\t\t// Deprecated: use latency=\"<number>\" instead.\n\t\t\tthis.#setLatencyNumber(newValue);\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\tget url(): URL | undefined {\n\t\treturn this.connection.url.peek();\n\t}\n\n\tset url(value: string | URL | undefined) {\n\t\tthis.connection.url.set(value ? new URL(value) : undefined);\n\t}\n\n\tget name(): Moq.Path.Valid {\n\t\treturn this.broadcast.name.peek();\n\t}\n\n\tset name(value: string | Moq.Path.Valid) {\n\t\tthis.broadcast.name.set(Moq.Path.from(value));\n\t}\n\n\tget paused(): boolean {\n\t\treturn this.backend.paused.peek();\n\t}\n\n\tset paused(value: boolean) {\n\t\tthis.backend.paused.set(value);\n\t}\n\n\tget volume(): number {\n\t\treturn this.backend.audio.volume.peek();\n\t}\n\n\tset volume(value: number) {\n\t\tthis.backend.audio.volume.set(value);\n\t}\n\n\tget muted(): boolean {\n\t\treturn this.backend.audio.muted.peek();\n\t}\n\n\tset muted(value: boolean) {\n\t\tthis.backend.audio.muted.set(value);\n\t}\n\n\tget reload(): boolean {\n\t\treturn this.broadcast.reload.peek();\n\t}\n\n\tset reload(value: boolean) {\n\t\tthis.broadcast.reload.set(value);\n\t}\n\n\tget latency(): Latency {\n\t\treturn this.backend.latency.peek();\n\t}\n\n\tset latency(value: Latency) {\n\t\tthis.backend.latency.set(value);\n\t}\n\n\t/** The jitter buffer in milliseconds. */\n\tget jitter(): Time.Milli {\n\t\treturn this.backend.jitter.peek();\n\t}\n\n\t/** @deprecated Use `latency = <number>` instead. */\n\tset jitter(value: number) {\n\t\tthis.backend.latency.set(value as Time.Milli);\n\t}\n}\n\ncustomElements.define(\"moq-watch\", MoqWatch);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-watch\": MoqWatch;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqWatch","Sync","#enabled","Signal","Effect","Moq","Broadcast","rtt","effect","rttSignal","MultiBackend","setElement","canvas","video","observer","url","name","volume","jitter","#setLatencyNumber","value","parsed","oldValue","newValue","exhaustive"],"mappings":"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"}
1
+ {"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import type { Time } from \"@moq/lite\";\nimport * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { MultiBackend } from \"./backend\";\nimport { Broadcast } from \"./broadcast\";\nimport type { Latency } from \"./sync\";\n\nconst OBSERVED = [\"url\", \"name\", \"paused\", \"volume\", \"muted\", \"reload\", \"latency\", \"jitter\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\n// Close everything when this element is garbage collected.\n// This is primarily to avoid a console.warn that we didn't close() before GC.\n// There's no destructor for web components so this is the best we can do.\nconst cleanup = new FinalizationRegistry<Effect>((signals) => signals.close());\n\n// An optional web component that wraps a <canvas>\nexport default class MoqWatch extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\t// The connection to the moq-relay server.\n\tconnection: Moq.Connection.Reload;\n\n\t// The broadcast being watched.\n\tbroadcast: Broadcast;\n\n\t// The backend that powers this element.\n\tbackend: MultiBackend;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\n\t// Expose the Effect class, so users can easily create effects scoped to this element.\n\tsignals = new Effect();\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tcleanup.register(this, this.signals);\n\n\t\tthis.connection = new Moq.Connection.Reload({\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.connection.close());\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tannounced: this.connection.announced,\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Flatten the RTT signal from the connection for the backend.\n\t\tconst rtt = new Signal<number | undefined>(undefined);\n\t\tthis.signals.run((effect) => {\n\t\t\tconst conn = effect.get(this.connection.established);\n\t\t\tconst rttSignal = conn?.rtt;\n\t\t\trtt.set(rttSignal ? effect.get(rttSignal) : undefined);\n\t\t});\n\n\t\tthis.backend = new MultiBackend({\n\t\t\tbroadcast: this.broadcast,\n\t\t\trtt,\n\t\t});\n\t\tthis.signals.cleanup(() => this.backend.close());\n\n\t\t// Watch to see if the canvas element is added or removed.\n\t\tconst setElement = () => {\n\t\t\tconst canvas = this.querySelector(\"canvas\") as HTMLCanvasElement | undefined;\n\t\t\tconst video = this.querySelector(\"video\") as HTMLVideoElement | undefined;\n\t\t\tif (canvas && video) {\n\t\t\t\tthrow new Error(\"Cannot have both canvas and video elements\");\n\t\t\t}\n\t\t\tthis.backend.element.set(canvas ?? video);\n\t\t};\n\n\t\tconst observer = new MutationObserver(setElement);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetElement();\n\n\t\t// Optionally update attributes to match the library state.\n\t\t// This is kind of dangerous because it can create loops.\n\t\t// NOTE: This only runs when the element is connected to the DOM, which is not obvious.\n\t\t// This is because there's no destructor for web components to clean up our effects.\n\t\tthis.signals.run((effect) => {\n\t\t\tconst url = effect.get(this.connection.url);\n\t\t\tif (url) {\n\t\t\t\tthis.setAttribute(\"url\", url.toString());\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"url\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst name = effect.get(this.broadcast.name);\n\t\t\tthis.setAttribute(\"name\", name.toString());\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.backend.audio.muted);\n\t\t\tif (muted) {\n\t\t\t\tthis.setAttribute(\"muted\", \"\");\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"muted\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst paused = effect.get(this.backend.paused);\n\t\t\tif (paused) {\n\t\t\t\tthis.setAttribute(\"paused\", \"true\");\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute(\"paused\");\n\t\t\t}\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst volume = effect.get(this.backend.audio.volume);\n\t\t\tthis.setAttribute(\"volume\", volume.toString());\n\t\t});\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst latency = effect.get(this.backend.latency);\n\t\t\tif (latency === \"real-time\") {\n\t\t\t\tthis.setAttribute(\"latency\", \"real-time\");\n\t\t\t} else {\n\t\t\t\tconst jitter = Math.floor(effect.get(this.backend.jitter));\n\t\t\t\tthis.setAttribute(\"latency\", jitter.toString());\n\t\t\t}\n\t\t});\n\t}\n\n\t// Annoyingly, we have to use these callbacks to figure out when the element is connected to the DOM.\n\t// This wouldn't be so bad if there was a destructor for web components to clean up our effects.\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t\tthis.style.display = \"block\";\n\t\tthis.style.position = \"relative\";\n\t}\n\n\tdisconnectedCallback() {\n\t\t// Stop everything but don't actually cleanup just in case we get added back to the DOM.\n\t\tthis.#enabled.set(false);\n\t}\n\n\t#setLatencyNumber(value: string | null) {\n\t\tconst parsed = value ? Number.parseFloat(value) : Number.NaN;\n\t\tthis.backend.latency.set((Number.isFinite(parsed) ? parsed : 100) as Time.Milli);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (name === \"url\") {\n\t\t\tthis.connection.url.set(newValue ? new URL(newValue) : undefined);\n\t\t} else if (name === \"name\") {\n\t\t\tthis.broadcast.name.set(Moq.Path.from(newValue ?? \"\"));\n\t\t} else if (name === \"paused\") {\n\t\t\tthis.backend.paused.set(newValue !== null);\n\t\t} else if (name === \"volume\") {\n\t\t\tconst volume = newValue ? Number.parseFloat(newValue) : 0.5;\n\t\t\tthis.backend.audio.volume.set(volume);\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.backend.audio.muted.set(newValue !== null);\n\t\t} else if (name === \"reload\") {\n\t\t\tthis.broadcast.reload.set(newValue !== null);\n\t\t} else if (name === \"latency\") {\n\t\t\tif (!newValue || newValue === \"real-time\") {\n\t\t\t\tthis.backend.latency.set(\"real-time\");\n\t\t\t} else {\n\t\t\t\tthis.#setLatencyNumber(newValue);\n\t\t\t}\n\t\t} else if (name === \"jitter\") {\n\t\t\t// Deprecated: use latency=\"<number>\" instead.\n\t\t\tthis.#setLatencyNumber(newValue);\n\t\t} else {\n\t\t\tconst exhaustive: never = name;\n\t\t\tthrow new Error(`Invalid attribute: ${exhaustive}`);\n\t\t}\n\t}\n\n\tget url(): URL | undefined {\n\t\treturn this.connection.url.peek();\n\t}\n\n\tset url(value: string | URL | undefined) {\n\t\tthis.connection.url.set(value ? new URL(value) : undefined);\n\t}\n\n\tget name(): Moq.Path.Valid {\n\t\treturn this.broadcast.name.peek();\n\t}\n\n\tset name(value: string | Moq.Path.Valid) {\n\t\tthis.broadcast.name.set(Moq.Path.from(value));\n\t}\n\n\tget paused(): boolean {\n\t\treturn this.backend.paused.peek();\n\t}\n\n\tset paused(value: boolean) {\n\t\tthis.backend.paused.set(value);\n\t}\n\n\tget volume(): number {\n\t\treturn this.backend.audio.volume.peek();\n\t}\n\n\tset volume(value: number) {\n\t\tthis.backend.audio.volume.set(value);\n\t}\n\n\tget muted(): boolean {\n\t\treturn this.backend.audio.muted.peek();\n\t}\n\n\tset muted(value: boolean) {\n\t\tthis.backend.audio.muted.set(value);\n\t}\n\n\tget reload(): boolean {\n\t\treturn this.broadcast.reload.peek();\n\t}\n\n\tset reload(value: boolean) {\n\t\tthis.broadcast.reload.set(value);\n\t}\n\n\tget latency(): Latency {\n\t\treturn this.backend.latency.peek();\n\t}\n\n\tset latency(value: Latency) {\n\t\tthis.backend.latency.set(value);\n\t}\n\n\t/** The jitter buffer in milliseconds. */\n\tget jitter(): Time.Milli {\n\t\treturn this.backend.jitter.peek();\n\t}\n\n\t/** @deprecated Use `latency = <number>` instead. */\n\tset jitter(value: number) {\n\t\tthis.backend.latency.set(value as Time.Milli);\n\t}\n}\n\ncustomElements.define(\"moq-watch\", MoqWatch);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-watch\": MoqWatch;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqWatch","#enabled","Signal","Effect","Moq","Broadcast","rtt","effect","rttSignal","MultiBackend","setElement","canvas","video","observer","url","name","volume","jitter","#setLatencyNumber","value","parsed","oldValue","newValue","exhaustive"],"mappings":"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"}
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as E from "@moq/lite";
2
2
  import { Signal as i, Effect as h } from "@moq/signals";
3
3
  import * as I from "@moq/signals";
4
- import { o as m, a as c, b as d, s as w, D as y, M as S, R as _, S as f, c as M, E as k, d as P, e as O, P as g, f as j, g as x } from "./broadcast-CZkbruBC.js";
5
- import { B as G, m as H, h as K, i as Q, t as U } from "./broadcast-CZkbruBC.js";
4
+ import { o as m, a as c, b as d, s as w, D as y, M as S, R as _, S as f, c as M, E as k, d as P, e as O, P as g, f as j, g as x } from "./broadcast-BMWX8K5V.js";
5
+ import { B as G, m as H, h as K, i as Q, t as U } from "./broadcast-BMWX8K5V.js";
6
6
  const T = m({
7
7
  name: c(w()),
8
8
  // name
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@moq/watch",
3
3
  "type": "module",
4
- "version": "0.2.5",
4
+ "version": "0.2.7",
5
5
  "description": "Watch Media over QUIC broadcasts",
6
6
  "license": "(MIT OR Apache-2.0)",
7
7
  "repository": "github:moq-dev/moq",
package/sync.d.ts CHANGED
@@ -21,6 +21,7 @@ export declare class Sync {
21
21
  signals: Effect;
22
22
  constructor(props?: SyncProps);
23
23
  received(timestamp: Time.Milli, label?: string): void;
24
+ now(): Time.Milli | undefined;
24
25
  wait(timestamp: Time.Milli): Promise<void>;
25
26
  close(): void;
26
27
  }
package/sync.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9C,gGAAgG;AAChG,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;AAW/C,MAAM,WAAW,SAAS;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CACpD;AAED,qBAAa,IAAI;;IAIhB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAmB;IAGrE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAKzB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAG3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAItC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAgB;IAOnD,QAAQ,CAAC,SAAS,iCAAiD;IAQnE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAMjC,OAAO,SAAgB;gBAEX,KAAK,CAAC,EAAE,SAAS;IAyD7B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,SAAK,GAAG,IAAI;IAgD3C,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAqChD,KAAK;CAGL"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9C,gGAAgG;AAChG,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;AAK/C,MAAM,WAAW,SAAS;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CACpD;AAED,qBAAa,IAAI;;IAIhB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAmB;IAGrE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAKzB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAG3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAItC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAgB;IAOnD,QAAQ,CAAC,SAAS,iCAAiD;IAMnE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAMjC,OAAO,SAAgB;gBAEX,KAAK,CAAC,EAAE,SAAS;IAwD7B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,SAAK,GAAG,IAAI;IA0CjD,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,SAAS;IAOvB,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAqChD,KAAK;CAGL"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/ui/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAW,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,KAAK,2BAA2B,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAElH,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,WAAW,CAAC;IAC/B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IAC7B,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,mBAAmB,EAAE,MAAM,SAAS,EAAE,CAAC;IACvC,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACvD,mBAAmB,EAAE,MAAM,OAAO,CAAC;IACnC,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,MAAM,OAAO,CAAC;IAC5B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAC5C,aAAa,EAAE,MAAM,cAAc,CAAC;IACpC,aAAa,EAAE,MAAM,cAAc,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,cAAc,8DAAwC,CAAC;AAEpE,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,eAkIhF"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/ui/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAW,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACzC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,KAAK,2BAA2B,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAElH,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,WAAW,CAAC;IAC/B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IAC7B,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,mBAAmB,EAAE,MAAM,SAAS,EAAE,CAAC;IACvC,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACvD,mBAAmB,EAAE,MAAM,OAAO,CAAC;IACnC,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACnD,YAAY,EAAE,MAAM,OAAO,CAAC;IAC5B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAC5C,aAAa,EAAE,MAAM,cAAc,CAAC;IACpC,aAAa,EAAE,MAAM,cAAc,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,cAAc,8DAAwC,CAAC;AAEpE,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,eAoIhF"}
package/ui/index.js CHANGED
@@ -4,7 +4,7 @@ const Kt = !1, Dt = (t, e) => t === e, Ht = /* @__PURE__ */ Symbol("solid-track"
4
4
  equals: Dt
5
5
  };
6
6
  let Mt = Vt;
7
- const F = 1, at = 2, Rt = {
7
+ const B = 1, at = 2, Rt = {
8
8
  owned: null,
9
9
  cleanups: null,
10
10
  context: null,
@@ -37,15 +37,15 @@ function E(t, e) {
37
37
  return [Tt.bind(n), a];
38
38
  }
39
39
  function T(t, e, n) {
40
- const a = kt(t, e, !1, F);
40
+ const a = kt(t, e, !1, B);
41
41
  X(a);
42
42
  }
43
43
  function Lt(t, e, n) {
44
44
  Mt = te;
45
- const a = kt(t, e, !1, F);
45
+ const a = kt(t, e, !1, B);
46
46
  a.user = !0, j ? j.push(a) : X(a);
47
47
  }
48
- function B(t, e, n) {
48
+ function O(t, e, n) {
49
49
  n = n ? Object.assign({}, rt, n) : rt;
50
50
  const a = kt(t, e, !0, 0);
51
51
  return a.observers = null, a.observerSlots = null, a.comparator = n.equals || void 0, X(a), Tt.bind(a);
@@ -82,7 +82,7 @@ function jt(t) {
82
82
  return p && p.context && (e = p.context[t.id]) !== void 0 ? e : t.defaultValue;
83
83
  }
84
84
  function Jt(t) {
85
- const e = B(t), n = B(() => wt(e()));
85
+ const e = O(t), n = O(() => wt(e()));
86
86
  return n.toArray = () => {
87
87
  const a = n();
88
88
  return Array.isArray(a) ? a : a != null ? [a] : [];
@@ -90,7 +90,7 @@ function Jt(t) {
90
90
  }
91
91
  function Tt() {
92
92
  if (this.sources && this.state)
93
- if (this.state === F) X(this);
93
+ if (this.state === B) X(this);
94
94
  else {
95
95
  const t = C;
96
96
  C = null, J(() => it(this), !1), C = t;
@@ -106,7 +106,7 @@ function It(t, e, n) {
106
106
  return (!t.comparator || !t.comparator(a, e)) && (t.value = e, t.observers && t.observers.length && J(() => {
107
107
  for (let r = 0; r < t.observers.length; r += 1) {
108
108
  const o = t.observers[r], s = gt && gt.running;
109
- s && gt.disposed.has(o), (s ? !o.tState : !o.state) && (o.pure ? C.push(o) : j.push(o), o.observers && zt(o)), s || (o.state = F);
109
+ s && gt.disposed.has(o), (s ? !o.tState : !o.state) && (o.pure ? C.push(o) : j.push(o), o.observers && zt(o)), s || (o.state = B);
110
110
  }
111
111
  if (C.length > 1e6)
112
112
  throw C = [], new Error();
@@ -125,13 +125,13 @@ function Zt(t, e, n) {
125
125
  try {
126
126
  a = t.fn(e);
127
127
  } catch (s) {
128
- return t.pure && (t.state = F, t.owned && t.owned.forEach(Q), t.owned = null), t.updatedAt = n + 1, Ot(s);
128
+ return t.pure && (t.state = B, t.owned && t.owned.forEach(Q), t.owned = null), t.updatedAt = n + 1, Ot(s);
129
129
  } finally {
130
130
  v = o, p = r;
131
131
  }
132
132
  (!t.updatedAt || t.updatedAt <= n) && (t.updatedAt != null && "observers" in t ? It(t, a) : t.value = a, t.updatedAt = n);
133
133
  }
134
- function kt(t, e, n, a = F, r) {
134
+ function kt(t, e, n, a = B, r) {
135
135
  const o = {
136
136
  fn: t,
137
137
  state: a,
@@ -155,7 +155,7 @@ function ot(t) {
155
155
  for (; (t = t.owner) && (!t.updatedAt || t.updatedAt < ut); )
156
156
  t.state && e.push(t);
157
157
  for (let n = e.length - 1; n >= 0; n--)
158
- if (t = e[n], t.state === F)
158
+ if (t = e[n], t.state === B)
159
159
  X(t);
160
160
  else if (t.state === at) {
161
161
  const a = C;
@@ -195,7 +195,7 @@ function it(t, e) {
195
195
  const a = t.sources[n];
196
196
  if (a.sources) {
197
197
  const r = a.state;
198
- r === F ? a !== e && (!a.updatedAt || a.updatedAt < ut) && ot(a) : r === at && it(a, e);
198
+ r === B ? a !== e && (!a.updatedAt || a.updatedAt < ut) && ot(a) : r === at && it(a, e);
199
199
  }
200
200
  }
201
201
  }
@@ -305,13 +305,13 @@ function ie(t) {
305
305
  const e = "fallback" in t && {
306
306
  fallback: () => t.fallback
307
307
  };
308
- return B(ae(() => t.each, t.children, e || void 0));
308
+ return O(ae(() => t.each, t.children, e || void 0));
309
309
  }
310
310
  function Z(t) {
311
- const e = t.keyed, n = B(() => t.when, void 0, void 0), a = e ? n : B(n, void 0, {
311
+ const e = t.keyed, n = O(() => t.when, void 0, void 0), a = e ? n : O(n, void 0, {
312
312
  equals: (r, o) => !r == !o
313
313
  });
314
- return B(() => {
314
+ return O(() => {
315
315
  const r = a();
316
316
  if (r) {
317
317
  const o = t.children;
@@ -323,7 +323,7 @@ function Z(t) {
323
323
  return t.fallback;
324
324
  }, void 0, void 0);
325
325
  }
326
- const mt = (t) => B(() => t());
326
+ const mt = (t) => O(() => t());
327
327
  function se(t, e, n) {
328
328
  let a = n.length, r = e.length, o = a, s = 0, i = 0, c = e[r - 1].nextSibling, u = null;
329
329
  for (; s < r || i < o; ) {
@@ -671,13 +671,13 @@ function xe(t) {
671
671
  function ke(t, e, n) {
672
672
  return arguments.length === 2 && (n = e, e = {}), we(t, e)(xe(n));
673
673
  }
674
- function O(t) {
674
+ function U(t) {
675
675
  const [e, n] = E(t.peek(), { equals: !1 }), a = t.subscribe((r) => n(() => r));
676
676
  return ft(() => a()), e;
677
677
  }
678
678
  const lt = Xt();
679
679
  function Ce(t) {
680
- const [e, n] = E("no-url"), [a, r] = E(!1), o = O(t.moqWatch.backend.audio.muted), [s, i] = E(0), c = O(t.moqWatch.backend.video.stalled), u = O(t.moqWatch.backend.latency), f = O(t.moqWatch.backend.jitter), [l, S] = E([]), x = O(t.moqWatch.backend.video.source.track), [A, y] = E(!1), [P, $] = E(!!document.fullscreenElement), m = () => {
680
+ const [e, n] = E("no-url"), [a, r] = E(!1), o = U(t.moqWatch.backend.audio.muted), [s, i] = E(0), c = U(t.moqWatch.backend.video.stalled), u = U(t.moqWatch.backend.latency), f = U(t.moqWatch.backend.jitter), [l, S] = E([]), x = U(t.moqWatch.backend.video.source.track), [A, y] = E(!1), [P, $] = E(!!document.fullscreenElement), m = () => {
681
681
  t.moqWatch.paused = !t.moqWatch.paused;
682
682
  }, h = () => {
683
683
  document.fullscreenElement ? document.exitFullscreen() : t.moqWatch.requestFullscreen();
@@ -687,12 +687,12 @@ function Ce(t) {
687
687
  t.moqWatch.backend.audio.muted.update((b) => !b);
688
688
  }, q = (b) => {
689
689
  t.moqWatch.latency = b;
690
- }, U = (b) => {
690
+ }, N = (b) => {
691
691
  t.moqWatch.backend.video.source.target.update((M) => ({
692
692
  ...M,
693
693
  name: b
694
694
  }));
695
- }, K = O(t.moqWatch.backend.video.timestamp), D = O(t.moqWatch.backend.video.buffered), dt = O(t.moqWatch.backend.audio.buffered), Y = {
695
+ }, K = () => t.moqWatch.backend.sync.now(), D = U(t.moqWatch.backend.video.buffered), dt = U(t.moqWatch.backend.audio.buffered), Y = {
696
696
  moqWatch: t.moqWatch,
697
697
  watchStatus: e,
698
698
  togglePlayback: m,
@@ -707,7 +707,7 @@ function Ce(t) {
707
707
  setLatency: q,
708
708
  availableRenditions: l,
709
709
  activeRendition: x,
710
- setActiveRendition: U,
710
+ setActiveRendition: N,
711
711
  isStatsPanelVisible: A,
712
712
  setIsStatsPanelVisible: y,
713
713
  isFullscreen: P,
@@ -744,7 +744,7 @@ function Ce(t) {
744
744
  }
745
745
  });
746
746
  }
747
- function N() {
747
+ function F() {
748
748
  const t = jt(lt);
749
749
  if (!t)
750
750
  throw new Error("useWatchUIContext must be used within a WatchUIContextProvider");
@@ -752,7 +752,7 @@ function N() {
752
752
  }
753
753
  var Se = /* @__PURE__ */ R('<div class="watch-ui__buffering flex--center"><div class=watch-ui__buffering-spinner>');
754
754
  function Ae() {
755
- const t = N();
755
+ const t = F();
756
756
  return g(Z, {
757
757
  get when() {
758
758
  return t.buffering();
@@ -775,17 +775,17 @@ function qt(t, e, n, a, r) {
775
775
  if (d <= h) continue;
776
776
  const _ = h / a * c, q = Math.max(2, (d - h) / a * c);
777
777
  if (o.globalAlpha = 0.85, o.fillStyle = r ? "#f87171" : y > 0 ? "#facc15" : "#4ade80", typeof o.roundRect == "function" ? (o.beginPath(), o.roundRect(_, S, q, x, A), o.fill()) : o.fillRect(_, S, q, x), m > a) {
778
- const U = ((m - a) / 1e3).toFixed(1);
779
- o.globalAlpha = 0.7, o.fillStyle = "black", o.font = "500 9px system-ui, sans-serif", o.textAlign = "right", o.textBaseline = "middle", o.fillText(`+${U}s`, _ + q - 4, u / 2);
778
+ const N = ((m - a) / 1e3).toFixed(1);
779
+ o.globalAlpha = 0.7, o.fillStyle = "black", o.font = "500 9px system-ui, sans-serif", o.textAlign = "right", o.textBaseline = "middle", o.fillText(`+${N}s`, _ + q - 4, u / 2);
780
780
  }
781
781
  }
782
782
  }
783
783
  function Pe(t) {
784
- const e = N(), n = () => t.max ?? 4e3, [a, r] = E(!1), [o, s] = E(!1), i = B(() => e.jitter() / n() * 100);
784
+ const e = F(), n = () => t.max ?? 4e3, [a, r] = E(!1), [o, s] = E(!1), i = O(() => e.jitter() / n() * 100);
785
785
  let c, u, f;
786
786
  const l = 48, S = (h) => {
787
787
  if (!c) return;
788
- const d = c.getBoundingClientRect(), _ = d.width - l, U = Math.max(0, Math.min(h - d.left - l, _)) / _ * n(), K = Math.round(U / et) * et, D = Math.max(vt, Math.min(n(), K));
788
+ const d = c.getBoundingClientRect(), _ = d.width - l, N = Math.max(0, Math.min(h - d.left - l, _)) / _ * n(), K = Math.round(N / et) * et, D = Math.max(vt, Math.min(n(), K));
789
789
  e.setLatency(D);
790
790
  }, x = (h) => {
791
791
  r(!0), s(!0), S(h.clientX), document.addEventListener("mousemove", A), document.addEventListener("mouseup", y);
@@ -815,7 +815,7 @@ function Pe(t) {
815
815
  }), ft(() => {
816
816
  $ !== void 0 && cancelAnimationFrame($), document.removeEventListener("mousemove", A), document.removeEventListener("mouseup", y);
817
817
  }), (() => {
818
- var h = $e(), d = h.firstChild, _ = d.firstChild, q = _.nextSibling, U = q.firstChild, K = U.nextSibling, D = q.nextSibling, dt = D.firstChild, Y = dt.nextSibling, V = D.nextSibling, L = V.firstChild, ht = L.firstChild;
818
+ var h = $e(), d = h.firstChild, _ = d.firstChild, q = _.nextSibling, N = q.firstChild, K = N.nextSibling, D = q.nextSibling, dt = D.firstChild, Y = dt.nextSibling, V = D.nextSibling, L = V.firstChild, ht = L.firstChild;
819
819
  d.$$keydown = P, d.$$mousedown = x;
820
820
  var b = c;
821
821
  typeof b == "function" ? _t(b, d) : c = d, pt(d, "aria-valuemin", vt);
@@ -838,7 +838,7 @@ function Pe(t) {
838
838
  }
839
839
  le(["mousedown", "keydown"]);
840
840
  function qe() {
841
- const t = N();
841
+ const t = F();
842
842
  return g(ct, {
843
843
  title: "Fullscreen",
844
844
  onClick: () => {
@@ -860,7 +860,7 @@ function qe() {
860
860
  });
861
861
  }
862
862
  function Me() {
863
- const t = N();
863
+ const t = F();
864
864
  return g(ct, {
865
865
  get title() {
866
866
  return t.isPlaying() ? "Pause" : "Play";
@@ -889,7 +889,7 @@ function We(t) {
889
889
  return t >= 1e6 ? `${(t / 1e6).toFixed(1)} Mbps` : t >= 1e3 ? `${(t / 1e3).toFixed(0)} kbps` : `${t} bps`;
890
890
  }
891
891
  function je() {
892
- const t = N(), e = (n) => {
892
+ const t = F(), e = (n) => {
893
893
  const a = n.currentTarget.value || void 0;
894
894
  t.setActiveRendition(a);
895
895
  };
@@ -913,7 +913,7 @@ function je() {
913
913
  })();
914
914
  }
915
915
  function Te() {
916
- const t = N();
916
+ const t = F();
917
917
  return g(ct, {
918
918
  get title() {
919
919
  return t.isStatsPanelVisible() ? "Hide stats" : "Show stats";
@@ -929,7 +929,7 @@ function Te() {
929
929
  var Ie = /* @__PURE__ */ R('<div class="watch-ui__volume-slider flex--center"><input type=range min=0 max=100><span class=watch-ui__volume-label>');
930
930
  const Ve = (t, e) => e || t === 0 ? g(W.Mute, {}) : t > 0 && t <= 33 ? g(W.VolumeLow, {}) : t > 33 && t <= 66 ? g(W.VolumeMedium, {}) : g(W.VolumeHigh, {});
931
931
  function ze() {
932
- const [t, e] = E(0), n = N(), a = (r) => {
932
+ const [t, e] = E(0), n = F(), a = (r) => {
933
933
  const o = r.currentTarget, s = parseFloat(o.value);
934
934
  n.setVolume(s);
935
935
  };
@@ -984,7 +984,7 @@ const Be = {
984
984
  text: "Unknown"
985
985
  };
986
986
  function Ne() {
987
- const t = N(), e = () => {
987
+ const t = F(), e = () => {
988
988
  const n = t.watchStatus();
989
989
  return Be[n] || Fe;
990
990
  };