@moq/publish 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/broadcast.d.ts CHANGED
@@ -9,7 +9,7 @@ import * as Video from "./video";
9
9
  export type BroadcastProps = {
10
10
  connection?: Moq.Connection.Established | Signal<Moq.Connection.Established | undefined>;
11
11
  enabled?: boolean | Signal<boolean>;
12
- path?: Moq.Path.Valid | Signal<Moq.Path.Valid | undefined>;
12
+ name?: Moq.Path.Valid | Signal<Moq.Path.Valid | undefined>;
13
13
  audio?: Audio.EncoderProps;
14
14
  video?: Video.Props;
15
15
  location?: Location.Props;
@@ -22,7 +22,7 @@ export declare class Broadcast {
22
22
  static readonly CATALOG_TRACK = "catalog.json";
23
23
  connection: Signal<Moq.Connection.Established | undefined>;
24
24
  enabled: Signal<boolean>;
25
- path: Signal<Moq.Path.Valid | undefined>;
25
+ name: Signal<Moq.Path.Valid | undefined>;
26
26
  audio: Audio.Encoder;
27
27
  video: Video.Root;
28
28
  location: Location.Root;
package/element.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import * as Moq from "@moq/lite";
2
2
  import { Broadcast } from "./broadcast";
3
3
  import * as Source from "./source";
4
- declare const OBSERVED: readonly ["url", "name", "path", "muted", "invisible", "source"];
4
+ declare const OBSERVED: readonly ["url", "name", "muted", "invisible", "source"];
5
5
  type Observed = (typeof OBSERVED)[number];
6
6
  type SourceType = "camera" | "screen" | "file";
7
7
  export default class MoqPublish extends HTMLElement {
8
8
  #private;
9
- static observedAttributes: readonly ["url", "name", "path", "muted", "invisible", "source"];
10
- url: Moq.Signals.Signal<URL | undefined>;
11
- path: Moq.Signals.Signal<Moq.Path.Valid | undefined>;
12
- source: Moq.Signals.Signal<File | SourceType | undefined>;
13
- muted: Moq.Signals.Signal<boolean>;
14
- invisible: Moq.Signals.Signal<boolean>;
9
+ static observedAttributes: readonly ["url", "name", "muted", "invisible", "source"];
10
+ state: {
11
+ source: Moq.Signals.Signal<File | SourceType | undefined>;
12
+ muted: Moq.Signals.Signal<boolean>;
13
+ invisible: Moq.Signals.Signal<boolean>;
14
+ };
15
15
  connection: Moq.Connection.Reload;
16
16
  broadcast: Broadcast;
17
17
  video: Moq.Signals.Signal<Source.Camera | Source.Screen | undefined>;
@@ -22,6 +22,16 @@ export default class MoqPublish extends HTMLElement {
22
22
  connectedCallback(): void;
23
23
  disconnectedCallback(): void;
24
24
  attributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null): void;
25
+ get url(): URL | undefined;
26
+ set url(value: string | URL | undefined);
27
+ get name(): Moq.Path.Valid | undefined;
28
+ set name(value: string | Moq.Path.Valid | undefined);
29
+ get source(): SourceType | File | undefined;
30
+ set source(value: SourceType | File | undefined);
31
+ get muted(): boolean;
32
+ set muted(value: boolean);
33
+ get invisible(): boolean;
34
+ set invisible(value: boolean);
25
35
  }
26
36
  declare global {
27
37
  interface HTMLElementTagNameMap {
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,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAGnC,QAAA,MAAM,QAAQ,kEAAmE,CAAC;AAClF,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,KAAK,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAO/C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;;IAClD,MAAM,CAAC,kBAAkB,mEAAY;IAErC,GAAG,sCAA0C;IAC7C,IAAI,iDAAqD;IACzD,MAAM,oDAAwD;IAG9D,KAAK,8BAAqB;IAC1B,SAAS,8BAAqB;IAE9B,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC;IAIrB,KAAK,gEAAoE;IACzE,KAAK,oEAAwE;IAC7E,IAAI,8CAAkD;IAUtD,OAAO,qBAAgB;;IAyEvB,iBAAiB;IAIjB,oBAAoB;IAIpB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAkGzF;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,aAAa,EAAE,UAAU,CAAC;KAC1B;CACD"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,QAAA,MAAM,QAAQ,0DAA2D,CAAC;AAC1E,KAAK,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,KAAK,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAO/C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;;IAClD,MAAM,CAAC,kBAAkB,2DAAY;IAIrC,KAAK;;;;MAIH;IAEF,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC;IAIrB,KAAK,gEAAoE;IACzE,KAAK,oEAAwE;IAC7E,IAAI,8CAAkD;IAUtD,OAAO,qBAAgB;;IAuEvB,iBAAiB;IAIjB,oBAAoB;IAIpB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAmGzF,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,GAAG,SAAS,CAErC;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,EAElD;IAED,IAAI,MAAM,IAAI,UAAU,GAAG,IAAI,GAAG,SAAS,CAE1C;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EAE9C;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAEvB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;CACD;AAID,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,aAAa,EAAE,UAAU,CAAC;KAC1B;CACD"}
package/element.js CHANGED
@@ -1,141 +1,170 @@
1
- import * as l from "@moq/lite";
2
- import { Signal as n, Effect as d } from "@moq/signals";
3
- import { B as u, C as h, M as b, S as v, F as g } from "./screen-Dz_GBTAe.js";
4
- const p = ["url", "name", "path", "muted", "invisible", "source"], w = new FinalizationRegistry((c) => c.close());
5
- class m extends HTMLElement {
6
- static observedAttributes = p;
7
- url = new n(void 0);
8
- path = new n(void 0);
9
- source = new n(void 0);
10
- // Controls whether audio/video is enabled.
11
- muted = new n(!1);
12
- invisible = new n(!1);
1
+ import * as c from "@moq/lite";
2
+ import { Signal as o, Effect as u } from "@moq/signals";
3
+ import { B as d, C as h, M as b, S as v, F as g } from "./screen-BZp2qFyj.js";
4
+ const m = ["url", "name", "muted", "invisible", "source"], p = new FinalizationRegistry((l) => l.close());
5
+ class w extends HTMLElement {
6
+ static observedAttributes = m;
7
+ // Reactive state for element properties that are also HTML attributes.
8
+ // Access these Signals directly for reactive subscriptions (e.g. effect.get(el.state.source)).
9
+ state = {
10
+ source: new o(void 0),
11
+ muted: new o(!1),
12
+ invisible: new o(!1)
13
+ };
13
14
  connection;
14
15
  broadcast;
15
- #o = new n(void 0);
16
- video = new n(void 0);
17
- audio = new n(void 0);
18
- file = new n(void 0);
16
+ #n = new o(void 0);
17
+ video = new o(void 0);
18
+ audio = new o(void 0);
19
+ file = new o(void 0);
19
20
  // The inverse of the `muted` and `invisible` signals.
20
- #s;
21
21
  #e;
22
- #i;
22
+ #s;
23
+ #t;
23
24
  // Set when the element is connected to the DOM.
24
- #t = new n(!1);
25
- signals = new d();
25
+ #i = new o(!1);
26
+ signals = new u();
26
27
  constructor() {
27
- super(), w.register(this, this.signals), this.connection = new l.Connection.Reload({
28
- url: this.url,
29
- enabled: this.#t
30
- }), this.signals.cleanup(() => this.connection.close()), this.#s = new n(!1), this.#e = new n(!1), this.#i = new n(!1), this.signals.run((s) => {
31
- const e = s.get(this.muted), t = s.get(this.invisible);
32
- this.#s.set(!t), this.#e.set(!e), this.#i.set(!e || !t);
33
- }), this.broadcast = new u({
28
+ super(), p.register(this, this.signals), this.connection = new c.Connection.Reload({
29
+ enabled: this.#i
30
+ }), this.signals.cleanup(() => this.connection.close()), this.#e = new o(!1), this.#s = new o(!1), this.#t = new o(!1), this.signals.run((s) => {
31
+ const t = s.get(this.state.muted), i = s.get(this.state.invisible);
32
+ this.#e.set(!i), this.#s.set(!t), this.#t.set(!t || !i);
33
+ }), this.broadcast = new d({
34
34
  connection: this.connection.established,
35
- enabled: this.#t,
36
- path: this.path,
35
+ enabled: this.#i,
37
36
  audio: {
38
- enabled: this.#e
37
+ enabled: this.#s
39
38
  },
40
39
  video: {
41
40
  hd: {
42
- enabled: this.#s
41
+ enabled: this.#e
43
42
  }
44
43
  }
45
44
  }), this.signals.cleanup(() => this.broadcast.close());
46
- const i = () => {
47
- this.#o.set(this.querySelector("video"));
48
- }, o = new MutationObserver(i);
49
- o.observe(this, { childList: !0, subtree: !0 }), this.signals.cleanup(() => o.disconnect()), i(), this.signals.run((s) => {
50
- const e = s.get(this.#o);
51
- if (!e) return;
52
- const t = s.get(this.broadcast.video.source);
53
- if (!t) {
54
- e.style.display = "none";
45
+ const e = () => {
46
+ this.#n.set(this.querySelector("video"));
47
+ }, n = new MutationObserver(e);
48
+ n.observe(this, { childList: !0, subtree: !0 }), this.signals.cleanup(() => n.disconnect()), e(), this.signals.run((s) => {
49
+ const t = s.get(this.#n);
50
+ if (!t) return;
51
+ const i = s.get(this.broadcast.video.source);
52
+ if (!i) {
53
+ t.style.display = "none";
55
54
  return;
56
55
  }
57
- e.srcObject = new MediaStream([t]), e.style.display = "block", s.cleanup(() => {
58
- e.srcObject = null;
56
+ t.srcObject = new MediaStream([i]), t.style.display = "block", s.cleanup(() => {
57
+ t.srcObject = null;
59
58
  });
60
- }), this.signals.run(this.#n.bind(this));
59
+ }), this.signals.run(this.#o.bind(this));
61
60
  }
62
61
  connectedCallback() {
63
- this.#t.set(!0);
62
+ this.#i.set(!0);
64
63
  }
65
64
  disconnectedCallback() {
66
- this.#t.set(!1);
65
+ this.#i.set(!1);
67
66
  }
68
- attributeChangedCallback(i, o, s) {
69
- if (o !== s)
70
- if (i === "url")
71
- this.url.set(s ? new URL(s) : void 0);
72
- else if (i === "name" || i === "path")
73
- this.path.set(s ? l.Path.from(s) : void 0);
74
- else if (i === "source")
67
+ attributeChangedCallback(e, n, s) {
68
+ if (n !== s)
69
+ if (e === "url")
70
+ this.connection.url.set(s ? new URL(s) : void 0);
71
+ else if (e === "name")
72
+ this.broadcast.name.set(s ? c.Path.from(s) : void 0);
73
+ else if (e === "source")
75
74
  if (s === "camera" || s === "screen" || s === "file" || s === null)
76
- this.source.set(s);
75
+ this.state.source.set(s);
77
76
  else
78
77
  throw new Error(`Invalid source: ${s}`);
79
- else if (i === "muted")
80
- this.muted.set(s !== null);
81
- else if (i === "invisible")
82
- this.invisible.set(s !== null);
78
+ else if (e === "muted")
79
+ this.state.muted.set(s !== null);
80
+ else if (e === "invisible")
81
+ this.state.invisible.set(s !== null);
83
82
  else {
84
- const e = i;
85
- throw new Error(`Invalid attribute: ${e}`);
83
+ const t = e;
84
+ throw new Error(`Invalid attribute: ${t}`);
86
85
  }
87
86
  }
88
- #n(i) {
89
- const o = i.get(this.source);
90
- if (!o) return;
91
- if (o === "camera") {
92
- const e = new h({ enabled: this.#s });
87
+ #o(e) {
88
+ const n = e.get(this.state.source);
89
+ if (!n) return;
90
+ if (n === "camera") {
91
+ const t = new h({ enabled: this.#e });
93
92
  this.signals.run((r) => {
94
- const a = r.get(e.source);
93
+ const a = r.get(t.source);
95
94
  this.broadcast.video.source.set(a);
96
95
  });
97
- const t = new b({ enabled: this.#e });
96
+ const i = new b({ enabled: this.#s });
98
97
  this.signals.run((r) => {
99
- const a = r.get(t.source);
98
+ const a = r.get(i.source);
100
99
  this.broadcast.audio.source.set(a);
101
- }), i.set(this.video, e), i.set(this.audio, t), i.cleanup(() => {
102
- e.close(), t.close();
100
+ }), e.set(this.video, t), e.set(this.audio, i), e.cleanup(() => {
101
+ t.close(), i.close();
103
102
  });
104
103
  return;
105
104
  }
106
- if (o === "screen") {
107
- const e = new v({
108
- enabled: this.#i
105
+ if (n === "screen") {
106
+ const t = new v({
107
+ enabled: this.#t
109
108
  });
110
- this.signals.run((t) => {
111
- const r = t.get(e.source);
112
- r && (t.set(this.broadcast.video.source, r.video), t.set(this.broadcast.audio.source, r.audio));
113
- }), i.set(this.video, e), i.set(this.audio, e), i.cleanup(() => {
114
- e.close();
109
+ this.signals.run((i) => {
110
+ const r = i.get(t.source);
111
+ r && (i.set(this.broadcast.video.source, r.video), i.set(this.broadcast.audio.source, r.audio));
112
+ }), e.set(this.video, t), e.set(this.audio, t), e.cleanup(() => {
113
+ t.close();
115
114
  });
116
115
  return;
117
116
  }
118
- if (o === "file" || o instanceof File) {
119
- const e = new g({
117
+ if (n === "file" || n instanceof File) {
118
+ const t = new g({
120
119
  // If a File is provided, use it directly.
121
120
  // TODO: Show a file picker otherwise.
122
- file: o instanceof File ? o : void 0,
123
- enabled: this.#i
121
+ file: n instanceof File ? n : void 0,
122
+ enabled: this.#t
124
123
  });
125
- this.signals.run((t) => {
126
- const r = t.get(e.source);
124
+ this.signals.run((i) => {
125
+ const r = i.get(t.source);
127
126
  this.broadcast.video.source.set(r.video), this.broadcast.audio.source.set(r.audio);
128
- }), i.cleanup(() => {
129
- e.close();
127
+ }), e.cleanup(() => {
128
+ t.close();
130
129
  });
131
130
  return;
132
131
  }
133
- const s = o;
132
+ const s = n;
134
133
  throw new Error(`Invalid source: ${s}`);
135
134
  }
135
+ get url() {
136
+ return this.connection.url.peek();
137
+ }
138
+ set url(e) {
139
+ this.connection.url.set(e ? new URL(e) : void 0);
140
+ }
141
+ get name() {
142
+ return this.broadcast.name.peek();
143
+ }
144
+ set name(e) {
145
+ this.broadcast.name.set(e ? c.Path.from(e) : void 0);
146
+ }
147
+ get source() {
148
+ return this.state.source.peek();
149
+ }
150
+ set source(e) {
151
+ this.state.source.set(e);
152
+ }
153
+ get muted() {
154
+ return this.state.muted.peek();
155
+ }
156
+ set muted(e) {
157
+ this.state.muted.set(e);
158
+ }
159
+ get invisible() {
160
+ return this.state.invisible.peek();
161
+ }
162
+ set invisible(e) {
163
+ this.state.invisible.set(e);
164
+ }
136
165
  }
137
- customElements.define("moq-publish", m);
166
+ customElements.define("moq-publish", w);
138
167
  export {
139
- m as default
168
+ w as default
140
169
  };
141
170
  //# sourceMappingURL=element.js.map
package/element.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { Broadcast } from \"./broadcast\";\nimport * as Source from \"./source\";\n\n// TODO remove name; replaced with path\nconst OBSERVED = [\"url\", \"name\", \"path\", \"muted\", \"invisible\", \"source\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\ntype SourceType = \"camera\" | \"screen\" | \"file\";\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\nexport default class MoqPublish extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\turl = new Signal<URL | undefined>(undefined);\n\tpath = new Signal<Moq.Path.Valid | undefined>(undefined);\n\tsource = new Signal<SourceType | File | undefined>(undefined);\n\n\t// Controls whether audio/video is enabled.\n\tmuted = new Signal(false);\n\tinvisible = new Signal(false);\n\n\tconnection: Moq.Connection.Reload;\n\tbroadcast: Broadcast;\n\n\t#preview = new Signal<HTMLVideoElement | undefined>(undefined);\n\n\tvideo = new Signal<Source.Camera | Source.Screen | undefined>(undefined);\n\taudio = new Signal<Source.Microphone | Source.Screen | undefined>(undefined);\n\tfile = new Signal<Source.File | undefined>(undefined);\n\n\t// The inverse of the `muted` and `invisible` signals.\n\t#videoEnabled: Signal<boolean>;\n\t#audioEnabled: Signal<boolean>;\n\t#eitherEnabled: Signal<boolean>;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\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\turl: this.url,\n\t\t\tenabled: this.#enabled,\n\t\t});\n\t\tthis.signals.cleanup(() => this.connection.close());\n\n\t\t// The inverse of the `muted` and `invisible` signals.\n\t\t// TODO make this.signals.computed to simplify the code.\n\t\tthis.#videoEnabled = new Signal(false);\n\t\tthis.#audioEnabled = new Signal(false);\n\t\tthis.#eitherEnabled = new Signal(false);\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.muted);\n\t\t\tconst invisible = effect.get(this.invisible);\n\t\t\tthis.#videoEnabled.set(!invisible);\n\t\t\tthis.#audioEnabled.set(!muted);\n\t\t\tthis.#eitherEnabled.set(!muted || !invisible);\n\t\t});\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tenabled: this.#enabled,\n\t\t\tpath: this.path,\n\n\t\t\taudio: {\n\t\t\t\tenabled: this.#audioEnabled,\n\t\t\t},\n\t\t\tvideo: {\n\t\t\t\thd: {\n\t\t\t\t\tenabled: this.#videoEnabled,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Watch to see if the preview element is added or removed.\n\t\tconst setPreview = () => {\n\t\t\tthis.#preview.set(this.querySelector(\"video\") as HTMLVideoElement | undefined);\n\t\t};\n\t\tconst observer = new MutationObserver(setPreview);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetPreview();\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst preview = effect.get(this.#preview);\n\t\t\tif (!preview) return;\n\n\t\t\tconst source = effect.get(this.broadcast.video.source);\n\t\t\tif (!source) {\n\t\t\t\tpreview.style.display = \"none\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpreview.srcObject = new MediaStream([source]);\n\t\t\tpreview.style.display = \"block\";\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tpreview.srcObject = null;\n\t\t\t});\n\t\t});\n\n\t\tthis.signals.run(this.#runSource.bind(this));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#enabled.set(false);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) return;\n\n\t\tif (name === \"url\") {\n\t\t\tthis.url.set(newValue ? new URL(newValue) : undefined);\n\t\t} else if (name === \"name\" || name === \"path\") {\n\t\t\tthis.path.set(newValue ? Moq.Path.from(newValue) : undefined);\n\t\t} else if (name === \"source\") {\n\t\t\tif (newValue === \"camera\" || newValue === \"screen\" || newValue === \"file\" || newValue === null) {\n\t\t\t\tthis.source.set(newValue as SourceType | undefined);\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid source: ${newValue}`);\n\t\t\t}\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.muted.set(newValue !== null);\n\t\t} else if (name === \"invisible\") {\n\t\t\tthis.invisible.set(newValue !== null);\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\t#runSource(effect: Effect) {\n\t\tconst source = effect.get(this.source);\n\t\tif (!source) return;\n\n\t\tif (source === \"camera\") {\n\t\t\tconst video = new Source.Camera({ enabled: this.#videoEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(video.source);\n\t\t\t\tthis.broadcast.video.source.set(source);\n\t\t\t});\n\n\t\t\tconst audio = new Source.Microphone({ enabled: this.#audioEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(audio.source);\n\t\t\t\tthis.broadcast.audio.source.set(source);\n\t\t\t});\n\n\t\t\teffect.set(this.video, video);\n\t\t\teffect.set(this.audio, audio);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tvideo.close();\n\t\t\t\taudio.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"screen\") {\n\t\t\tconst screen = new Source.Screen({\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(screen.source);\n\t\t\t\tif (!source) return;\n\n\t\t\t\teffect.set(this.broadcast.video.source, source.video);\n\t\t\t\teffect.set(this.broadcast.audio.source, source.audio);\n\t\t\t});\n\n\t\t\teffect.set(this.video, screen);\n\t\t\teffect.set(this.audio, screen);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tscreen.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"file\" || source instanceof File) {\n\t\t\tconst fileSource = new Source.File({\n\t\t\t\t// If a File is provided, use it directly.\n\t\t\t\t// TODO: Show a file picker otherwise.\n\t\t\t\tfile: source instanceof File ? source : undefined,\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(fileSource.source);\n\t\t\t\tthis.broadcast.video.source.set(source.video);\n\t\t\t\tthis.broadcast.audio.source.set(source.audio);\n\t\t\t});\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tfileSource.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst exhaustive: never = source;\n\t\tthrow new Error(`Invalid source: ${exhaustive}`);\n\t}\n}\n\ncustomElements.define(\"moq-publish\", MoqPublish);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-publish\": MoqPublish;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqPublish","Signal","#preview","#videoEnabled","#audioEnabled","#eitherEnabled","#enabled","Effect","Moq","effect","muted","invisible","Broadcast","setPreview","observer","preview","source","#runSource","name","oldValue","newValue","exhaustive","video","Source.Camera","audio","Source.Microphone","screen","Source.Screen","fileSource","Source.File"],"mappings":"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"}
1
+ {"version":3,"file":"element.js","sources":["../src/element.ts"],"sourcesContent":["import * as Moq from \"@moq/lite\";\nimport { Effect, Signal } from \"@moq/signals\";\nimport { Broadcast } from \"./broadcast\";\nimport * as Source from \"./source\";\n\nconst OBSERVED = [\"url\", \"name\", \"muted\", \"invisible\", \"source\"] as const;\ntype Observed = (typeof OBSERVED)[number];\n\ntype SourceType = \"camera\" | \"screen\" | \"file\";\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\nexport default class MoqPublish extends HTMLElement {\n\tstatic observedAttributes = OBSERVED;\n\n\t// Reactive state for element properties that are also HTML attributes.\n\t// Access these Signals directly for reactive subscriptions (e.g. effect.get(el.state.source)).\n\tstate = {\n\t\tsource: new Signal<SourceType | File | undefined>(undefined),\n\t\tmuted: new Signal(false),\n\t\tinvisible: new Signal(false),\n\t};\n\n\tconnection: Moq.Connection.Reload;\n\tbroadcast: Broadcast;\n\n\t#preview = new Signal<HTMLVideoElement | undefined>(undefined);\n\n\tvideo = new Signal<Source.Camera | Source.Screen | undefined>(undefined);\n\taudio = new Signal<Source.Microphone | Source.Screen | undefined>(undefined);\n\tfile = new Signal<Source.File | undefined>(undefined);\n\n\t// The inverse of the `muted` and `invisible` signals.\n\t#videoEnabled: Signal<boolean>;\n\t#audioEnabled: Signal<boolean>;\n\t#eitherEnabled: Signal<boolean>;\n\n\t// Set when the element is connected to the DOM.\n\t#enabled = new Signal(false);\n\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\t// The inverse of the `muted` and `invisible` signals.\n\t\t// TODO make this.signals.computed to simplify the code.\n\t\tthis.#videoEnabled = new Signal(false);\n\t\tthis.#audioEnabled = new Signal(false);\n\t\tthis.#eitherEnabled = new Signal(false);\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst muted = effect.get(this.state.muted);\n\t\t\tconst invisible = effect.get(this.state.invisible);\n\t\t\tthis.#videoEnabled.set(!invisible);\n\t\t\tthis.#audioEnabled.set(!muted);\n\t\t\tthis.#eitherEnabled.set(!muted || !invisible);\n\t\t});\n\n\t\tthis.broadcast = new Broadcast({\n\t\t\tconnection: this.connection.established,\n\t\t\tenabled: this.#enabled,\n\n\t\t\taudio: {\n\t\t\t\tenabled: this.#audioEnabled,\n\t\t\t},\n\t\t\tvideo: {\n\t\t\t\thd: {\n\t\t\t\t\tenabled: this.#videoEnabled,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t\tthis.signals.cleanup(() => this.broadcast.close());\n\n\t\t// Watch to see if the preview element is added or removed.\n\t\tconst setPreview = () => {\n\t\t\tthis.#preview.set(this.querySelector(\"video\") as HTMLVideoElement | undefined);\n\t\t};\n\t\tconst observer = new MutationObserver(setPreview);\n\t\tobserver.observe(this, { childList: true, subtree: true });\n\t\tthis.signals.cleanup(() => observer.disconnect());\n\t\tsetPreview();\n\n\t\tthis.signals.run((effect) => {\n\t\t\tconst preview = effect.get(this.#preview);\n\t\t\tif (!preview) return;\n\n\t\t\tconst source = effect.get(this.broadcast.video.source);\n\t\t\tif (!source) {\n\t\t\t\tpreview.style.display = \"none\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpreview.srcObject = new MediaStream([source]);\n\t\t\tpreview.style.display = \"block\";\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tpreview.srcObject = null;\n\t\t\t});\n\t\t});\n\n\t\tthis.signals.run(this.#runSource.bind(this));\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#enabled.set(true);\n\t}\n\n\tdisconnectedCallback() {\n\t\tthis.#enabled.set(false);\n\t}\n\n\tattributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null) {\n\t\tif (oldValue === newValue) return;\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(newValue ? Moq.Path.from(newValue) : undefined);\n\t\t} else if (name === \"source\") {\n\t\t\tif (newValue === \"camera\" || newValue === \"screen\" || newValue === \"file\" || newValue === null) {\n\t\t\t\tthis.state.source.set(newValue as SourceType | undefined);\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid source: ${newValue}`);\n\t\t\t}\n\t\t} else if (name === \"muted\") {\n\t\t\tthis.state.muted.set(newValue !== null);\n\t\t} else if (name === \"invisible\") {\n\t\t\tthis.state.invisible.set(newValue !== null);\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\t#runSource(effect: Effect) {\n\t\tconst source = effect.get(this.state.source);\n\t\tif (!source) return;\n\n\t\tif (source === \"camera\") {\n\t\t\tconst video = new Source.Camera({ enabled: this.#videoEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(video.source);\n\t\t\t\tthis.broadcast.video.source.set(source);\n\t\t\t});\n\n\t\t\tconst audio = new Source.Microphone({ enabled: this.#audioEnabled });\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(audio.source);\n\t\t\t\tthis.broadcast.audio.source.set(source);\n\t\t\t});\n\n\t\t\teffect.set(this.video, video);\n\t\t\teffect.set(this.audio, audio);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tvideo.close();\n\t\t\t\taudio.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"screen\") {\n\t\t\tconst screen = new Source.Screen({\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(screen.source);\n\t\t\t\tif (!source) return;\n\n\t\t\t\teffect.set(this.broadcast.video.source, source.video);\n\t\t\t\teffect.set(this.broadcast.audio.source, source.audio);\n\t\t\t});\n\n\t\t\teffect.set(this.video, screen);\n\t\t\teffect.set(this.audio, screen);\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tscreen.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (source === \"file\" || source instanceof File) {\n\t\t\tconst fileSource = new Source.File({\n\t\t\t\t// If a File is provided, use it directly.\n\t\t\t\t// TODO: Show a file picker otherwise.\n\t\t\t\tfile: source instanceof File ? source : undefined,\n\t\t\t\tenabled: this.#eitherEnabled,\n\t\t\t});\n\n\t\t\tthis.signals.run((effect) => {\n\t\t\t\tconst source = effect.get(fileSource.source);\n\t\t\t\tthis.broadcast.video.source.set(source.video);\n\t\t\t\tthis.broadcast.audio.source.set(source.audio);\n\t\t\t});\n\n\t\t\teffect.cleanup(() => {\n\t\t\t\tfileSource.close();\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst exhaustive: never = source;\n\t\tthrow new Error(`Invalid source: ${exhaustive}`);\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 | undefined {\n\t\treturn this.broadcast.name.peek();\n\t}\n\n\tset name(value: string | Moq.Path.Valid | undefined) {\n\t\tthis.broadcast.name.set(value ? Moq.Path.from(value) : undefined);\n\t}\n\n\tget source(): SourceType | File | undefined {\n\t\treturn this.state.source.peek();\n\t}\n\n\tset source(value: SourceType | File | undefined) {\n\t\tthis.state.source.set(value);\n\t}\n\n\tget muted(): boolean {\n\t\treturn this.state.muted.peek();\n\t}\n\n\tset muted(value: boolean) {\n\t\tthis.state.muted.set(value);\n\t}\n\n\tget invisible(): boolean {\n\t\treturn this.state.invisible.peek();\n\t}\n\n\tset invisible(value: boolean) {\n\t\tthis.state.invisible.set(value);\n\t}\n}\n\ncustomElements.define(\"moq-publish\", MoqPublish);\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t\"moq-publish\": MoqPublish;\n\t}\n}\n"],"names":["OBSERVED","cleanup","signals","MoqPublish","Signal","#preview","#videoEnabled","#audioEnabled","#eitherEnabled","#enabled","Effect","Moq","effect","muted","invisible","Broadcast","setPreview","observer","preview","source","#runSource","name","oldValue","newValue","exhaustive","video","Source.Camera","audio","Source.Microphone","screen","Source.Screen","fileSource","Source.File","value"],"mappings":"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"}
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { E as e, C as o, D as a, F as r, M as t, S as s } from "./screen-Dz_GBTAe.js";
2
- import { B as u, i as p, a as _, P as b, u as S, b as f } from "./screen-Dz_GBTAe.js";
1
+ import { E as e, C as o, D as a, F as r, M as t, S as s } from "./screen-BZp2qFyj.js";
2
+ import { B as u, i as p, a as _, P as b, u as S, b as f } from "./screen-BZp2qFyj.js";
3
3
  const n = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4
4
  __proto__: null,
5
5
  Encoder: e
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@moq/publish",
3
3
  "type": "module",
4
- "version": "0.1.1",
5
- "description": "Publish media to Media over QUIC streams",
4
+ "version": "0.2.0",
5
+ "description": "Publish Media over QUIC broadcasts",
6
6
  "license": "(MIT OR Apache-2.0)",
7
7
  "repository": "github:moq-dev/moq",
8
8
  "exports": {
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@moq/hang": "^0.2.0",
37
- "@moq/lite": "^0.1.3",
37
+ "@moq/lite": "^0.1.4",
38
38
  "@moq/signals": "^0.1.3",
39
39
  "@moq/ui-core": "^0.1.0"
40
40
  }
@@ -6246,7 +6246,7 @@ class Xn {
6246
6246
  static CATALOG_TRACK = "catalog.json";
6247
6247
  connection;
6248
6248
  enabled;
6249
- path;
6249
+ name;
6250
6250
  audio;
6251
6251
  video;
6252
6252
  location;
@@ -6255,12 +6255,12 @@ class Xn {
6255
6255
  user;
6256
6256
  signals = new P();
6257
6257
  constructor(n) {
6258
- this.connection = f.from(n?.connection), this.enabled = f.from(n?.enabled ?? !1), this.path = f.from(n?.path), this.audio = new dn(n?.audio), this.video = new B(n?.video), this.location = new Wn(n?.location), this.chat = new Gn(n?.chat), this.preview = new pe(n?.preview), this.user = new Kn(n?.user), this.signals.run(this.#e.bind(this));
6258
+ this.connection = f.from(n?.connection), this.enabled = f.from(n?.enabled ?? !1), this.name = f.from(n?.name), this.audio = new dn(n?.audio), this.video = new B(n?.video), this.location = new Wn(n?.location), this.chat = new Gn(n?.chat), this.preview = new pe(n?.preview), this.user = new Kn(n?.user), this.signals.run(this.#e.bind(this));
6259
6259
  }
6260
6260
  #e(n) {
6261
6261
  const t = n.getAll([this.enabled, this.connection]);
6262
6262
  if (!t) return;
6263
- const [r, s] = t, i = n.get(this.path);
6263
+ const [r, s] = t, i = n.get(this.name);
6264
6264
  if (i === void 0) return;
6265
6265
  const o = new ln.Broadcast();
6266
6266
  n.cleanup(() => o.close()), s.publish(i, o), n.spawn(this.#n.bind(this, o, n));
@@ -6583,4 +6583,4 @@ export {
6583
6583
  aa as i,
6584
6584
  da as u
6585
6585
  };
6586
- //# sourceMappingURL=screen-Dz_GBTAe.js.map
6586
+ //# sourceMappingURL=screen-BZp2qFyj.js.map