@wazo/sdk 1.0.0-alpha.17 → 1.0.0-alpha.18
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/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/__voice__/call.test.js +40 -4
- package/esm/state-machine/call-state-machine.js +33 -18
- package/esm/types/state-machine/call-state-machine.d.ts +12 -1
- package/esm/types/state-machine/call-state-machine.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/voice/call.js +24 -6
- package/lib/__tests__/__voice__/call.test.js +39 -3
- package/lib/state-machine/call-state-machine.js +34 -19
- package/lib/types/state-machine/call-state-machine.d.ts +12 -1
- package/lib/types/state-machine/call-state-machine.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/voice/call.js +24 -6
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +46 -4
- package/src/state-machine/call-state-machine.ts +37 -18
- package/src/voice/call.ts +28 -8
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Inviter, UserAgent } from 'sip.js';
|
|
3
3
|
import softphone from '../../voice/softphone';
|
|
4
4
|
import Call from '../../voice/call';
|
|
5
|
-
import { Actions, EstablishedStates, States } from '../../state-machine/call-state-machine';
|
|
5
|
+
import { Actions, EstablishedStates, EstablishedSubStates, States } from '../../state-machine/call-state-machine';
|
|
6
6
|
import { Actions as SoftphoneActions } from '../../state-machine/softphone-state-machine';
|
|
7
7
|
import ApiCall from '../../domain/Call';
|
|
8
8
|
import InvalidStateTransition from '../../domain/InvalidStateTransition';
|
|
@@ -27,6 +27,9 @@ jest.mock('../..', () => ({
|
|
|
27
27
|
}));
|
|
28
28
|
jest.mock('../../web-rtc-client', () => jest.fn().mockImplementation(() => ({
|
|
29
29
|
answer: jest.fn(() => Promise.resolve()),
|
|
30
|
+
mute: jest.fn(() => Promise.resolve()),
|
|
31
|
+
hold: jest.fn(() => Promise.resolve()),
|
|
32
|
+
unhold: jest.fn(() => Promise.resolve()),
|
|
30
33
|
hangup: jest.fn(() => Promise.resolve()),
|
|
31
34
|
register: jest.fn(() => Promise.resolve()),
|
|
32
35
|
onCallEnded: jest.fn(() => Promise.resolve()),
|
|
@@ -66,9 +69,16 @@ describe('Call', () => {
|
|
|
66
69
|
expect(call.id).toBe(apiCall.sipCallId);
|
|
67
70
|
expect(call.apiId).toBe(apiCall.id);
|
|
68
71
|
expect(call.number).toBe(apiCall.calleeNumber);
|
|
69
|
-
expect(call.answerTime).toStrictEqual(
|
|
72
|
+
expect(call.answerTime).toStrictEqual(undefined);
|
|
73
|
+
expect(call.creationTime).toStrictEqual(apiCall.startingTime);
|
|
70
74
|
expect(call.isMuted()).toBeTruthy();
|
|
71
|
-
expect(call.state).toStrictEqual({
|
|
75
|
+
expect(call.state).toStrictEqual({
|
|
76
|
+
[States.ESTABLISHED]: {
|
|
77
|
+
[EstablishedStates.ONGOING]: {},
|
|
78
|
+
[EstablishedSubStates.MUTE]: EstablishedStates.MUTED,
|
|
79
|
+
[EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
72
82
|
expect(call.isEstablished()).toBeTruthy();
|
|
73
83
|
});
|
|
74
84
|
});
|
|
@@ -118,10 +128,36 @@ describe('Call', () => {
|
|
|
118
128
|
// @ts-ignore: private method
|
|
119
129
|
call._sendAction(Actions.MAKE_CALL);
|
|
120
130
|
call.on('remotelyAccepted', () => {
|
|
121
|
-
expect(call.state).toStrictEqual({
|
|
131
|
+
expect(call.state).toStrictEqual({
|
|
132
|
+
[States.ESTABLISHED]: {
|
|
133
|
+
[EstablishedStates.ONGOING]: {},
|
|
134
|
+
[EstablishedSubStates.MUTE]: EstablishedStates.UN_MUTED,
|
|
135
|
+
[EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
122
138
|
done();
|
|
123
139
|
});
|
|
124
140
|
call.onAccepted();
|
|
125
141
|
});
|
|
126
142
|
});
|
|
143
|
+
describe('Multiple sub state', () => {
|
|
144
|
+
it('Should mute and hold a call', () => {
|
|
145
|
+
const call = new Call(sipCall, softphone);
|
|
146
|
+
// @ts-ignore: private method
|
|
147
|
+
call._sendAction(Actions.MAKE_CALL);
|
|
148
|
+
expect(call.isMuted()).toBeFalsy();
|
|
149
|
+
expect(call.isHeld()).toBeFalsy();
|
|
150
|
+
// @ts-ignore: private method
|
|
151
|
+
call._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
152
|
+
call.mute();
|
|
153
|
+
expect(call.isMuted()).toBeTruthy();
|
|
154
|
+
expect(call.isHeld()).toBeFalsy();
|
|
155
|
+
call.hold();
|
|
156
|
+
expect(call.isMuted()).toBeTruthy();
|
|
157
|
+
expect(call.isHeld()).toBeTruthy();
|
|
158
|
+
call.resume();
|
|
159
|
+
expect(call.isMuted()).toBeTruthy();
|
|
160
|
+
expect(call.isHeld()).toBeFalsy();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
127
163
|
});
|
|
@@ -12,6 +12,12 @@ export const EstablishedStates = {
|
|
|
12
12
|
ONGOING: 'ongoing',
|
|
13
13
|
HELD: 'held',
|
|
14
14
|
MUTED: 'muted',
|
|
15
|
+
UN_MUTED: 'unMuted',
|
|
16
|
+
UN_HELD: 'unHeld',
|
|
17
|
+
};
|
|
18
|
+
export const EstablishedSubStates = {
|
|
19
|
+
MUTE: 'muteState',
|
|
20
|
+
HOLD: 'holdState',
|
|
15
21
|
};
|
|
16
22
|
export const Actions = {
|
|
17
23
|
INCOMING_CALL: 'incomingCall',
|
|
@@ -74,35 +80,44 @@ const callMachine = setup({
|
|
|
74
80
|
},
|
|
75
81
|
[States.ESTABLISHED]: {
|
|
76
82
|
initial: EstablishedStates.ONGOING,
|
|
83
|
+
type: 'parallel',
|
|
77
84
|
on: {
|
|
78
85
|
[Actions.HANGUP]: {
|
|
79
86
|
guard: 'isRegistered',
|
|
80
87
|
target: States.TERMINATED,
|
|
81
88
|
},
|
|
82
|
-
[EstablishedActions.HOLD]: {
|
|
83
|
-
guard: 'isRegistered',
|
|
84
|
-
target: `.${EstablishedStates.HELD}`,
|
|
85
|
-
},
|
|
86
|
-
[EstablishedActions.MUTE]: {
|
|
87
|
-
guard: 'isRegistered',
|
|
88
|
-
target: `.${EstablishedStates.MUTED}`,
|
|
89
|
-
},
|
|
90
89
|
},
|
|
91
90
|
states: {
|
|
92
91
|
[EstablishedStates.ONGOING]: {},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
// Mute / Unmute
|
|
93
|
+
[EstablishedSubStates.MUTE]: {
|
|
94
|
+
initial: EstablishedStates.UN_MUTED,
|
|
95
|
+
states: {
|
|
96
|
+
[EstablishedStates.MUTED]: {
|
|
97
|
+
on: {
|
|
98
|
+
unMute: EstablishedStates.UN_MUTED,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
[EstablishedStates.UN_MUTED]: {
|
|
102
|
+
on: {
|
|
103
|
+
mute: EstablishedStates.MUTED,
|
|
104
|
+
},
|
|
98
105
|
},
|
|
99
106
|
},
|
|
100
107
|
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
// Hold / Resume
|
|
109
|
+
[EstablishedSubStates.HOLD]: {
|
|
110
|
+
initial: EstablishedStates.UN_HELD,
|
|
111
|
+
states: {
|
|
112
|
+
[EstablishedStates.HELD]: {
|
|
113
|
+
on: {
|
|
114
|
+
[EstablishedActions.RESUME]: EstablishedStates.UN_HELD,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
[EstablishedStates.UN_HELD]: {
|
|
118
|
+
on: {
|
|
119
|
+
[EstablishedActions.HOLD]: EstablishedStates.HELD,
|
|
120
|
+
},
|
|
106
121
|
},
|
|
107
122
|
},
|
|
108
123
|
},
|
|
@@ -10,9 +10,16 @@ export declare const EstablishedStates: {
|
|
|
10
10
|
readonly ONGOING: "ongoing";
|
|
11
11
|
readonly HELD: "held";
|
|
12
12
|
readonly MUTED: "muted";
|
|
13
|
+
readonly UN_MUTED: "unMuted";
|
|
14
|
+
readonly UN_HELD: "unHeld";
|
|
15
|
+
};
|
|
16
|
+
export declare const EstablishedSubStates: {
|
|
17
|
+
readonly MUTE: "muteState";
|
|
18
|
+
readonly HOLD: "holdState";
|
|
13
19
|
};
|
|
14
20
|
export type StateTypes = typeof States[keyof typeof States];
|
|
15
21
|
export type EstablishedStateTypes = typeof EstablishedStates[keyof typeof EstablishedStates];
|
|
22
|
+
export type EstablishedSubStateTypes = typeof EstablishedSubStates[keyof typeof EstablishedSubStates];
|
|
16
23
|
export declare const Actions: {
|
|
17
24
|
readonly INCOMING_CALL: "incomingCall";
|
|
18
25
|
readonly MAKE_CALL: "makeCall";
|
|
@@ -33,7 +40,11 @@ declare const callMachine: import("xstate").StateMachine<import("xstate").Machin
|
|
|
33
40
|
type: "isRegistered";
|
|
34
41
|
params: unknown;
|
|
35
42
|
}, never, "ringing" | "progress" | "idle" | "terminated" | {
|
|
36
|
-
established?:
|
|
43
|
+
established?: Required<{
|
|
44
|
+
ongoing?: {} | undefined;
|
|
45
|
+
muteState?: "muted" | "unMuted" | undefined;
|
|
46
|
+
holdState?: "held" | "unHeld" | undefined;
|
|
47
|
+
}> | undefined;
|
|
37
48
|
}, string, import("xstate").NonReducibleUnknown, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, import("xstate").ResolveTypegenMeta<import("xstate").TypegenDisabled, import("xstate").AnyEventObject, never, never, {
|
|
38
49
|
type: "isRegistered";
|
|
39
50
|
params: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-state-machine.d.ts","sourceRoot":"","sources":["../../../src/state-machine/call-state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKlD,eAAO,MAAM,MAAM;;;;;;CAMT,CAAC;AAEX,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"call-state-machine.d.ts","sourceRoot":"","sources":["../../../src/state-machine/call-state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKlD,eAAO,MAAM,MAAM;;;;;;CAMT,CAAC;AAEX,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAAG,OAAO,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAC7F,MAAM,MAAM,wBAAwB,GAAG,OAAO,oBAAoB,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAEtG,eAAO,MAAM,OAAO;;;;;;;CAOV,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,OAAO,OAAO,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG,OAAO,kBAAkB,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAEhG,QAAA,MAAM,WAAW;;;;;;;;;;;;gDA8Ff,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAE5D,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../src/voice/call.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mDAAmD,CAAC;AAEhG,OAAyB,EAAsF,KAAK,UAAU,EAAqB,KAAK,qBAAqB,EAAE,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../src/voice/call.ts"],"names":[],"mappings":"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"}
|
package/esm/voice/call.js
CHANGED
|
@@ -88,10 +88,22 @@ class Call extends EventEmitter {
|
|
|
88
88
|
// Update call state
|
|
89
89
|
const snapshot = call.callActor.getSnapshot();
|
|
90
90
|
if (apiCall.isUp()) {
|
|
91
|
-
snapshot.value = {
|
|
91
|
+
snapshot.value = {
|
|
92
|
+
[States.ESTABLISHED]: {
|
|
93
|
+
[EstablishedStates.ONGOING]: {},
|
|
94
|
+
muteState: EstablishedStates.UN_MUTED,
|
|
95
|
+
holdState: EstablishedStates.UN_HELD,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
92
98
|
}
|
|
93
99
|
if (apiCall.muted) {
|
|
94
|
-
snapshot.value = {
|
|
100
|
+
snapshot.value = {
|
|
101
|
+
[States.ESTABLISHED]: {
|
|
102
|
+
[EstablishedStates.ONGOING]: {},
|
|
103
|
+
muteState: EstablishedStates.MUTED,
|
|
104
|
+
holdState: EstablishedStates.UN_HELD,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
95
107
|
}
|
|
96
108
|
if (apiCall.isRinging()) {
|
|
97
109
|
snapshot.value = States.RINGING;
|
|
@@ -246,13 +258,13 @@ class Call extends EventEmitter {
|
|
|
246
258
|
this.emit(EVENT_CAMERA_DISABLED);
|
|
247
259
|
}
|
|
248
260
|
isMuted() {
|
|
249
|
-
return this._hasEstablishedState(EstablishedStates.MUTED);
|
|
261
|
+
return this._hasEstablishedState('muteState', EstablishedStates.MUTED);
|
|
250
262
|
}
|
|
251
263
|
isCameraMuted() {
|
|
252
264
|
return isVideoMuted(this.sipCall);
|
|
253
265
|
}
|
|
254
266
|
isHeld() {
|
|
255
|
-
return this._hasEstablishedState(EstablishedStates.HELD);
|
|
267
|
+
return this._hasEstablishedState('holdState', EstablishedStates.HELD);
|
|
256
268
|
}
|
|
257
269
|
isEstablishing() {
|
|
258
270
|
return this.sipCall.state === SessionState.Establishing;
|
|
@@ -482,9 +494,15 @@ class Call extends EventEmitter {
|
|
|
482
494
|
get state() {
|
|
483
495
|
return getState(this.callActor);
|
|
484
496
|
}
|
|
485
|
-
_hasEstablishedState(establishedState) {
|
|
497
|
+
_hasEstablishedState(subState, establishedState) {
|
|
486
498
|
const state = this.state;
|
|
487
|
-
|
|
499
|
+
if (typeof state !== 'object') {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
if (!(States.ESTABLISHED in state)) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
return state[States.ESTABLISHED][subState] === establishedState;
|
|
488
506
|
}
|
|
489
507
|
_bindEvents() {
|
|
490
508
|
if (this.sipCall instanceof Invitation) {
|
|
@@ -41,6 +41,9 @@ jest.mock('../..', () => ({
|
|
|
41
41
|
}));
|
|
42
42
|
jest.mock('../../web-rtc-client', () => jest.fn().mockImplementation(() => ({
|
|
43
43
|
answer: jest.fn(() => Promise.resolve()),
|
|
44
|
+
mute: jest.fn(() => Promise.resolve()),
|
|
45
|
+
hold: jest.fn(() => Promise.resolve()),
|
|
46
|
+
unhold: jest.fn(() => Promise.resolve()),
|
|
44
47
|
hangup: jest.fn(() => Promise.resolve()),
|
|
45
48
|
register: jest.fn(() => Promise.resolve()),
|
|
46
49
|
onCallEnded: jest.fn(() => Promise.resolve()),
|
|
@@ -80,9 +83,16 @@ describe('Call', () => {
|
|
|
80
83
|
expect(call.id).toBe(apiCall.sipCallId);
|
|
81
84
|
expect(call.apiId).toBe(apiCall.id);
|
|
82
85
|
expect(call.number).toBe(apiCall.calleeNumber);
|
|
83
|
-
expect(call.answerTime).toStrictEqual(
|
|
86
|
+
expect(call.answerTime).toStrictEqual(undefined);
|
|
87
|
+
expect(call.creationTime).toStrictEqual(apiCall.startingTime);
|
|
84
88
|
expect(call.isMuted()).toBeTruthy();
|
|
85
|
-
expect(call.state).toStrictEqual({
|
|
89
|
+
expect(call.state).toStrictEqual({
|
|
90
|
+
[call_state_machine_1.States.ESTABLISHED]: {
|
|
91
|
+
[call_state_machine_1.EstablishedStates.ONGOING]: {},
|
|
92
|
+
[call_state_machine_1.EstablishedSubStates.MUTE]: call_state_machine_1.EstablishedStates.MUTED,
|
|
93
|
+
[call_state_machine_1.EstablishedSubStates.HOLD]: call_state_machine_1.EstablishedStates.UN_HELD,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
86
96
|
expect(call.isEstablished()).toBeTruthy();
|
|
87
97
|
}));
|
|
88
98
|
});
|
|
@@ -132,10 +142,36 @@ describe('Call', () => {
|
|
|
132
142
|
// @ts-ignore: private method
|
|
133
143
|
call._sendAction(call_state_machine_1.Actions.MAKE_CALL);
|
|
134
144
|
call.on('remotelyAccepted', () => {
|
|
135
|
-
expect(call.state).toStrictEqual({
|
|
145
|
+
expect(call.state).toStrictEqual({
|
|
146
|
+
[call_state_machine_1.States.ESTABLISHED]: {
|
|
147
|
+
[call_state_machine_1.EstablishedStates.ONGOING]: {},
|
|
148
|
+
[call_state_machine_1.EstablishedSubStates.MUTE]: call_state_machine_1.EstablishedStates.UN_MUTED,
|
|
149
|
+
[call_state_machine_1.EstablishedSubStates.HOLD]: call_state_machine_1.EstablishedStates.UN_HELD,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
136
152
|
done();
|
|
137
153
|
});
|
|
138
154
|
call.onAccepted();
|
|
139
155
|
});
|
|
140
156
|
});
|
|
157
|
+
describe('Multiple sub state', () => {
|
|
158
|
+
it('Should mute and hold a call', () => {
|
|
159
|
+
const call = new call_1.default(sipCall, softphone_1.default);
|
|
160
|
+
// @ts-ignore: private method
|
|
161
|
+
call._sendAction(call_state_machine_1.Actions.MAKE_CALL);
|
|
162
|
+
expect(call.isMuted()).toBeFalsy();
|
|
163
|
+
expect(call.isHeld()).toBeFalsy();
|
|
164
|
+
// @ts-ignore: private method
|
|
165
|
+
call._sendAction(call_state_machine_1.Actions.REMOTLY_ACCEPTED);
|
|
166
|
+
call.mute();
|
|
167
|
+
expect(call.isMuted()).toBeTruthy();
|
|
168
|
+
expect(call.isHeld()).toBeFalsy();
|
|
169
|
+
call.hold();
|
|
170
|
+
expect(call.isMuted()).toBeTruthy();
|
|
171
|
+
expect(call.isHeld()).toBeTruthy();
|
|
172
|
+
call.resume();
|
|
173
|
+
expect(call.isMuted()).toBeTruthy();
|
|
174
|
+
expect(call.isHeld()).toBeFalsy();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
141
177
|
});
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EstablishedActions = exports.Actions = exports.EstablishedStates = exports.States = void 0;
|
|
6
|
+
exports.EstablishedActions = exports.Actions = exports.EstablishedSubStates = exports.EstablishedStates = exports.States = void 0;
|
|
7
7
|
const xstate_1 = require("xstate");
|
|
8
8
|
const softphone_1 = __importDefault(require("../voice/softphone"));
|
|
9
9
|
const softphone_state_machine_1 = require("./softphone-state-machine");
|
|
@@ -18,6 +18,12 @@ exports.EstablishedStates = {
|
|
|
18
18
|
ONGOING: 'ongoing',
|
|
19
19
|
HELD: 'held',
|
|
20
20
|
MUTED: 'muted',
|
|
21
|
+
UN_MUTED: 'unMuted',
|
|
22
|
+
UN_HELD: 'unHeld',
|
|
23
|
+
};
|
|
24
|
+
exports.EstablishedSubStates = {
|
|
25
|
+
MUTE: 'muteState',
|
|
26
|
+
HOLD: 'holdState',
|
|
21
27
|
};
|
|
22
28
|
exports.Actions = {
|
|
23
29
|
INCOMING_CALL: 'incomingCall',
|
|
@@ -80,35 +86,44 @@ const callMachine = (0, xstate_1.setup)({
|
|
|
80
86
|
},
|
|
81
87
|
[exports.States.ESTABLISHED]: {
|
|
82
88
|
initial: exports.EstablishedStates.ONGOING,
|
|
89
|
+
type: 'parallel',
|
|
83
90
|
on: {
|
|
84
91
|
[exports.Actions.HANGUP]: {
|
|
85
92
|
guard: 'isRegistered',
|
|
86
93
|
target: exports.States.TERMINATED,
|
|
87
94
|
},
|
|
88
|
-
[exports.EstablishedActions.HOLD]: {
|
|
89
|
-
guard: 'isRegistered',
|
|
90
|
-
target: `.${exports.EstablishedStates.HELD}`,
|
|
91
|
-
},
|
|
92
|
-
[exports.EstablishedActions.MUTE]: {
|
|
93
|
-
guard: 'isRegistered',
|
|
94
|
-
target: `.${exports.EstablishedStates.MUTED}`,
|
|
95
|
-
},
|
|
96
95
|
},
|
|
97
96
|
states: {
|
|
98
97
|
[exports.EstablishedStates.ONGOING]: {},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
// Mute / Unmute
|
|
99
|
+
[exports.EstablishedSubStates.MUTE]: {
|
|
100
|
+
initial: exports.EstablishedStates.UN_MUTED,
|
|
101
|
+
states: {
|
|
102
|
+
[exports.EstablishedStates.MUTED]: {
|
|
103
|
+
on: {
|
|
104
|
+
unMute: exports.EstablishedStates.UN_MUTED,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
[exports.EstablishedStates.UN_MUTED]: {
|
|
108
|
+
on: {
|
|
109
|
+
mute: exports.EstablishedStates.MUTED,
|
|
110
|
+
},
|
|
104
111
|
},
|
|
105
112
|
},
|
|
106
113
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
// Hold / Resume
|
|
115
|
+
[exports.EstablishedSubStates.HOLD]: {
|
|
116
|
+
initial: exports.EstablishedStates.UN_HELD,
|
|
117
|
+
states: {
|
|
118
|
+
[exports.EstablishedStates.HELD]: {
|
|
119
|
+
on: {
|
|
120
|
+
[exports.EstablishedActions.RESUME]: exports.EstablishedStates.UN_HELD,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
[exports.EstablishedStates.UN_HELD]: {
|
|
124
|
+
on: {
|
|
125
|
+
[exports.EstablishedActions.HOLD]: exports.EstablishedStates.HELD,
|
|
126
|
+
},
|
|
112
127
|
},
|
|
113
128
|
},
|
|
114
129
|
},
|
|
@@ -10,9 +10,16 @@ export declare const EstablishedStates: {
|
|
|
10
10
|
readonly ONGOING: "ongoing";
|
|
11
11
|
readonly HELD: "held";
|
|
12
12
|
readonly MUTED: "muted";
|
|
13
|
+
readonly UN_MUTED: "unMuted";
|
|
14
|
+
readonly UN_HELD: "unHeld";
|
|
15
|
+
};
|
|
16
|
+
export declare const EstablishedSubStates: {
|
|
17
|
+
readonly MUTE: "muteState";
|
|
18
|
+
readonly HOLD: "holdState";
|
|
13
19
|
};
|
|
14
20
|
export type StateTypes = typeof States[keyof typeof States];
|
|
15
21
|
export type EstablishedStateTypes = typeof EstablishedStates[keyof typeof EstablishedStates];
|
|
22
|
+
export type EstablishedSubStateTypes = typeof EstablishedSubStates[keyof typeof EstablishedSubStates];
|
|
16
23
|
export declare const Actions: {
|
|
17
24
|
readonly INCOMING_CALL: "incomingCall";
|
|
18
25
|
readonly MAKE_CALL: "makeCall";
|
|
@@ -33,7 +40,11 @@ declare const callMachine: import("xstate").StateMachine<import("xstate").Machin
|
|
|
33
40
|
type: "isRegistered";
|
|
34
41
|
params: unknown;
|
|
35
42
|
}, never, "ringing" | "progress" | "idle" | "terminated" | {
|
|
36
|
-
established?:
|
|
43
|
+
established?: Required<{
|
|
44
|
+
ongoing?: {} | undefined;
|
|
45
|
+
muteState?: "muted" | "unMuted" | undefined;
|
|
46
|
+
holdState?: "held" | "unHeld" | undefined;
|
|
47
|
+
}> | undefined;
|
|
37
48
|
}, string, import("xstate").NonReducibleUnknown, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, import("xstate").ResolveTypegenMeta<import("xstate").TypegenDisabled, import("xstate").AnyEventObject, never, never, {
|
|
38
49
|
type: "isRegistered";
|
|
39
50
|
params: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-state-machine.d.ts","sourceRoot":"","sources":["../../../src/state-machine/call-state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKlD,eAAO,MAAM,MAAM;;;;;;CAMT,CAAC;AAEX,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"call-state-machine.d.ts","sourceRoot":"","sources":["../../../src/state-machine/call-state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKlD,eAAO,MAAM,MAAM;;;;;;CAMT,CAAC;AAEX,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAAG,OAAO,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAC7F,MAAM,MAAM,wBAAwB,GAAG,OAAO,oBAAoB,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAEtG,eAAO,MAAM,OAAO;;;;;;;CAOV,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,OAAO,OAAO,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;AAE/D,MAAM,MAAM,sBAAsB,GAAG,OAAO,kBAAkB,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAEhG,QAAA,MAAM,WAAW;;;;;;;;;;;;gDA8Ff,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAE5D,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../src/voice/call.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mDAAmD,CAAC;AAEhG,OAAyB,EAAsF,KAAK,UAAU,EAAqB,KAAK,qBAAqB,EAAE,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../src/voice/call.ts"],"names":[],"mappings":"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"}
|
package/lib/voice/call.js
CHANGED
|
@@ -111,10 +111,22 @@ class Call extends events_1.EventEmitter {
|
|
|
111
111
|
// Update call state
|
|
112
112
|
const snapshot = call.callActor.getSnapshot();
|
|
113
113
|
if (apiCall.isUp()) {
|
|
114
|
-
snapshot.value = {
|
|
114
|
+
snapshot.value = {
|
|
115
|
+
[call_state_machine_1.States.ESTABLISHED]: {
|
|
116
|
+
[call_state_machine_1.EstablishedStates.ONGOING]: {},
|
|
117
|
+
muteState: call_state_machine_1.EstablishedStates.UN_MUTED,
|
|
118
|
+
holdState: call_state_machine_1.EstablishedStates.UN_HELD,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
115
121
|
}
|
|
116
122
|
if (apiCall.muted) {
|
|
117
|
-
snapshot.value = {
|
|
123
|
+
snapshot.value = {
|
|
124
|
+
[call_state_machine_1.States.ESTABLISHED]: {
|
|
125
|
+
[call_state_machine_1.EstablishedStates.ONGOING]: {},
|
|
126
|
+
muteState: call_state_machine_1.EstablishedStates.MUTED,
|
|
127
|
+
holdState: call_state_machine_1.EstablishedStates.UN_HELD,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
118
130
|
}
|
|
119
131
|
if (apiCall.isRinging()) {
|
|
120
132
|
snapshot.value = call_state_machine_1.States.RINGING;
|
|
@@ -284,13 +296,13 @@ class Call extends events_1.EventEmitter {
|
|
|
284
296
|
this.emit(exports.EVENT_CAMERA_DISABLED);
|
|
285
297
|
}
|
|
286
298
|
isMuted() {
|
|
287
|
-
return this._hasEstablishedState(call_state_machine_1.EstablishedStates.MUTED);
|
|
299
|
+
return this._hasEstablishedState('muteState', call_state_machine_1.EstablishedStates.MUTED);
|
|
288
300
|
}
|
|
289
301
|
isCameraMuted() {
|
|
290
302
|
return (0, webrtc_1.isVideoMuted)(this.sipCall);
|
|
291
303
|
}
|
|
292
304
|
isHeld() {
|
|
293
|
-
return this._hasEstablishedState(call_state_machine_1.EstablishedStates.HELD);
|
|
305
|
+
return this._hasEstablishedState('holdState', call_state_machine_1.EstablishedStates.HELD);
|
|
294
306
|
}
|
|
295
307
|
isEstablishing() {
|
|
296
308
|
return this.sipCall.state === session_state_1.SessionState.Establishing;
|
|
@@ -531,9 +543,15 @@ class Call extends events_1.EventEmitter {
|
|
|
531
543
|
get state() {
|
|
532
544
|
return (0, utils_1.getState)(this.callActor);
|
|
533
545
|
}
|
|
534
|
-
_hasEstablishedState(establishedState) {
|
|
546
|
+
_hasEstablishedState(subState, establishedState) {
|
|
535
547
|
const state = this.state;
|
|
536
|
-
|
|
548
|
+
if (typeof state !== 'object') {
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
if (!(call_state_machine_1.States.ESTABLISHED in state)) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
return state[call_state_machine_1.States.ESTABLISHED][subState] === establishedState;
|
|
537
555
|
}
|
|
538
556
|
_bindEvents() {
|
|
539
557
|
var _a, _b;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { Inviter, UserAgent, type URI } from 'sip.js';
|
|
|
3
3
|
|
|
4
4
|
import softphone from '../../voice/softphone';
|
|
5
5
|
import Call from '../../voice/call';
|
|
6
|
-
import { Actions, EstablishedStates, States } from '../../state-machine/call-state-machine';
|
|
6
|
+
import { Actions, EstablishedStates, EstablishedSubStates, States } from '../../state-machine/call-state-machine';
|
|
7
7
|
import { Actions as SoftphoneActions } from '../../state-machine/softphone-state-machine';
|
|
8
8
|
import ApiCall from '../../domain/Call';
|
|
9
9
|
|
|
@@ -32,6 +32,9 @@ jest.mock('../..', () => ({
|
|
|
32
32
|
|
|
33
33
|
jest.mock('../../web-rtc-client', () => jest.fn().mockImplementation(() => ({
|
|
34
34
|
answer: jest.fn(() => Promise.resolve()),
|
|
35
|
+
mute: jest.fn(() => Promise.resolve()),
|
|
36
|
+
hold: jest.fn(() => Promise.resolve()),
|
|
37
|
+
unhold: jest.fn(() => Promise.resolve()),
|
|
35
38
|
hangup: jest.fn(() => Promise.resolve()),
|
|
36
39
|
register: jest.fn(() => Promise.resolve()),
|
|
37
40
|
onCallEnded: jest.fn(() => Promise.resolve()),
|
|
@@ -76,9 +79,16 @@ describe('Call', () => {
|
|
|
76
79
|
expect(call.id).toBe(apiCall.sipCallId);
|
|
77
80
|
expect(call.apiId).toBe(apiCall.id);
|
|
78
81
|
expect(call.number).toBe(apiCall.calleeNumber);
|
|
79
|
-
expect(call.answerTime).toStrictEqual(
|
|
82
|
+
expect(call.answerTime).toStrictEqual(undefined);
|
|
83
|
+
expect(call.creationTime).toStrictEqual(apiCall.startingTime);
|
|
80
84
|
expect(call.isMuted()).toBeTruthy();
|
|
81
|
-
expect(call.state).toStrictEqual({
|
|
85
|
+
expect(call.state).toStrictEqual({
|
|
86
|
+
[States.ESTABLISHED]: {
|
|
87
|
+
[EstablishedStates.ONGOING]: {},
|
|
88
|
+
[EstablishedSubStates.MUTE]: EstablishedStates.MUTED,
|
|
89
|
+
[EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
82
92
|
expect(call.isEstablished()).toBeTruthy();
|
|
83
93
|
});
|
|
84
94
|
});
|
|
@@ -141,11 +151,43 @@ describe('Call', () => {
|
|
|
141
151
|
call._sendAction(Actions.MAKE_CALL);
|
|
142
152
|
|
|
143
153
|
call.on('remotelyAccepted', () => {
|
|
144
|
-
expect(call.state).toStrictEqual({
|
|
154
|
+
expect(call.state).toStrictEqual({
|
|
155
|
+
[States.ESTABLISHED]: {
|
|
156
|
+
[EstablishedStates.ONGOING]: {},
|
|
157
|
+
[EstablishedSubStates.MUTE]: EstablishedStates.UN_MUTED,
|
|
158
|
+
[EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
145
161
|
done();
|
|
146
162
|
});
|
|
147
163
|
|
|
148
164
|
call.onAccepted();
|
|
149
165
|
});
|
|
150
166
|
});
|
|
167
|
+
|
|
168
|
+
describe('Multiple sub state', () => {
|
|
169
|
+
it('Should mute and hold a call', () => {
|
|
170
|
+
const call = new Call(sipCall, softphone);
|
|
171
|
+
// @ts-ignore: private method
|
|
172
|
+
call._sendAction(Actions.MAKE_CALL);
|
|
173
|
+
|
|
174
|
+
expect(call.isMuted()).toBeFalsy();
|
|
175
|
+
expect(call.isHeld()).toBeFalsy();
|
|
176
|
+
|
|
177
|
+
// @ts-ignore: private method
|
|
178
|
+
call._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
179
|
+
|
|
180
|
+
call.mute();
|
|
181
|
+
expect(call.isMuted()).toBeTruthy();
|
|
182
|
+
expect(call.isHeld()).toBeFalsy();
|
|
183
|
+
|
|
184
|
+
call.hold();
|
|
185
|
+
expect(call.isMuted()).toBeTruthy();
|
|
186
|
+
expect(call.isHeld()).toBeTruthy();
|
|
187
|
+
|
|
188
|
+
call.resume();
|
|
189
|
+
expect(call.isMuted()).toBeTruthy();
|
|
190
|
+
expect(call.isHeld()).toBeFalsy();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
151
193
|
});
|