@moq/publish 0.1.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/README.md +100 -0
- package/audio/capture-worklet.d.ts +2 -0
- package/audio/capture-worklet.d.ts.map +1 -0
- package/audio/capture.d.ts +6 -0
- package/audio/capture.d.ts.map +1 -0
- package/audio/encoder.d.ts +31 -0
- package/audio/encoder.d.ts.map +1 -0
- package/audio/index.d.ts +3 -0
- package/audio/index.d.ts.map +1 -0
- package/audio/types.d.ts +18 -0
- package/audio/types.d.ts.map +1 -0
- package/broadcast.d.ts +36 -0
- package/broadcast.d.ts.map +1 -0
- package/chat/index.d.ts +19 -0
- package/chat/index.d.ts.map +1 -0
- package/chat/message.d.ts +19 -0
- package/chat/message.d.ts.map +1 -0
- package/chat/typing.d.ts +19 -0
- package/chat/typing.d.ts.map +1 -0
- package/element.d.ts +32 -0
- package/element.d.ts.map +1 -0
- package/element.js +141 -0
- package/element.js.map +1 -0
- package/index.d.ts +9 -0
- package/index.d.ts.map +1 -0
- package/index.js +24 -0
- package/index.js.map +1 -0
- package/libav-opus-af-BlMWboA7.js +368 -0
- package/libav-opus-af-BlMWboA7.js.map +1 -0
- package/location/index.d.ts +33 -0
- package/location/index.d.ts.map +1 -0
- package/location/peers.d.ts +26 -0
- package/location/peers.d.ts.map +1 -0
- package/location/window.d.ts +35 -0
- package/location/window.d.ts.map +1 -0
- package/main-DGBFe0O7.js +2301 -0
- package/main-DGBFe0O7.js.map +1 -0
- package/package.json +41 -0
- package/preview.d.ts +21 -0
- package/preview.d.ts.map +1 -0
- package/screen-BCioRZHS.js +6579 -0
- package/screen-BCioRZHS.js.map +1 -0
- package/source/camera.d.ts +19 -0
- package/source/camera.d.ts.map +1 -0
- package/source/device.d.ts +19 -0
- package/source/device.d.ts.map +1 -0
- package/source/file.d.ts +20 -0
- package/source/file.d.ts.map +1 -0
- package/source/index.d.ts +6 -0
- package/source/index.d.ts.map +1 -0
- package/source/microphone.d.ts +19 -0
- package/source/microphone.d.ts.map +1 -0
- package/source/screen.d.ts +22 -0
- package/source/screen.d.ts.map +1 -0
- package/support/element.d.ts +22 -0
- package/support/element.d.ts.map +1 -0
- package/support/element.js +184 -0
- package/support/element.js.map +1 -0
- package/support/index.d.ts +29 -0
- package/support/index.d.ts.map +1 -0
- package/support/index.js +63 -0
- package/support/index.js.map +1 -0
- package/ui/components/CameraSourceButton.d.ts +2 -0
- package/ui/components/CameraSourceButton.d.ts.map +1 -0
- package/ui/components/FileSourceButton.d.ts +2 -0
- package/ui/components/FileSourceButton.d.ts.map +1 -0
- package/ui/components/MediaSourceSelector.d.ts +8 -0
- package/ui/components/MediaSourceSelector.d.ts.map +1 -0
- package/ui/components/MicrophoneSourceButton.d.ts +2 -0
- package/ui/components/MicrophoneSourceButton.d.ts.map +1 -0
- package/ui/components/NothingSourceButton.d.ts +2 -0
- package/ui/components/NothingSourceButton.d.ts.map +1 -0
- package/ui/components/PublishControls.d.ts +2 -0
- package/ui/components/PublishControls.d.ts.map +1 -0
- package/ui/components/PublishStatusIndicator.d.ts +2 -0
- package/ui/components/PublishStatusIndicator.d.ts.map +1 -0
- package/ui/components/ScreenSourceButton.d.ts +2 -0
- package/ui/components/ScreenSourceButton.d.ts.map +1 -0
- package/ui/context.d.ts +25 -0
- package/ui/context.d.ts.map +1 -0
- package/ui/element.d.ts +5 -0
- package/ui/element.d.ts.map +1 -0
- package/ui/hooks/use-publish-ui.d.ts +15 -0
- package/ui/hooks/use-publish-ui.d.ts.map +1 -0
- package/ui/index.d.ts +7 -0
- package/ui/index.d.ts.map +1 -0
- package/ui/index.js +974 -0
- package/ui/index.js.map +1 -0
- package/user.d.ts +25 -0
- package/user.d.ts.map +1 -0
- package/video/encoder.d.ts +31 -0
- package/video/encoder.d.ts.map +1 -0
- package/video/index.d.ts +85 -0
- package/video/index.d.ts.map +1 -0
- package/video/polyfill.d.ts +3 -0
- package/video/polyfill.d.ts.map +1 -0
- package/video/types.d.ts +20 -0
- package/video/types.d.ts.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img height="128px" src="https://github.com/moq-dev/moq/blob/main/.github/logo.svg" alt="Media over QUIC">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @moq/publish
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@moq/publish)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
|
|
10
|
+
Publish media to [Media over QUIC](https://moq.dev/) (MoQ) broadcasts, built on top of [@moq/hang](../hang) and [@moq/lite](../lite).
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun add @moq/publish
|
|
16
|
+
# or
|
|
17
|
+
npm add @moq/publish
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Web Component
|
|
21
|
+
|
|
22
|
+
The simplest way to publish a stream:
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<script type="module">
|
|
26
|
+
import "@moq/publish/element";
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<moq-publish
|
|
30
|
+
url="https://relay.example.com/anon"
|
|
31
|
+
path="room/alice"
|
|
32
|
+
audio video controls>
|
|
33
|
+
<video muted autoplay></video>
|
|
34
|
+
</moq-publish>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Attributes
|
|
38
|
+
|
|
39
|
+
| Attribute | Type | Default | Description |
|
|
40
|
+
|------------|---------|----------|---------------------------------|
|
|
41
|
+
| `url` | string | required | Relay server URL |
|
|
42
|
+
| `path` | string | required | Broadcast path |
|
|
43
|
+
| `source` | string | — | `"camera"`, `"screen"`, `"file"` |
|
|
44
|
+
| `audio` | boolean | false | Enable audio capture |
|
|
45
|
+
| `video` | boolean | false | Enable video capture |
|
|
46
|
+
| `controls` | boolean | false | Show simple publishing controls |
|
|
47
|
+
|
|
48
|
+
## JavaScript API
|
|
49
|
+
|
|
50
|
+
For more control:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import * as Publish from "@moq/publish";
|
|
54
|
+
|
|
55
|
+
const publish = new Publish.Broadcast(connection, {
|
|
56
|
+
enabled: true,
|
|
57
|
+
name: "alice",
|
|
58
|
+
video: { enabled: true },
|
|
59
|
+
audio: { enabled: true },
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Change source at runtime
|
|
63
|
+
publish.source.camera.enabled.set(true);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## UI Web Component
|
|
67
|
+
|
|
68
|
+
`@moq/publish` includes a SolidJS-powered UI overlay (`<moq-publish-ui>`) with source selection (camera, screen, file, microphone) and status indicator. It depends on [`@moq/ui-core`](../ui-core) for shared UI primitives.
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<script type="module">
|
|
72
|
+
import "@moq/publish/element";
|
|
73
|
+
import "@moq/publish/ui";
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<moq-publish-ui>
|
|
77
|
+
<moq-publish url="https://relay.example.com/anon" path="room/alice" audio video>
|
|
78
|
+
<video muted autoplay></video>
|
|
79
|
+
</moq-publish>
|
|
80
|
+
</moq-publish-ui>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The `<moq-publish-ui>` element automatically discovers the nested `<moq-publish>` element and wires up reactive controls.
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
- **Camera & microphone** — Capture from user devices
|
|
88
|
+
- **Screen sharing** — Capture display or window
|
|
89
|
+
- **File playback** — Publish from a media file
|
|
90
|
+
- **WebCodecs encoding** — Hardware-accelerated video and audio encoding
|
|
91
|
+
- **Reactive state** — All properties are signals from `@moq/signals`
|
|
92
|
+
- **Chat** — Publish text chat messages
|
|
93
|
+
- **Location** — Publish peer position and window tracking
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
Licensed under either:
|
|
98
|
+
|
|
99
|
+
- Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
100
|
+
- MIT license ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-worklet.d.ts","sourceRoot":"","sources":["../../src/audio/capture-worklet.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/audio/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,WAAW,UAAU;IAC1B,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;CACzB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as Catalog from "@moq/hang/catalog";
|
|
2
|
+
import type * as Moq from "@moq/lite";
|
|
3
|
+
import { Time } from "@moq/lite";
|
|
4
|
+
import { Effect, type Getter, Signal } from "@moq/signals";
|
|
5
|
+
import type { Source } from "./types";
|
|
6
|
+
export type EncoderProps = {
|
|
7
|
+
enabled?: boolean | Signal<boolean>;
|
|
8
|
+
source?: Source | Signal<Source | undefined>;
|
|
9
|
+
muted?: boolean | Signal<boolean>;
|
|
10
|
+
volume?: number | Signal<number>;
|
|
11
|
+
maxLatency?: Time.Milli;
|
|
12
|
+
container?: Catalog.Container;
|
|
13
|
+
};
|
|
14
|
+
export declare class Encoder {
|
|
15
|
+
#private;
|
|
16
|
+
static readonly TRACK = "audio/data";
|
|
17
|
+
static readonly PRIORITY: 80;
|
|
18
|
+
enabled: Signal<boolean>;
|
|
19
|
+
muted: Signal<boolean>;
|
|
20
|
+
volume: Signal<number>;
|
|
21
|
+
maxLatency: Time.Milli;
|
|
22
|
+
source: Signal<Source | undefined>;
|
|
23
|
+
readonly catalog: Getter<Catalog.Audio | undefined>;
|
|
24
|
+
readonly config: Getter<Catalog.AudioConfig | undefined>;
|
|
25
|
+
readonly root: Getter<AudioNode | undefined>;
|
|
26
|
+
active: Moq.Signals.Signal<boolean>;
|
|
27
|
+
constructor(props?: EncoderProps);
|
|
28
|
+
serve(track: Moq.Track, effect: Effect): void;
|
|
29
|
+
close(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=encoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/audio/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAG7C,OAAO,KAAK,KAAK,GAAG,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAStC,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE7C,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAIjC,UAAU,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAExB,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;CAC9B,CAAC;AAEF,qBAAa,OAAO;;IACnB,MAAM,CAAC,QAAQ,CAAC,KAAK,gBAAgB;IACrC,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAA0B;IAElD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC;IAEvB,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAGnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAiB;IAGpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAgB;IAKxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,CAAc;IAE1D,MAAM,8BAA8B;gBAIxB,KAAK,CAAC,EAAE,YAAY;IAyFhC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAiF7C,KAAK;CAGL"}
|
package/audio/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/audio/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type Source = StreamTrack;
|
|
2
|
+
export type Constraints = Omit<MediaTrackConstraints, "aspectRatio" | "backgroundBlur" | "displaySurface" | "facingMode" | "frameRate" | "height" | "width">;
|
|
3
|
+
export interface StreamTrack extends MediaStreamTrack {
|
|
4
|
+
kind: "audio";
|
|
5
|
+
clone(): StreamTrack;
|
|
6
|
+
getSettings(): TrackSettings;
|
|
7
|
+
}
|
|
8
|
+
export interface TrackSettings {
|
|
9
|
+
deviceId: string;
|
|
10
|
+
groupId: string;
|
|
11
|
+
sampleRate: number;
|
|
12
|
+
autoGainControl?: boolean;
|
|
13
|
+
channelCount?: number;
|
|
14
|
+
echoCancellation?: boolean;
|
|
15
|
+
noiseSuppression?: boolean;
|
|
16
|
+
sampleSize?: number;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audio/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAEjC,MAAM,MAAM,WAAW,GAAG,IAAI,CAC7B,qBAAqB,EACrB,aAAa,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CACrG,CAAC;AAGF,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACpD,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,IAAI,WAAW,CAAC;IACrB,WAAW,IAAI,aAAa,CAAC;CAC7B;AAID,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAGhB,UAAU,EAAE,MAAM,CAAC;IAGnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
package/broadcast.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as Moq from "@moq/lite";
|
|
2
|
+
import { Signal } from "@moq/signals";
|
|
3
|
+
import * as Audio from "./audio";
|
|
4
|
+
import * as Chat from "./chat";
|
|
5
|
+
import * as Location from "./location";
|
|
6
|
+
import { Preview, type PreviewProps } from "./preview";
|
|
7
|
+
import * as User from "./user";
|
|
8
|
+
import * as Video from "./video";
|
|
9
|
+
export type BroadcastProps = {
|
|
10
|
+
connection?: Moq.Connection.Established | Signal<Moq.Connection.Established | undefined>;
|
|
11
|
+
enabled?: boolean | Signal<boolean>;
|
|
12
|
+
path?: Moq.Path.Valid | Signal<Moq.Path.Valid | undefined>;
|
|
13
|
+
audio?: Audio.EncoderProps;
|
|
14
|
+
video?: Video.Props;
|
|
15
|
+
location?: Location.Props;
|
|
16
|
+
user?: User.Props;
|
|
17
|
+
chat?: Chat.Props;
|
|
18
|
+
preview?: PreviewProps;
|
|
19
|
+
};
|
|
20
|
+
export declare class Broadcast {
|
|
21
|
+
#private;
|
|
22
|
+
static readonly CATALOG_TRACK = "catalog.json";
|
|
23
|
+
connection: Signal<Moq.Connection.Established | undefined>;
|
|
24
|
+
enabled: Signal<boolean>;
|
|
25
|
+
path: Signal<Moq.Path.Valid | undefined>;
|
|
26
|
+
audio: Audio.Encoder;
|
|
27
|
+
video: Video.Root;
|
|
28
|
+
location: Location.Root;
|
|
29
|
+
chat: Chat.Root;
|
|
30
|
+
preview: Preview;
|
|
31
|
+
user: User.Info;
|
|
32
|
+
signals: Moq.Signals.Effect;
|
|
33
|
+
constructor(props?: BroadcastProps);
|
|
34
|
+
close(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=broadcast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../src/broadcast.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EAAU,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,cAAc,GAAG;IAC5B,UAAU,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IACzF,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC1B,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAClB,OAAO,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,qBAAa,SAAS;;IACrB,MAAM,CAAC,QAAQ,CAAC,aAAa,kBAAkB;IAE/C,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAEzC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;IAElB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;IAEhB,OAAO,qBAAgB;gBAEX,KAAK,CAAC,EAAE,cAAc;IAmGlC,KAAK;CASL"}
|
package/chat/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as Catalog from "@moq/hang/catalog";
|
|
2
|
+
import { type Getter } from "@moq/signals";
|
|
3
|
+
import { Message, type MessageProps } from "./message";
|
|
4
|
+
import { Typing, type TypingProps } from "./typing";
|
|
5
|
+
export * from "./message";
|
|
6
|
+
export * from "./typing";
|
|
7
|
+
export type Props = {
|
|
8
|
+
message?: MessageProps;
|
|
9
|
+
typing?: TypingProps;
|
|
10
|
+
};
|
|
11
|
+
export declare class Root {
|
|
12
|
+
#private;
|
|
13
|
+
message: Message;
|
|
14
|
+
typing: Typing;
|
|
15
|
+
readonly catalog: Getter<Catalog.Chat | undefined>;
|
|
16
|
+
constructor(props?: Props);
|
|
17
|
+
close(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAU,KAAK,MAAM,EAAU,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AAEzB,MAAM,MAAM,KAAK,GAAG;IACnB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,qBAAa,IAAI;;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAiB;gBAIvD,KAAK,CAAC,EAAE,KAAK;IAYzB,KAAK;CAKL"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as Moq from "@moq/lite";
|
|
2
|
+
import { Effect, Signal } from "@moq/signals";
|
|
3
|
+
export type MessageProps = {
|
|
4
|
+
enabled?: boolean | Signal<boolean>;
|
|
5
|
+
};
|
|
6
|
+
export declare class Message {
|
|
7
|
+
#private;
|
|
8
|
+
static readonly TRACK = "chat/message.txt";
|
|
9
|
+
static readonly PRIORITY: 90;
|
|
10
|
+
enabled: Signal<boolean>;
|
|
11
|
+
latest: Signal<string>;
|
|
12
|
+
catalog: Moq.Signals.Signal<{
|
|
13
|
+
name: string;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
constructor(props?: MessageProps);
|
|
16
|
+
serve(track: Moq.Track, effect: Effect): void;
|
|
17
|
+
close(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/chat/message.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,GAAG,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,qBAAa,OAAO;;IACnB,MAAM,CAAC,QAAQ,CAAC,KAAK,sBAAsB;IAC3C,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAAyB;IAEjD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO;;mBAAoD;gBAI/C,KAAK,CAAC,EAAE,YAAY;IAYhC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ7C,KAAK;CAGL"}
|
package/chat/typing.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type * as Moq from "@moq/lite";
|
|
2
|
+
import { Effect, Signal } from "@moq/signals";
|
|
3
|
+
export type TypingProps = {
|
|
4
|
+
enabled?: boolean | Signal<boolean>;
|
|
5
|
+
};
|
|
6
|
+
export declare class Typing {
|
|
7
|
+
#private;
|
|
8
|
+
static readonly TRACK = "chat/typing.bool";
|
|
9
|
+
static readonly PRIORITY: 40;
|
|
10
|
+
enabled: Signal<boolean>;
|
|
11
|
+
active: Signal<boolean>;
|
|
12
|
+
catalog: Moq.Signals.Signal<{
|
|
13
|
+
name: string;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
constructor(props?: TypingProps);
|
|
16
|
+
serve(track: Moq.Track, effect: Effect): void;
|
|
17
|
+
close(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=typing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typing.d.ts","sourceRoot":"","sources":["../../src/chat/typing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,GAAG,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,qBAAa,MAAM;;IAClB,MAAM,CAAC,QAAQ,CAAC,KAAK,sBAAsB;IAC3C,MAAM,CAAC,QAAQ,CAAC,QAAQ,KAA2B;IAEnD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAGzB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAExB,OAAO;;mBAAoD;gBAI/C,KAAK,CAAC,EAAE,WAAW;IAY/B,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ7C,KAAK;CAGL"}
|
package/element.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as Moq from "@moq/lite";
|
|
2
|
+
import { Broadcast } from "./broadcast";
|
|
3
|
+
import * as Source from "./source";
|
|
4
|
+
declare const OBSERVED: readonly ["url", "name", "path", "muted", "invisible", "source"];
|
|
5
|
+
type Observed = (typeof OBSERVED)[number];
|
|
6
|
+
type SourceType = "camera" | "screen" | "file";
|
|
7
|
+
export default class MoqPublish extends HTMLElement {
|
|
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>;
|
|
15
|
+
connection: Moq.Connection.Reload;
|
|
16
|
+
broadcast: Broadcast;
|
|
17
|
+
video: Moq.Signals.Signal<Source.Camera | Source.Screen | undefined>;
|
|
18
|
+
audio: Moq.Signals.Signal<Source.Microphone | Source.Screen | undefined>;
|
|
19
|
+
file: Moq.Signals.Signal<Source.File | undefined>;
|
|
20
|
+
signals: Moq.Signals.Effect;
|
|
21
|
+
constructor();
|
|
22
|
+
connectedCallback(): void;
|
|
23
|
+
disconnectedCallback(): void;
|
|
24
|
+
attributeChangedCallback(name: Observed, oldValue: string | null, newValue: string | null): void;
|
|
25
|
+
}
|
|
26
|
+
declare global {
|
|
27
|
+
interface HTMLElementTagNameMap {
|
|
28
|
+
"moq-publish": MoqPublish;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=element.d.ts.map
|
package/element.d.ts.map
ADDED
|
@@ -0,0 +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"}
|
package/element.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as l from "@moq/lite";
|
|
2
|
+
import { Signal as n, Effect as d } from "@moq/signals";
|
|
3
|
+
import { B as h, C as u, M as b, S as v, F as f } from "./screen-BCioRZHS.js";
|
|
4
|
+
const g = ["url", "name", "path", "muted", "invisible", "source"], p = new FinalizationRegistry((a) => a.close());
|
|
5
|
+
class w extends HTMLElement {
|
|
6
|
+
static observedAttributes = g;
|
|
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);
|
|
13
|
+
connection;
|
|
14
|
+
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);
|
|
19
|
+
// The inverse of the `muted` and `invisible` signals.
|
|
20
|
+
#s;
|
|
21
|
+
#e;
|
|
22
|
+
#t;
|
|
23
|
+
// Set when the element is connected to the DOM.
|
|
24
|
+
#i = new n(!1);
|
|
25
|
+
signals = new d();
|
|
26
|
+
constructor() {
|
|
27
|
+
super(), p.register(this, this.signals), this.connection = new l.Connection.Reload({
|
|
28
|
+
url: this.url,
|
|
29
|
+
enabled: this.#i
|
|
30
|
+
}), this.signals.cleanup(() => this.connection.close()), this.#s = new n(!1), this.#e = new n(!1), this.#t = new n(!1), this.signals.effect((s) => {
|
|
31
|
+
const e = s.get(this.muted), i = s.get(this.invisible);
|
|
32
|
+
this.#s.set(!i), this.#e.set(!e), this.#t.set(!e || !i);
|
|
33
|
+
}), this.broadcast = new h({
|
|
34
|
+
connection: this.connection.established,
|
|
35
|
+
enabled: this.#i,
|
|
36
|
+
path: this.path,
|
|
37
|
+
audio: {
|
|
38
|
+
enabled: this.#e
|
|
39
|
+
},
|
|
40
|
+
video: {
|
|
41
|
+
hd: {
|
|
42
|
+
enabled: this.#s
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}), this.signals.cleanup(() => this.broadcast.close());
|
|
46
|
+
const t = () => {
|
|
47
|
+
this.#o.set(this.querySelector("video"));
|
|
48
|
+
}, o = new MutationObserver(t);
|
|
49
|
+
o.observe(this, { childList: !0, subtree: !0 }), this.signals.cleanup(() => o.disconnect()), t(), this.signals.effect((s) => {
|
|
50
|
+
const e = s.get(this.#o);
|
|
51
|
+
if (!e) return;
|
|
52
|
+
const i = s.get(this.broadcast.video.source);
|
|
53
|
+
if (!i) {
|
|
54
|
+
e.style.display = "none";
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
e.srcObject = new MediaStream([i]), e.style.display = "block", s.cleanup(() => {
|
|
58
|
+
e.srcObject = null;
|
|
59
|
+
});
|
|
60
|
+
}), this.signals.effect(this.#n.bind(this));
|
|
61
|
+
}
|
|
62
|
+
connectedCallback() {
|
|
63
|
+
this.#i.set(!0);
|
|
64
|
+
}
|
|
65
|
+
disconnectedCallback() {
|
|
66
|
+
this.#i.set(!1);
|
|
67
|
+
}
|
|
68
|
+
attributeChangedCallback(t, o, s) {
|
|
69
|
+
if (o !== s)
|
|
70
|
+
if (t === "url")
|
|
71
|
+
this.url.set(s ? new URL(s) : void 0);
|
|
72
|
+
else if (t === "name" || t === "path")
|
|
73
|
+
this.path.set(s ? l.Path.from(s) : void 0);
|
|
74
|
+
else if (t === "source")
|
|
75
|
+
if (s === "camera" || s === "screen" || s === "file" || s === null)
|
|
76
|
+
this.source.set(s);
|
|
77
|
+
else
|
|
78
|
+
throw new Error(`Invalid source: ${s}`);
|
|
79
|
+
else if (t === "muted")
|
|
80
|
+
this.muted.set(s !== null);
|
|
81
|
+
else if (t === "invisible")
|
|
82
|
+
this.invisible.set(s !== null);
|
|
83
|
+
else {
|
|
84
|
+
const e = t;
|
|
85
|
+
throw new Error(`Invalid attribute: ${e}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
#n(t) {
|
|
89
|
+
const o = t.get(this.source);
|
|
90
|
+
if (!o) return;
|
|
91
|
+
if (o === "camera") {
|
|
92
|
+
const e = new u({ enabled: this.#s });
|
|
93
|
+
this.signals.effect((r) => {
|
|
94
|
+
const c = r.get(e.source);
|
|
95
|
+
this.broadcast.video.source.set(c);
|
|
96
|
+
});
|
|
97
|
+
const i = new b({ enabled: this.#e });
|
|
98
|
+
this.signals.effect((r) => {
|
|
99
|
+
const c = r.get(i.source);
|
|
100
|
+
this.broadcast.audio.source.set(c);
|
|
101
|
+
}), t.set(this.video, e), t.set(this.audio, i), t.cleanup(() => {
|
|
102
|
+
e.close(), i.close();
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (o === "screen") {
|
|
107
|
+
const e = new v({
|
|
108
|
+
enabled: this.#t
|
|
109
|
+
});
|
|
110
|
+
this.signals.effect((i) => {
|
|
111
|
+
const r = i.get(e.source);
|
|
112
|
+
r && (i.set(this.broadcast.video.source, r.video), i.set(this.broadcast.audio.source, r.audio));
|
|
113
|
+
}), t.set(this.video, e), t.set(this.audio, e), t.cleanup(() => {
|
|
114
|
+
e.close();
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (o === "file" || o instanceof File) {
|
|
119
|
+
const e = new f({
|
|
120
|
+
// If a File is provided, use it directly.
|
|
121
|
+
// TODO: Show a file picker otherwise.
|
|
122
|
+
file: o instanceof File ? o : void 0,
|
|
123
|
+
enabled: this.#t
|
|
124
|
+
});
|
|
125
|
+
this.signals.effect((i) => {
|
|
126
|
+
const r = i.get(e.source);
|
|
127
|
+
this.broadcast.video.source.set(r.video), this.broadcast.audio.source.set(r.audio);
|
|
128
|
+
}), t.cleanup(() => {
|
|
129
|
+
e.close();
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const s = o;
|
|
134
|
+
throw new Error(`Invalid source: ${s}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
customElements.define("moq-publish", w);
|
|
138
|
+
export {
|
|
139
|
+
w as default
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=element.js.map
|
package/element.js.map
ADDED
|
@@ -0,0 +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.effect((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.effect((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.effect(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.effect((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.effect((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.effect((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.effect((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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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * as Audio from "./audio";
|
|
2
|
+
export * from "./broadcast";
|
|
3
|
+
export * as Chat from "./chat";
|
|
4
|
+
export * as Location from "./location";
|
|
5
|
+
export * from "./preview";
|
|
6
|
+
export * as Source from "./source";
|
|
7
|
+
export * as User from "./user";
|
|
8
|
+
export * as Video from "./video";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { E as e, C as o, D as a, F as r, M as t, S as s } from "./screen-BCioRZHS.js";
|
|
2
|
+
import { B as u, i as p, a as _, P as b, u as S, b as f } from "./screen-BCioRZHS.js";
|
|
3
|
+
const n = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4
|
+
__proto__: null,
|
|
5
|
+
Encoder: e
|
|
6
|
+
}, Symbol.toStringTag, { value: "Module" })), c = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
7
|
+
__proto__: null,
|
|
8
|
+
Camera: o,
|
|
9
|
+
Device: a,
|
|
10
|
+
File: r,
|
|
11
|
+
Microphone: t,
|
|
12
|
+
Screen: s
|
|
13
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
14
|
+
export {
|
|
15
|
+
n as Audio,
|
|
16
|
+
u as Broadcast,
|
|
17
|
+
p as Chat,
|
|
18
|
+
_ as Location,
|
|
19
|
+
b as Preview,
|
|
20
|
+
c as Source,
|
|
21
|
+
S as User,
|
|
22
|
+
f as Video
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|