@sprucelabs/heartwood-view-controllers 119.3.1 → 119.4.1
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/build/esm/tests/AbstractViewControllerTest.d.ts +14 -14
- package/build/esm/tests/AbstractViewControllerTest.js +14 -12
- package/build/esm/tests/MockRtcPeerConnection.d.ts +5 -2
- package/build/esm/tests/MockRtcPeerConnection.js +20 -12
- package/build/esm/webRtcStreaming/WebRtcConnection.d.ts +12 -2
- package/build/esm/webRtcStreaming/WebRtcConnection.js +7 -3
- package/build/tests/AbstractViewControllerTest.d.ts +14 -14
- package/build/tests/AbstractViewControllerTest.js +13 -10
- package/build/tests/MockRtcPeerConnection.d.ts +5 -2
- package/build/tests/MockRtcPeerConnection.js +18 -12
- package/build/webRtcStreaming/WebRtcConnection.d.ts +12 -2
- package/build/webRtcStreaming/WebRtcConnection.js +6 -2
- package/package.json +19 -19
|
@@ -6,20 +6,20 @@ import { RenderOptions } from '../utilities/render.utility';
|
|
|
6
6
|
import ViewControllerFactory, { ViewControllerFactoryOptions } from '../viewControllers/ViewControllerFactory';
|
|
7
7
|
import MercuryFixture from './fixtures/MercuryFixture';
|
|
8
8
|
export default abstract class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
9
|
-
protected
|
|
10
|
-
protected
|
|
11
|
-
private
|
|
12
|
-
protected
|
|
13
|
-
protected
|
|
14
|
-
protected
|
|
15
|
-
protected
|
|
16
|
-
protected
|
|
17
|
-
protected
|
|
18
|
-
protected
|
|
19
|
-
protected
|
|
20
|
-
protected
|
|
21
|
-
protected
|
|
22
|
-
protected
|
|
9
|
+
protected controllerMap: Record<string, any>;
|
|
10
|
+
protected views?: ViewControllerFactory;
|
|
11
|
+
private mercuryFixture?;
|
|
12
|
+
protected client: MercuryClient;
|
|
13
|
+
protected eventFaker: EventFaker;
|
|
14
|
+
protected get mercury(): MercuryFixture;
|
|
15
|
+
protected beforeEach(): Promise<void>;
|
|
16
|
+
protected afterEach(): Promise<void>;
|
|
17
|
+
protected Factory(options?: Partial<ViewControllerFactoryOptions>): ViewControllerFactory;
|
|
18
|
+
protected getFactory(): ViewControllerFactory;
|
|
19
|
+
protected Controller<N extends keyof ViewControllerMap>(name: N, options: ControllerOptions<N>): ViewControllerMap[N];
|
|
20
|
+
protected App<N extends AppControllerId>(name: N, options?: Partial<ControllerOptions<N>>): import("../types/heartwood.types").AppControllerMap[N];
|
|
21
|
+
protected render<Vc extends ViewController<any>>(vc: Vc, options?: RenderOptions): ReturnType<Vc["render"]>;
|
|
22
|
+
protected click(button?: {
|
|
23
23
|
onClick?: (() => void | Promise<void>) | null | undefined;
|
|
24
24
|
} | null): Promise<void>;
|
|
25
25
|
}
|
|
@@ -24,14 +24,18 @@ import formAssert from './utilities/formAssert.js';
|
|
|
24
24
|
import interactor from './utilities/interactor.js';
|
|
25
25
|
import listAssert from './utilities/listAssert.js';
|
|
26
26
|
import vcAssert from './utilities/vcAssert.js';
|
|
27
|
-
class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
28
|
-
|
|
27
|
+
export default class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
this.controllerMap = {};
|
|
31
|
+
}
|
|
32
|
+
get mercury() {
|
|
29
33
|
if (!this.mercuryFixture) {
|
|
30
34
|
this.mercuryFixture = new MercuryFixture(this.cwd);
|
|
31
35
|
}
|
|
32
36
|
return this.mercuryFixture;
|
|
33
37
|
}
|
|
34
|
-
|
|
38
|
+
beforeEach() {
|
|
35
39
|
const _super = Object.create(null, {
|
|
36
40
|
beforeEach: { get: () => super.beforeEach }
|
|
37
41
|
});
|
|
@@ -54,7 +58,7 @@ class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
|
54
58
|
this.eventFaker = new EventFaker(this.client);
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
|
-
|
|
61
|
+
afterEach() {
|
|
58
62
|
const _super = Object.create(null, {
|
|
59
63
|
afterEach: { get: () => super.afterEach }
|
|
60
64
|
});
|
|
@@ -64,32 +68,30 @@ class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
|
64
68
|
yield ((_a = this.mercuryFixture) === null || _a === void 0 ? void 0 : _a.destroy());
|
|
65
69
|
});
|
|
66
70
|
}
|
|
67
|
-
|
|
71
|
+
Factory(options) {
|
|
68
72
|
const mercury = this.mercury;
|
|
69
73
|
return ViewControllerFactory.Factory(Object.assign({ controllerMap: this.controllerMap, device: new SpyDevice(), connectToApi: () => {
|
|
70
74
|
return mercury.connectToApi();
|
|
71
75
|
} }, options));
|
|
72
76
|
}
|
|
73
|
-
|
|
77
|
+
getFactory() {
|
|
74
78
|
if (!this.views) {
|
|
75
79
|
this.views = this.Factory();
|
|
76
80
|
}
|
|
77
81
|
return this.views;
|
|
78
82
|
}
|
|
79
|
-
|
|
83
|
+
Controller(name, options) {
|
|
80
84
|
const vc = this.getFactory().Controller(name, options);
|
|
81
85
|
this.render(vc);
|
|
82
86
|
return vc;
|
|
83
87
|
}
|
|
84
|
-
|
|
88
|
+
App(name, options) {
|
|
85
89
|
return this.getFactory().App(name, options);
|
|
86
90
|
}
|
|
87
|
-
|
|
91
|
+
render(vc, options) {
|
|
88
92
|
return renderUtil.render(vc, options);
|
|
89
93
|
}
|
|
90
|
-
|
|
94
|
+
click(button) {
|
|
91
95
|
return interactor.click(button);
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
|
-
AbstractViewControllerTest.controllerMap = {};
|
|
95
|
-
export default AbstractViewControllerTest;
|
|
@@ -4,9 +4,11 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
4
4
|
private constructorOptions?;
|
|
5
5
|
offer: RTCSessionDescription;
|
|
6
6
|
private lastAddedEventListener?;
|
|
7
|
+
private eventListeners;
|
|
7
8
|
private addedTransceivers;
|
|
8
9
|
private lastCreatedDataChannel?;
|
|
9
10
|
private tranceiverAndDataChannelCalls;
|
|
11
|
+
private stats;
|
|
10
12
|
constructor(options?: RTCConfiguration);
|
|
11
13
|
assertCreatedOfferEquals(offer: RTCSessionDescriptionInit): void;
|
|
12
14
|
assertCreatedDataChannel(label: string, dataChannelDict?: RTCDataChannelInit): void;
|
|
@@ -24,7 +26,6 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
24
26
|
}): void;
|
|
25
27
|
assertTrackListenerSet(expected: () => void): void;
|
|
26
28
|
static onCreateOffer(cb?: () => void): void;
|
|
27
|
-
emitTrackAdded(event?: RTCTrackEvent): void;
|
|
28
29
|
canTrickleIceCandidates: boolean | null;
|
|
29
30
|
connectionState: RTCPeerConnectionState;
|
|
30
31
|
currentLocalDescription: RTCSessionDescription | null;
|
|
@@ -56,7 +57,8 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
56
57
|
getConfiguration(): RTCConfiguration;
|
|
57
58
|
getReceivers(): RTCRtpReceiver[];
|
|
58
59
|
getSenders(): RTCRtpSender[];
|
|
59
|
-
getStats(_selector?: unknown, _successCallback?: unknown, _failureCallback?: unknown): Promise<
|
|
60
|
+
getStats(_selector?: unknown, _successCallback?: unknown, _failureCallback?: unknown): Promise<RTCStatsReport>;
|
|
61
|
+
setStats(stats: RTCStatsReport): void;
|
|
60
62
|
getTransceivers(): RTCRtpTransceiver[];
|
|
61
63
|
removeTrack(): void;
|
|
62
64
|
restartIce(): void;
|
|
@@ -68,6 +70,7 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
68
70
|
}): Promise<void>;
|
|
69
71
|
addEventListener(type: unknown, listener: unknown, _options?: unknown): void;
|
|
70
72
|
removeEventListener(_type: unknown, _listener: unknown, _options?: unknown): void;
|
|
73
|
+
emitEvent(name: string, event?: Event): Promise<void>;
|
|
71
74
|
dispatchEvent(_event: Event): boolean;
|
|
72
75
|
}
|
|
73
76
|
export interface AddedTransceiver {
|
|
@@ -13,10 +13,12 @@ export default class MockRtcPeerConnection {
|
|
|
13
13
|
this.offer = {
|
|
14
14
|
[generateId()]: generateId(),
|
|
15
15
|
};
|
|
16
|
+
this.eventListeners = [];
|
|
16
17
|
this.addedTransceivers = [];
|
|
17
18
|
this.tranceiverAndDataChannelCalls = [];
|
|
19
|
+
this.stats = [];
|
|
18
20
|
this.canTrickleIceCandidates = null;
|
|
19
|
-
this.connectionState =
|
|
21
|
+
this.connectionState = 'connected';
|
|
20
22
|
this.currentLocalDescription = null;
|
|
21
23
|
this.currentRemoteDescription = null;
|
|
22
24
|
this.iceConnectionState = {};
|
|
@@ -85,15 +87,6 @@ export default class MockRtcPeerConnection {
|
|
|
85
87
|
static onCreateOffer(cb) {
|
|
86
88
|
this.onCreateOfferHandler = cb;
|
|
87
89
|
}
|
|
88
|
-
emitTrackAdded(event) {
|
|
89
|
-
const lastListener = this.lastAddedEventListener;
|
|
90
|
-
if ((lastListener === null || lastListener === void 0 ? void 0 : lastListener.eventName) === 'track') {
|
|
91
|
-
lastListener.listener(event !== null && event !== void 0 ? event : {});
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
assert.fail('Did not call connection.addEventListener with track listener');
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
90
|
addIceCandidate(_candidate, _successCallback, _failureCallback) {
|
|
98
91
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
92
|
throw new Error('Method not implemented.');
|
|
@@ -143,12 +136,14 @@ export default class MockRtcPeerConnection {
|
|
|
143
136
|
getSenders() {
|
|
144
137
|
return [];
|
|
145
138
|
}
|
|
146
|
-
//@ts-ignore
|
|
147
139
|
getStats(_selector, _successCallback, _failureCallback) {
|
|
148
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
-
|
|
141
|
+
return this.stats;
|
|
150
142
|
});
|
|
151
143
|
}
|
|
144
|
+
setStats(stats) {
|
|
145
|
+
this.stats = stats;
|
|
146
|
+
}
|
|
152
147
|
getTransceivers() {
|
|
153
148
|
return [];
|
|
154
149
|
}
|
|
@@ -170,10 +165,23 @@ export default class MockRtcPeerConnection {
|
|
|
170
165
|
eventName: type,
|
|
171
166
|
listener,
|
|
172
167
|
};
|
|
168
|
+
this.eventListeners.push({
|
|
169
|
+
type,
|
|
170
|
+
listener,
|
|
171
|
+
});
|
|
173
172
|
}
|
|
174
173
|
removeEventListener(_type, _listener, _options) {
|
|
175
174
|
throw new Error('Method not implemented.');
|
|
176
175
|
}
|
|
176
|
+
emitEvent(name, event) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
for (const listener of this.eventListeners) {
|
|
179
|
+
if (listener.type === name) {
|
|
180
|
+
yield listener.listener(event);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
177
185
|
dispatchEvent(_event) {
|
|
178
186
|
return true;
|
|
179
187
|
}
|
|
@@ -20,8 +20,18 @@ export interface WebRtcVcPluginCreateOfferOptions {
|
|
|
20
20
|
offerToReceiveVideo?: boolean;
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
export
|
|
24
|
-
|
|
23
|
+
export interface WebRtcStateEventMap {
|
|
24
|
+
createdOffer: RTCTrackEvent;
|
|
25
|
+
suppliedAnswer: RTCTrackEvent;
|
|
26
|
+
trackAdded: RTCTrackEvent;
|
|
27
|
+
error: WebRtcErrorEvent;
|
|
28
|
+
}
|
|
29
|
+
export type WebRtcConnectionState = keyof WebRtcStateEventMap;
|
|
30
|
+
export type WebRtcStateChangeEvent = RTCTrackEvent | WebRtcErrorEvent;
|
|
31
|
+
export type WebRtcStateChangeHandler = (state: WebRtcConnectionState, event?: WebRtcStateChangeEvent) => void | Promise<void>;
|
|
32
|
+
export interface WebRtcErrorEvent {
|
|
33
|
+
stats: RTCStatsReport;
|
|
34
|
+
}
|
|
25
35
|
export interface WebRtcConnection {
|
|
26
36
|
offStateChange(listener: WebRtcStateChangeHandler): void;
|
|
27
37
|
createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
|
|
@@ -44,9 +44,13 @@ export default class WebRtcConnectionImpl {
|
|
|
44
44
|
iceServers: [],
|
|
45
45
|
});
|
|
46
46
|
this.rtcPeerConnection = connection;
|
|
47
|
-
connection.addEventListener('connectionstatechange', () => {
|
|
48
|
-
this.log.info(
|
|
49
|
-
|
|
47
|
+
connection.addEventListener('connectionstatechange', () => __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
this.log.info(`RTCPeerConnection state changed to ${connection.connectionState}`);
|
|
49
|
+
if (connection.connectionState === 'failed') {
|
|
50
|
+
const stats = yield connection.getStats();
|
|
51
|
+
yield this.emitStateChange('error', { stats });
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
50
54
|
const { offerToReceiveAudio, offerToReceiveVideo } = offerOptions;
|
|
51
55
|
if (offerToReceiveAudio) {
|
|
52
56
|
connection.addTransceiver('audio', { direction: 'recvonly' });
|
|
@@ -6,20 +6,20 @@ import { RenderOptions } from '../utilities/render.utility';
|
|
|
6
6
|
import ViewControllerFactory, { ViewControllerFactoryOptions } from '../viewControllers/ViewControllerFactory';
|
|
7
7
|
import MercuryFixture from './fixtures/MercuryFixture';
|
|
8
8
|
export default abstract class AbstractViewControllerTest extends AbstractSpruceTest {
|
|
9
|
-
protected
|
|
10
|
-
protected
|
|
11
|
-
private
|
|
12
|
-
protected
|
|
13
|
-
protected
|
|
14
|
-
protected
|
|
15
|
-
protected
|
|
16
|
-
protected
|
|
17
|
-
protected
|
|
18
|
-
protected
|
|
19
|
-
protected
|
|
20
|
-
protected
|
|
21
|
-
protected
|
|
22
|
-
protected
|
|
9
|
+
protected controllerMap: Record<string, any>;
|
|
10
|
+
protected views?: ViewControllerFactory;
|
|
11
|
+
private mercuryFixture?;
|
|
12
|
+
protected client: MercuryClient;
|
|
13
|
+
protected eventFaker: EventFaker;
|
|
14
|
+
protected get mercury(): MercuryFixture;
|
|
15
|
+
protected beforeEach(): Promise<void>;
|
|
16
|
+
protected afterEach(): Promise<void>;
|
|
17
|
+
protected Factory(options?: Partial<ViewControllerFactoryOptions>): ViewControllerFactory;
|
|
18
|
+
protected getFactory(): ViewControllerFactory;
|
|
19
|
+
protected Controller<N extends keyof ViewControllerMap>(name: N, options: ControllerOptions<N>): ViewControllerMap[N];
|
|
20
|
+
protected App<N extends AppControllerId>(name: N, options?: Partial<ControllerOptions<N>>): import("../types/heartwood.types").AppControllerMap[N];
|
|
21
|
+
protected render<Vc extends ViewController<any>>(vc: Vc, options?: RenderOptions): ReturnType<Vc["render"]>;
|
|
22
|
+
protected click(button?: {
|
|
23
23
|
onClick?: (() => void | Promise<void>) | null | undefined;
|
|
24
24
|
} | null): Promise<void>;
|
|
25
25
|
}
|
|
@@ -21,13 +21,17 @@ const interactor_1 = __importDefault(require("./utilities/interactor"));
|
|
|
21
21
|
const listAssert_1 = __importDefault(require("./utilities/listAssert"));
|
|
22
22
|
const vcAssert_1 = __importDefault(require("./utilities/vcAssert"));
|
|
23
23
|
class AbstractViewControllerTest extends test_utils_1.default {
|
|
24
|
-
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.controllerMap = {};
|
|
27
|
+
}
|
|
28
|
+
get mercury() {
|
|
25
29
|
if (!this.mercuryFixture) {
|
|
26
30
|
this.mercuryFixture = new MercuryFixture_1.default(this.cwd);
|
|
27
31
|
}
|
|
28
32
|
return this.mercuryFixture;
|
|
29
33
|
}
|
|
30
|
-
|
|
34
|
+
async beforeEach() {
|
|
31
35
|
await super.beforeEach();
|
|
32
36
|
delete ViewControllerFactory_1.default.Class;
|
|
33
37
|
Authenticator_1.default.reset();
|
|
@@ -45,11 +49,11 @@ class AbstractViewControllerTest extends test_utils_1.default {
|
|
|
45
49
|
this.client = mercury_client_1.MercuryTestClient.getInternalEmitter(spruce_event_utils_1.eventContractUtil.unifyContracts(mercury_core_events_1.coreEventContracts));
|
|
46
50
|
this.eventFaker = new EventFaker_1.default(this.client);
|
|
47
51
|
}
|
|
48
|
-
|
|
52
|
+
async afterEach() {
|
|
49
53
|
await super.afterEach();
|
|
50
54
|
await this.mercuryFixture?.destroy();
|
|
51
55
|
}
|
|
52
|
-
|
|
56
|
+
Factory(options) {
|
|
53
57
|
const mercury = this.mercury;
|
|
54
58
|
return ViewControllerFactory_1.default.Factory({
|
|
55
59
|
controllerMap: this.controllerMap,
|
|
@@ -60,26 +64,25 @@ class AbstractViewControllerTest extends test_utils_1.default {
|
|
|
60
64
|
...options,
|
|
61
65
|
});
|
|
62
66
|
}
|
|
63
|
-
|
|
67
|
+
getFactory() {
|
|
64
68
|
if (!this.views) {
|
|
65
69
|
this.views = this.Factory();
|
|
66
70
|
}
|
|
67
71
|
return this.views;
|
|
68
72
|
}
|
|
69
|
-
|
|
73
|
+
Controller(name, options) {
|
|
70
74
|
const vc = this.getFactory().Controller(name, options);
|
|
71
75
|
this.render(vc);
|
|
72
76
|
return vc;
|
|
73
77
|
}
|
|
74
|
-
|
|
78
|
+
App(name, options) {
|
|
75
79
|
return this.getFactory().App(name, options);
|
|
76
80
|
}
|
|
77
|
-
|
|
81
|
+
render(vc, options) {
|
|
78
82
|
return render_utility_1.default.render(vc, options);
|
|
79
83
|
}
|
|
80
|
-
|
|
84
|
+
click(button) {
|
|
81
85
|
return interactor_1.default.click(button);
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
|
-
AbstractViewControllerTest.controllerMap = {};
|
|
85
88
|
exports.default = AbstractViewControllerTest;
|
|
@@ -4,9 +4,11 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
4
4
|
private constructorOptions?;
|
|
5
5
|
offer: RTCSessionDescription;
|
|
6
6
|
private lastAddedEventListener?;
|
|
7
|
+
private eventListeners;
|
|
7
8
|
private addedTransceivers;
|
|
8
9
|
private lastCreatedDataChannel?;
|
|
9
10
|
private tranceiverAndDataChannelCalls;
|
|
11
|
+
private stats;
|
|
10
12
|
constructor(options?: RTCConfiguration);
|
|
11
13
|
assertCreatedOfferEquals(offer: RTCSessionDescriptionInit): void;
|
|
12
14
|
assertCreatedDataChannel(label: string, dataChannelDict?: RTCDataChannelInit): void;
|
|
@@ -24,7 +26,6 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
24
26
|
}): void;
|
|
25
27
|
assertTrackListenerSet(expected: () => void): void;
|
|
26
28
|
static onCreateOffer(cb?: () => void): void;
|
|
27
|
-
emitTrackAdded(event?: RTCTrackEvent): void;
|
|
28
29
|
canTrickleIceCandidates: boolean | null;
|
|
29
30
|
connectionState: RTCPeerConnectionState;
|
|
30
31
|
currentLocalDescription: RTCSessionDescription | null;
|
|
@@ -56,7 +57,8 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
56
57
|
getConfiguration(): RTCConfiguration;
|
|
57
58
|
getReceivers(): RTCRtpReceiver[];
|
|
58
59
|
getSenders(): RTCRtpSender[];
|
|
59
|
-
getStats(_selector?: unknown, _successCallback?: unknown, _failureCallback?: unknown): Promise<
|
|
60
|
+
getStats(_selector?: unknown, _successCallback?: unknown, _failureCallback?: unknown): Promise<RTCStatsReport>;
|
|
61
|
+
setStats(stats: RTCStatsReport): void;
|
|
60
62
|
getTransceivers(): RTCRtpTransceiver[];
|
|
61
63
|
removeTrack(): void;
|
|
62
64
|
restartIce(): void;
|
|
@@ -68,6 +70,7 @@ export default class MockRtcPeerConnection implements RTCPeerConnection {
|
|
|
68
70
|
}): Promise<void>;
|
|
69
71
|
addEventListener(type: unknown, listener: unknown, _options?: unknown): void;
|
|
70
72
|
removeEventListener(_type: unknown, _listener: unknown, _options?: unknown): void;
|
|
73
|
+
emitEvent(name: string, event?: Event): Promise<void>;
|
|
71
74
|
dispatchEvent(_event: Event): boolean;
|
|
72
75
|
}
|
|
73
76
|
export interface AddedTransceiver {
|
|
@@ -6,10 +6,12 @@ class MockRtcPeerConnection {
|
|
|
6
6
|
this.offer = {
|
|
7
7
|
[(0, test_utils_1.generateId)()]: (0, test_utils_1.generateId)(),
|
|
8
8
|
};
|
|
9
|
+
this.eventListeners = [];
|
|
9
10
|
this.addedTransceivers = [];
|
|
10
11
|
this.tranceiverAndDataChannelCalls = [];
|
|
12
|
+
this.stats = [];
|
|
11
13
|
this.canTrickleIceCandidates = null;
|
|
12
|
-
this.connectionState =
|
|
14
|
+
this.connectionState = 'connected';
|
|
13
15
|
this.currentLocalDescription = null;
|
|
14
16
|
this.currentRemoteDescription = null;
|
|
15
17
|
this.iceConnectionState = {};
|
|
@@ -78,15 +80,6 @@ class MockRtcPeerConnection {
|
|
|
78
80
|
static onCreateOffer(cb) {
|
|
79
81
|
this.onCreateOfferHandler = cb;
|
|
80
82
|
}
|
|
81
|
-
emitTrackAdded(event) {
|
|
82
|
-
const lastListener = this.lastAddedEventListener;
|
|
83
|
-
if (lastListener?.eventName === 'track') {
|
|
84
|
-
lastListener.listener(event ?? {});
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
test_utils_1.assert.fail('Did not call connection.addEventListener with track listener');
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
83
|
async addIceCandidate(_candidate, _successCallback, _failureCallback) {
|
|
91
84
|
throw new Error('Method not implemented.');
|
|
92
85
|
}
|
|
@@ -129,9 +122,11 @@ class MockRtcPeerConnection {
|
|
|
129
122
|
getSenders() {
|
|
130
123
|
return [];
|
|
131
124
|
}
|
|
132
|
-
//@ts-ignore
|
|
133
125
|
async getStats(_selector, _successCallback, _failureCallback) {
|
|
134
|
-
|
|
126
|
+
return this.stats;
|
|
127
|
+
}
|
|
128
|
+
setStats(stats) {
|
|
129
|
+
this.stats = stats;
|
|
135
130
|
}
|
|
136
131
|
getTransceivers() {
|
|
137
132
|
return [];
|
|
@@ -150,10 +145,21 @@ class MockRtcPeerConnection {
|
|
|
150
145
|
eventName: type,
|
|
151
146
|
listener,
|
|
152
147
|
};
|
|
148
|
+
this.eventListeners.push({
|
|
149
|
+
type,
|
|
150
|
+
listener,
|
|
151
|
+
});
|
|
153
152
|
}
|
|
154
153
|
removeEventListener(_type, _listener, _options) {
|
|
155
154
|
throw new Error('Method not implemented.');
|
|
156
155
|
}
|
|
156
|
+
async emitEvent(name, event) {
|
|
157
|
+
for (const listener of this.eventListeners) {
|
|
158
|
+
if (listener.type === name) {
|
|
159
|
+
await listener.listener(event);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
157
163
|
dispatchEvent(_event) {
|
|
158
164
|
return true;
|
|
159
165
|
}
|
|
@@ -20,8 +20,18 @@ export interface WebRtcVcPluginCreateOfferOptions {
|
|
|
20
20
|
offerToReceiveVideo?: boolean;
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
export
|
|
24
|
-
|
|
23
|
+
export interface WebRtcStateEventMap {
|
|
24
|
+
createdOffer: RTCTrackEvent;
|
|
25
|
+
suppliedAnswer: RTCTrackEvent;
|
|
26
|
+
trackAdded: RTCTrackEvent;
|
|
27
|
+
error: WebRtcErrorEvent;
|
|
28
|
+
}
|
|
29
|
+
export type WebRtcConnectionState = keyof WebRtcStateEventMap;
|
|
30
|
+
export type WebRtcStateChangeEvent = RTCTrackEvent | WebRtcErrorEvent;
|
|
31
|
+
export type WebRtcStateChangeHandler = (state: WebRtcConnectionState, event?: WebRtcStateChangeEvent) => void | Promise<void>;
|
|
32
|
+
export interface WebRtcErrorEvent {
|
|
33
|
+
stats: RTCStatsReport;
|
|
34
|
+
}
|
|
25
35
|
export interface WebRtcConnection {
|
|
26
36
|
offStateChange(listener: WebRtcStateChangeHandler): void;
|
|
27
37
|
createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
|
|
@@ -38,8 +38,12 @@ class WebRtcConnectionImpl {
|
|
|
38
38
|
iceServers: [],
|
|
39
39
|
});
|
|
40
40
|
this.rtcPeerConnection = connection;
|
|
41
|
-
connection.addEventListener('connectionstatechange', () => {
|
|
42
|
-
this.log.info(
|
|
41
|
+
connection.addEventListener('connectionstatechange', async () => {
|
|
42
|
+
this.log.info(`RTCPeerConnection state changed to ${connection.connectionState}`);
|
|
43
|
+
if (connection.connectionState === 'failed') {
|
|
44
|
+
const stats = await connection.getStats();
|
|
45
|
+
await this.emitStateChange('error', { stats });
|
|
46
|
+
}
|
|
43
47
|
});
|
|
44
48
|
const { offerToReceiveAudio, offerToReceiveVideo } = offerOptions;
|
|
45
49
|
if (offerToReceiveAudio) {
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"description": "All the power of Heartwood in one, convenient package.",
|
|
16
|
-
"version": "119.
|
|
16
|
+
"version": "119.4.1",
|
|
17
17
|
"skill": {
|
|
18
18
|
"namespace": "HeartwoodViewControllers",
|
|
19
19
|
"commandOverrides": {
|
|
@@ -78,16 +78,16 @@
|
|
|
78
78
|
"@babel/preset-env": "^7.27.2",
|
|
79
79
|
"@babel/preset-typescript": "^7.27.1",
|
|
80
80
|
"@babel/runtime": "^7.27.1",
|
|
81
|
-
"@sprucelabs/calendar-utils": "^42.0.
|
|
82
|
-
"@sprucelabs/error": "^6.0.
|
|
81
|
+
"@sprucelabs/calendar-utils": "^42.0.689",
|
|
82
|
+
"@sprucelabs/error": "^6.0.601",
|
|
83
83
|
"@sprucelabs/globby": "^2.0.502",
|
|
84
|
-
"@sprucelabs/mercury-core-events": "^26.0.
|
|
85
|
-
"@sprucelabs/mercury-types": "^47.2.
|
|
86
|
-
"@sprucelabs/schema": "^31.0.
|
|
87
|
-
"@sprucelabs/spruce-core-schemas": "^40.1.
|
|
88
|
-
"@sprucelabs/spruce-event-utils": "^40.2.
|
|
89
|
-
"@sprucelabs/spruce-skill-utils": "^31.2.
|
|
90
|
-
"@sprucelabs/test-utils": "^5.5.
|
|
84
|
+
"@sprucelabs/mercury-core-events": "^26.0.70",
|
|
85
|
+
"@sprucelabs/mercury-types": "^47.2.79",
|
|
86
|
+
"@sprucelabs/schema": "^31.0.90",
|
|
87
|
+
"@sprucelabs/spruce-core-schemas": "^40.1.682",
|
|
88
|
+
"@sprucelabs/spruce-event-utils": "^40.2.88",
|
|
89
|
+
"@sprucelabs/spruce-skill-utils": "^31.2.97",
|
|
90
|
+
"@sprucelabs/test-utils": "^5.5.48",
|
|
91
91
|
"@swc/core": "1.2.103",
|
|
92
92
|
"babel-loader": "^10.0.0",
|
|
93
93
|
"babel-plugin-module-resolver": "^5.0.2",
|
|
@@ -100,24 +100,24 @@
|
|
|
100
100
|
"webpack": "5.70.0"
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
|
-
"@sprucelabs/esm-postbuild": "^6.0.
|
|
104
|
-
"@sprucelabs/jest-json-reporter": "^8.0.
|
|
105
|
-
"@sprucelabs/mercury-client": "^42.0.
|
|
106
|
-
"@sprucelabs/mercury-event-emitter": "^42.0.
|
|
107
|
-
"@sprucelabs/resolve-path-aliases": "^2.0.
|
|
103
|
+
"@sprucelabs/esm-postbuild": "^6.0.564",
|
|
104
|
+
"@sprucelabs/jest-json-reporter": "^8.0.602",
|
|
105
|
+
"@sprucelabs/mercury-client": "^42.0.789",
|
|
106
|
+
"@sprucelabs/mercury-event-emitter": "^42.0.789",
|
|
107
|
+
"@sprucelabs/resolve-path-aliases": "^2.0.542",
|
|
108
108
|
"@sprucelabs/semantic-release": "^5.0.2",
|
|
109
|
-
"@sprucelabs/test": "^9.0.
|
|
110
|
-
"@types/node": "^22.15.
|
|
109
|
+
"@sprucelabs/test": "^9.0.81",
|
|
110
|
+
"@types/node": "^22.15.21",
|
|
111
111
|
"@types/terser-webpack-plugin": "^5.2.0",
|
|
112
112
|
"chokidar-cli": "^3.0.0",
|
|
113
|
-
"eslint": "^9.
|
|
113
|
+
"eslint": "^9.27.0",
|
|
114
114
|
"eslint-config-spruce": "^11.2.26",
|
|
115
115
|
"jest": "^29.7.0",
|
|
116
116
|
"jest-circus": "^29.7.0",
|
|
117
117
|
"jsdom": "^26.1.0",
|
|
118
118
|
"prettier": "^3.5.3",
|
|
119
119
|
"ts-node": "^10.9.2",
|
|
120
|
-
"tsc-watch": "^6.
|
|
120
|
+
"tsc-watch": "^6.3.1",
|
|
121
121
|
"tsconfig-paths": "^4.2.0",
|
|
122
122
|
"typescript": "^5.8.3",
|
|
123
123
|
"yarn-upgrade-all": "^0.7.5"
|