@wxcc-desktop/sdk 1.2.6 → 1.2.10
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 +18 -391
- package/dist/index.js +1 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/jsapi/actions-jsapi.d.ts +33 -0
- package/dist/types/jsapi/agent-contact-jsapi.d.ts +430 -0
- package/dist/types/jsapi/agent-state-info-jsapi.d.ts +88 -0
- package/dist/types/jsapi/common/_logger.d.ts +4 -0
- package/dist/types/jsapi/common/_service-checker.d.ts +12 -0
- package/dist/types/jsapi/common/_service-events.d.ts +31 -0
- package/dist/types/jsapi/config-jsapi.d.ts +26 -0
- package/dist/types/jsapi/dialer-jsapi.d.ts +73 -0
- package/dist/types/jsapi/i18n-jsapi.d.ts +23 -0
- package/dist/types/jsapi/logger-jsapi.d.ts +19 -0
- package/dist/types/jsapi/screenpop-jsapi.d.ts +29 -0
- package/dist/types/jsapi/shortcut-key-jsapi.d.ts +67 -0
- package/dist/types/sdk.d.ts +1 -0
- package/package.json +5 -60
- package/.eslintignore +0 -5
- package/.eslintrc.js +0 -22
- package/.prettierignore +0 -5
- package/.prettierrc +0 -5
- package/README_PUBLISH.md +0 -36
- package/jenkins-automation/MergePipeline.groovy +0 -143
- package/jest.config.js +0 -15
- package/sonar-project.properties +0 -17
- package/src/[sandbox]/README.md +0 -55
- package/src/[sandbox]/assets/i18n/de/app.json +0 -6
- package/src/[sandbox]/assets/i18n/en/app.json +0 -6
- package/src/[sandbox]/assets/i18n/widget-using-js-api/de/widget-using-js-api.json +0 -5
- package/src/[sandbox]/assets/i18n/widget-using-js-api/en/widget-using-js-api.json +0 -5
- package/src/[sandbox]/favicon.ico +0 -0
- package/src/[sandbox]/index.html +0 -9
- package/src/[sandbox]/sandbox-config.ts +0 -23
- package/src/[sandbox]/sandbox-mock.ts +0 -218
- package/src/[sandbox]/sandbox.ts +0 -164
- package/src/[sandbox]/widget-using-js-api.ts +0 -658
- package/src/global.d.ts +0 -5
- package/src/index.ts +0 -101
- package/src/jsapi/actions-jsapi.test.ts +0 -155
- package/src/jsapi/actions-jsapi.ts +0 -410
- package/src/jsapi/agent-contact-jsapi.test.ts +0 -217
- package/src/jsapi/agent-contact-jsapi.ts +0 -275
- package/src/jsapi/agent-state-info-jsapi.test.ts +0 -176
- package/src/jsapi/agent-state-info-jsapi.ts +0 -288
- package/src/jsapi/common/_logger.test.ts +0 -16
- package/src/jsapi/common/_logger.ts +0 -9
- package/src/jsapi/common/_service-checker.test.ts +0 -44
- package/src/jsapi/common/_service-checker.ts +0 -28
- package/src/jsapi/common/_service-events.test.ts +0 -122
- package/src/jsapi/common/_service-events.ts +0 -156
- package/src/jsapi/config-jsapi.test.ts +0 -78
- package/src/jsapi/config-jsapi.ts +0 -106
- package/src/jsapi/dialer-jsapi.test.ts +0 -101
- package/src/jsapi/dialer-jsapi.ts +0 -116
- package/src/jsapi/i18n-jsapi.test.ts +0 -62
- package/src/jsapi/i18n-jsapi.ts +0 -77
- package/src/jsapi/logger-jsapi.test.ts +0 -45
- package/src/jsapi/logger-jsapi.ts +0 -62
- package/src/jsapi/screenpop-jsapi.test.ts +0 -80
- package/src/jsapi/screenpop-jsapi.ts +0 -100
- package/src/jsapi/shortcut-key-jsapi.test.ts +0 -88
- package/src/jsapi/shortcut-key-jsapi.ts +0 -112
- package/src/sdk.ts +0 -3
- package/src/tsconfig.json +0 -18
- package/tsconfig.json +0 -13
- package/webpack.config.dev.server.ts +0 -12
- package/webpack.config.ts +0 -134
@@ -1,288 +0,0 @@
|
|
1
|
-
import { AgentxService, Service } from "@wxcc-desktop/sdk-types";
|
2
|
-
import EventEmitter from "event-emitter";
|
3
|
-
import allOff from "event-emitter/all-off";
|
4
|
-
import { logger } from "../sdk";
|
5
|
-
import { createJsApiLogger } from "./common/_logger";
|
6
|
-
import { createServiceChecker } from "./common/_service-checker";
|
7
|
-
|
8
|
-
type LatestInfoData = {
|
9
|
-
agentName?: string;
|
10
|
-
agentProfileID?: string;
|
11
|
-
agentSessionId?: string;
|
12
|
-
teamId?: string;
|
13
|
-
teamName?: string;
|
14
|
-
dn?: string;
|
15
|
-
status?: string;
|
16
|
-
subStatus?: string;
|
17
|
-
idleCodes?: Service.Aqm.Configs.Entity[];
|
18
|
-
wrapupCodes?: Service.Aqm.Configs.Entity[];
|
19
|
-
outDialRegex?: string;
|
20
|
-
isOutboundEnabledForTenant?: boolean;
|
21
|
-
isOutboundEnabledForAgent?: boolean;
|
22
|
-
};
|
23
|
-
|
24
|
-
const INITIAL_INFO_DATA: LatestInfoData = {
|
25
|
-
agentName: undefined,
|
26
|
-
agentProfileID: undefined,
|
27
|
-
agentSessionId: undefined,
|
28
|
-
teamId: undefined,
|
29
|
-
teamName: undefined,
|
30
|
-
dn: undefined,
|
31
|
-
status: undefined,
|
32
|
-
subStatus: undefined,
|
33
|
-
idleCodes: undefined,
|
34
|
-
wrapupCodes: undefined,
|
35
|
-
outDialRegex: undefined,
|
36
|
-
isOutboundEnabledForTenant: undefined,
|
37
|
-
isOutboundEnabledForAgent: undefined
|
38
|
-
};
|
39
|
-
|
40
|
-
type Listeners = {
|
41
|
-
updated: (p: { name: keyof LatestInfoData; value?: string; oldValue?: string }[]) => void;
|
42
|
-
};
|
43
|
-
type Events = keyof Listeners;
|
44
|
-
|
45
|
-
type Config = {
|
46
|
-
logger: ReturnType<typeof createJsApiLogger>;
|
47
|
-
serviceChecker: ReturnType<typeof createServiceChecker>;
|
48
|
-
};
|
49
|
-
|
50
|
-
export class AgentStateInfoJsapi {
|
51
|
-
private readonly emitter = EventEmitter();
|
52
|
-
private readonly logger: Config["logger"];
|
53
|
-
private readonly serviceChecker: Config["serviceChecker"];
|
54
|
-
|
55
|
-
private SERVICE?: AgentxService;
|
56
|
-
|
57
|
-
private checkService() {
|
58
|
-
return this.serviceChecker.check(this.SERVICE);
|
59
|
-
}
|
60
|
-
|
61
|
-
private listeners: Set<() => void> = new Set();
|
62
|
-
|
63
|
-
private emit<T extends Events>(eventName: T, ...args: Parameters<Listeners[T]>) {
|
64
|
-
this.emitter.emit(eventName, ...args);
|
65
|
-
}
|
66
|
-
|
67
|
-
private update(p: LatestInfoData) {
|
68
|
-
const keys = Object.keys(p) as (keyof LatestInfoData)[];
|
69
|
-
|
70
|
-
const updatedPayload = keys.reduce((acc, key) => {
|
71
|
-
const value = p[key];
|
72
|
-
const oldValue = this.latestData[key];
|
73
|
-
|
74
|
-
if (JSON.stringify(value) !== JSON.stringify(oldValue)) {
|
75
|
-
acc.push({
|
76
|
-
name: key,
|
77
|
-
value: value,
|
78
|
-
oldValue: oldValue
|
79
|
-
});
|
80
|
-
}
|
81
|
-
return acc;
|
82
|
-
}, [] as { name: keyof LatestInfoData; value: any; oldValue: any }[]);
|
83
|
-
|
84
|
-
if (updatedPayload.length) {
|
85
|
-
updatedPayload.forEach(p => (this.latestData[p.name] = p.value));
|
86
|
-
this.emit("updated", updatedPayload);
|
87
|
-
}
|
88
|
-
}
|
89
|
-
|
90
|
-
private static getOutdialRegex(dialPlan: Service.Aqm.Configs.DialPlan) {
|
91
|
-
if (dialPlan && dialPlan.dialPlanEntity) {
|
92
|
-
const dpe = dialPlan.dialPlanEntity.find(entity => {
|
93
|
-
return entity.name === "Any Format";
|
94
|
-
});
|
95
|
-
if (dpe) {
|
96
|
-
return dpe.regex;
|
97
|
-
}
|
98
|
-
}
|
99
|
-
return "";
|
100
|
-
}
|
101
|
-
|
102
|
-
constructor(config: Config) {
|
103
|
-
this.logger = config.logger;
|
104
|
-
this.serviceChecker = config.serviceChecker;
|
105
|
-
}
|
106
|
-
|
107
|
-
latestData: LatestInfoData = JSON.parse(JSON.stringify(INITIAL_INFO_DATA));
|
108
|
-
|
109
|
-
//Init with ready SERVICE
|
110
|
-
async init(SERVICE?: AgentxService) {
|
111
|
-
if (SERVICE) {
|
112
|
-
this.SERVICE = SERVICE;
|
113
|
-
}
|
114
|
-
|
115
|
-
if (!this.checkService()) {
|
116
|
-
return;
|
117
|
-
}
|
118
|
-
|
119
|
-
// Events
|
120
|
-
this.subscribeSelfDataEvents();
|
121
|
-
|
122
|
-
// Fetch
|
123
|
-
await this.fetchLatestData();
|
124
|
-
|
125
|
-
this.logger.info("Inited");
|
126
|
-
}
|
127
|
-
|
128
|
-
cleanup() {
|
129
|
-
this.unsubscribeSelfDataEvents();
|
130
|
-
|
131
|
-
this.removeAllEventListeners();
|
132
|
-
|
133
|
-
this.SERVICE = undefined;
|
134
|
-
|
135
|
-
this.update(JSON.parse(JSON.stringify(INITIAL_INFO_DATA)) as LatestInfoData);
|
136
|
-
|
137
|
-
this.logger.info("Cleaned");
|
138
|
-
}
|
139
|
-
|
140
|
-
// initial data self watch calls
|
141
|
-
private async fetchLatestData() {
|
142
|
-
const profile = this.SERVICE?.conf.profile ? this.SERVICE?.conf.profile : await this.SERVICE?.conf.fetchProfile();
|
143
|
-
|
144
|
-
if (profile) {
|
145
|
-
const {
|
146
|
-
agentName,
|
147
|
-
agentProfileID,
|
148
|
-
teams,
|
149
|
-
defaultDn,
|
150
|
-
defaultIdleName,
|
151
|
-
agentSubStatus,
|
152
|
-
idleCodes,
|
153
|
-
wrapupCodes,
|
154
|
-
dialPlan,
|
155
|
-
isOutboundEnabledForTenant,
|
156
|
-
isOutboundEnabledForAgent
|
157
|
-
} = profile;
|
158
|
-
|
159
|
-
//
|
160
|
-
const [team] = teams;
|
161
|
-
const { teamId, teamName } = team;
|
162
|
-
const dn = defaultDn;
|
163
|
-
const status = defaultIdleName;
|
164
|
-
const subStatus = agentSubStatus;
|
165
|
-
//
|
166
|
-
const outDialRegex = AgentStateInfoJsapi.getOutdialRegex(dialPlan);
|
167
|
-
|
168
|
-
this.update({
|
169
|
-
agentName,
|
170
|
-
agentProfileID,
|
171
|
-
teamName,
|
172
|
-
teamId,
|
173
|
-
dn,
|
174
|
-
status,
|
175
|
-
subStatus,
|
176
|
-
idleCodes,
|
177
|
-
wrapupCodes,
|
178
|
-
outDialRegex,
|
179
|
-
isOutboundEnabledForTenant,
|
180
|
-
isOutboundEnabledForAgent
|
181
|
-
});
|
182
|
-
}
|
183
|
-
}
|
184
|
-
|
185
|
-
// Self data events
|
186
|
-
private subscribeSelfDataEvents() {
|
187
|
-
if (!this.checkService()) {
|
188
|
-
return;
|
189
|
-
}
|
190
|
-
|
191
|
-
// Relogin
|
192
|
-
{
|
193
|
-
const listenerRef = this.SERVICE?.aqm.agent.eAgentReloginSuccess.listen(({ data }) => {
|
194
|
-
const { agentSessionId, teamId, dn, status, subStatus } = data;
|
195
|
-
|
196
|
-
this.update({ agentSessionId, teamId, dn, status, subStatus });
|
197
|
-
});
|
198
|
-
|
199
|
-
this.listeners.add(() => listenerRef?.stopListen());
|
200
|
-
}
|
201
|
-
// StationLogin
|
202
|
-
{
|
203
|
-
const listenerRef = this.SERVICE?.aqm.agent.eAgentStationLoginSuccess.listen(({ data }) => {
|
204
|
-
const { agentSessionId, teamId, status, subStatus } = data;
|
205
|
-
|
206
|
-
this.update({ agentSessionId, teamId, status, subStatus });
|
207
|
-
});
|
208
|
-
|
209
|
-
this.listeners.add(() => listenerRef?.stopListen());
|
210
|
-
}
|
211
|
-
// StateChange
|
212
|
-
{
|
213
|
-
const listenerRef = this.SERVICE?.aqm.agent.eAgentStateChangeSuccess.listen(({ data }) => {
|
214
|
-
const { agentSessionId, status, subStatus } = data;
|
215
|
-
|
216
|
-
this.update({ agentSessionId, status, subStatus });
|
217
|
-
});
|
218
|
-
|
219
|
-
this.listeners.add(() => listenerRef?.stopListen());
|
220
|
-
}
|
221
|
-
// DN Registered
|
222
|
-
{
|
223
|
-
const listenerRef = this.SERVICE?.aqm.agent.eAgentDNRegistered.listen(({ data }) => {
|
224
|
-
const { dn } = data;
|
225
|
-
|
226
|
-
this.update({ dn });
|
227
|
-
});
|
228
|
-
|
229
|
-
this.listeners.add(() => listenerRef?.stopListen());
|
230
|
-
}
|
231
|
-
}
|
232
|
-
|
233
|
-
private unsubscribeSelfDataEvents() {
|
234
|
-
this.listeners.forEach(u => u());
|
235
|
-
|
236
|
-
this.listeners.clear();
|
237
|
-
}
|
238
|
-
|
239
|
-
// data calls
|
240
|
-
async stateChange(stateData: { state: "Available" | "Idle"; auxCodeIdArray: string }) {
|
241
|
-
if (!this.checkService()) {
|
242
|
-
return;
|
243
|
-
}
|
244
|
-
return this.SERVICE?.aqm.agent.stateChange({ data: stateData });
|
245
|
-
}
|
246
|
-
|
247
|
-
async mockOutdialAniList() {
|
248
|
-
if (!this.checkService()) {
|
249
|
-
return;
|
250
|
-
}
|
251
|
-
return this.SERVICE?.aqm.agent.mockOutdialAniList({ p: null });
|
252
|
-
}
|
253
|
-
|
254
|
-
async fetchAddressBooks() {
|
255
|
-
if (!this.checkService()) {
|
256
|
-
return;
|
257
|
-
}
|
258
|
-
return this.SERVICE?.aqm.agent.fetchAddressBooks({ p: null });
|
259
|
-
}
|
260
|
-
|
261
|
-
// data events
|
262
|
-
addEventListener<T extends Events>(eventName: T, listener: Listeners[T]) {
|
263
|
-
if (!this.checkService()) {
|
264
|
-
return;
|
265
|
-
}
|
266
|
-
this.emitter.on(eventName, listener);
|
267
|
-
}
|
268
|
-
|
269
|
-
removeEventListener<T extends Events>(eventName: T, listener: Listeners[T]) {
|
270
|
-
if (!this.checkService()) {
|
271
|
-
return;
|
272
|
-
}
|
273
|
-
this.emitter.off(eventName, listener);
|
274
|
-
}
|
275
|
-
|
276
|
-
removeAllEventListeners() {
|
277
|
-
allOff(this.emitter);
|
278
|
-
}
|
279
|
-
}
|
280
|
-
|
281
|
-
const agentInfoJsApiLogger = createJsApiLogger(logger, "[AgentInfo JSAPI] =>");
|
282
|
-
|
283
|
-
// Standalone init
|
284
|
-
export const createAgentStateInfoJsApi = () =>
|
285
|
-
new AgentStateInfoJsapi({
|
286
|
-
logger: agentInfoJsApiLogger,
|
287
|
-
serviceChecker: createServiceChecker({ logger: agentInfoJsApiLogger })
|
288
|
-
});
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { createJsApiLogger } from "./_logger";
|
2
|
-
|
3
|
-
describe("Common Logger", () => {
|
4
|
-
it("creates", () => {
|
5
|
-
const logger = createJsApiLogger(
|
6
|
-
{
|
7
|
-
info: () => {},
|
8
|
-
warn: () => {},
|
9
|
-
error: () => {}
|
10
|
-
},
|
11
|
-
"TEST"
|
12
|
-
);
|
13
|
-
|
14
|
-
expect(logger).toBeDefined();
|
15
|
-
});
|
16
|
-
});
|
@@ -1,9 +0,0 @@
|
|
1
|
-
import { Logger } from "@uuip/unified-ui-platform-sdk";
|
2
|
-
|
3
|
-
type SeverityLogger = Pick<Logger.Service, "info" | "warn" | "error">;
|
4
|
-
|
5
|
-
export const createJsApiLogger = (logger: SeverityLogger, subPrefix: string): SeverityLogger => ({
|
6
|
-
info: (...args: any[]) => logger.info(subPrefix, ...args),
|
7
|
-
warn: (...args: any[]) => logger.warn(subPrefix, ...args),
|
8
|
-
error: (...args: any[]) => logger.error(subPrefix, ...args)
|
9
|
-
});
|
@@ -1,44 +0,0 @@
|
|
1
|
-
import { AgentxServices, SERVICE } from "@wxcc-desktop/sdk-types";
|
2
|
-
import { createServiceChecker } from "./_service-checker";
|
3
|
-
|
4
|
-
jest.mock("@wxcc-desktop/sdk-types", () => {
|
5
|
-
const agentx_services_mock = {
|
6
|
-
SERVICE: {
|
7
|
-
isInited: false,
|
8
|
-
init: async (accessToken: string) => {
|
9
|
-
agentx_services_mock.SERVICE.isInited = true;
|
10
|
-
}
|
11
|
-
} as AgentxServices
|
12
|
-
};
|
13
|
-
return agentx_services_mock;
|
14
|
-
});
|
15
|
-
|
16
|
-
describe("Common Service Checker", () => {
|
17
|
-
let serviceChecker: ReturnType<typeof createServiceChecker>;
|
18
|
-
|
19
|
-
beforeEach(() => {
|
20
|
-
serviceChecker = createServiceChecker({
|
21
|
-
logger: {
|
22
|
-
info: () => {},
|
23
|
-
warn: () => {},
|
24
|
-
error: () => {}
|
25
|
-
}
|
26
|
-
});
|
27
|
-
});
|
28
|
-
|
29
|
-
it("creates", () => {
|
30
|
-
expect(serviceChecker).toBeDefined();
|
31
|
-
});
|
32
|
-
|
33
|
-
it("checks", async () => {
|
34
|
-
const res1 = serviceChecker.check();
|
35
|
-
expect(res1).toBeFalsy();
|
36
|
-
|
37
|
-
const res2 = serviceChecker.check(SERVICE);
|
38
|
-
expect(res2).toBeFalsy();
|
39
|
-
|
40
|
-
await (SERVICE as AgentxServices).init("fake-token");
|
41
|
-
const res3 = serviceChecker.check(SERVICE);
|
42
|
-
expect(res3).toBeTruthy();
|
43
|
-
});
|
44
|
-
});
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import { AgentxService } from "@wxcc-desktop/sdk-types";
|
2
|
-
import { createJsApiLogger } from "./_logger";
|
3
|
-
|
4
|
-
type Config = { logger: ReturnType<typeof createJsApiLogger> };
|
5
|
-
|
6
|
-
export class ServiceChecker {
|
7
|
-
private readonly logger: Config["logger"];
|
8
|
-
|
9
|
-
constructor(config: Config) {
|
10
|
-
this.logger = config.logger;
|
11
|
-
}
|
12
|
-
|
13
|
-
check(SERVICE?: AgentxService) {
|
14
|
-
if (!SERVICE) {
|
15
|
-
this.logger.error("SERVICE is not defined...");
|
16
|
-
return false;
|
17
|
-
}
|
18
|
-
|
19
|
-
if (!SERVICE.isInited) {
|
20
|
-
this.logger.error("SERVICE still not initialized... Await it's init(...) first.");
|
21
|
-
return false;
|
22
|
-
}
|
23
|
-
|
24
|
-
return true;
|
25
|
-
}
|
26
|
-
}
|
27
|
-
|
28
|
-
export const createServiceChecker = (config: Config) => new ServiceChecker(config);
|
@@ -1,122 +0,0 @@
|
|
1
|
-
import { Signal } from "@uuip/unified-ui-platform-sdk";
|
2
|
-
import { logger } from "../../sdk";
|
3
|
-
import { createServiceEvents } from "./_service-events";
|
4
|
-
|
5
|
-
describe("Common Service Events", () => {
|
6
|
-
type Listeners = {
|
7
|
-
TEST: (...args: any[]) => void;
|
8
|
-
};
|
9
|
-
const creator = () =>
|
10
|
-
createServiceEvents<Listeners>({
|
11
|
-
logger: logger
|
12
|
-
});
|
13
|
-
let serviceEvents: ReturnType<typeof creator>;
|
14
|
-
let aqmServiceEntity: any;
|
15
|
-
|
16
|
-
beforeEach(() => {
|
17
|
-
serviceEvents = creator();
|
18
|
-
const { signal } = Signal.create.empty();
|
19
|
-
aqmServiceEntity = {
|
20
|
-
TEST: signal
|
21
|
-
};
|
22
|
-
});
|
23
|
-
|
24
|
-
it("creates", () => {
|
25
|
-
expect(serviceEvents).toBeDefined();
|
26
|
-
});
|
27
|
-
|
28
|
-
it("inits", () => {
|
29
|
-
expect(serviceEvents.isInited).toBeFalsy();
|
30
|
-
|
31
|
-
serviceEvents.init({
|
32
|
-
aqmServiceEntity: aqmServiceEntity,
|
33
|
-
aqmServiceEntityString: "ttt"
|
34
|
-
});
|
35
|
-
|
36
|
-
expect(serviceEvents.isInited).toBeTruthy();
|
37
|
-
});
|
38
|
-
|
39
|
-
it("listens", () => {
|
40
|
-
serviceEvents.init({
|
41
|
-
aqmServiceEntity: aqmServiceEntity,
|
42
|
-
aqmServiceEntityString: "ttt"
|
43
|
-
});
|
44
|
-
|
45
|
-
let counter = 0;
|
46
|
-
const listener: Listeners["TEST"] = () => {
|
47
|
-
counter++;
|
48
|
-
};
|
49
|
-
|
50
|
-
serviceEvents.addEventListener("TEST", listener);
|
51
|
-
|
52
|
-
aqmServiceEntity.TEST.send("A");
|
53
|
-
aqmServiceEntity.TEST.send("B");
|
54
|
-
|
55
|
-
serviceEvents.removeEventListener("TEST", listener);
|
56
|
-
|
57
|
-
expect(counter).toBe(2);
|
58
|
-
});
|
59
|
-
|
60
|
-
it("listensOnce", () => {
|
61
|
-
serviceEvents.init({
|
62
|
-
aqmServiceEntity: aqmServiceEntity,
|
63
|
-
aqmServiceEntityString: "ttt"
|
64
|
-
});
|
65
|
-
|
66
|
-
let counter = 0;
|
67
|
-
const listener: Listeners["TEST"] = () => counter++;
|
68
|
-
|
69
|
-
serviceEvents.addOnceEventListener("TEST", listener);
|
70
|
-
|
71
|
-
aqmServiceEntity.TEST.send("C");
|
72
|
-
aqmServiceEntity.TEST.send("D");
|
73
|
-
|
74
|
-
serviceEvents.removeOnceEventListener("TEST", listener);
|
75
|
-
|
76
|
-
expect(counter).toBe(1);
|
77
|
-
});
|
78
|
-
|
79
|
-
it("removes all listeners", () => {
|
80
|
-
serviceEvents.init({
|
81
|
-
aqmServiceEntity: aqmServiceEntity,
|
82
|
-
aqmServiceEntityString: "ttt"
|
83
|
-
});
|
84
|
-
|
85
|
-
let counter1 = 0;
|
86
|
-
let counter2 = 0;
|
87
|
-
const listener1: Listeners["TEST"] = () => counter1++;
|
88
|
-
const listener2: Listeners["TEST"] = () => counter2++;
|
89
|
-
|
90
|
-
serviceEvents.addEventListener("TEST", listener1);
|
91
|
-
serviceEvents.addOnceEventListener("TEST", listener2);
|
92
|
-
|
93
|
-
aqmServiceEntity.TEST.send("E");
|
94
|
-
aqmServiceEntity.TEST.send("F");
|
95
|
-
|
96
|
-
serviceEvents.removeAllEventListeners();
|
97
|
-
|
98
|
-
aqmServiceEntity.TEST.send("G");
|
99
|
-
|
100
|
-
expect(counter1).toBe(2);
|
101
|
-
expect(counter2).toBe(1);
|
102
|
-
});
|
103
|
-
|
104
|
-
it("cleanups", () => {
|
105
|
-
serviceEvents.init({
|
106
|
-
aqmServiceEntity: aqmServiceEntity,
|
107
|
-
aqmServiceEntityString: "ttt"
|
108
|
-
});
|
109
|
-
|
110
|
-
let counter = 0;
|
111
|
-
const listener: Listeners["TEST"] = () => counter++;
|
112
|
-
|
113
|
-
serviceEvents.addEventListener("TEST", listener);
|
114
|
-
|
115
|
-
serviceEvents.cleanup();
|
116
|
-
|
117
|
-
aqmServiceEntity.TEST.send("H");
|
118
|
-
|
119
|
-
expect(counter).toBe(0);
|
120
|
-
expect(serviceEvents.isInited).toBeFalsy();
|
121
|
-
});
|
122
|
-
});
|
@@ -1,156 +0,0 @@
|
|
1
|
-
import { AgentxService } from "@wxcc-desktop/sdk-types";
|
2
|
-
import { createJsApiLogger } from "./_logger";
|
3
|
-
|
4
|
-
type AqmServiceEntities =
|
5
|
-
| AgentxService["aqm"]["agent"]
|
6
|
-
| AgentxService["aqm"]["configs"]
|
7
|
-
| AgentxService["aqm"]["contact"]
|
8
|
-
| AgentxService["aqm"]["dialer"]
|
9
|
-
| AgentxService["aqm"]["screenpop"];
|
10
|
-
|
11
|
-
type Unlisten = () => void;
|
12
|
-
type Events<Listeners> = keyof Listeners;
|
13
|
-
type ListenersUnlistenMap<Listeners> = Map<Events<Listeners>, Map<Listeners[Events<Listeners>], Unlisten>>;
|
14
|
-
|
15
|
-
type Config = { logger: ReturnType<typeof createJsApiLogger> };
|
16
|
-
type InitConfig = { aqmServiceEntity: AqmServiceEntities; aqmServiceEntityString: string };
|
17
|
-
|
18
|
-
export class AqmServiceEntityEvents<Listeners> {
|
19
|
-
private readonly logger: Config["logger"];
|
20
|
-
|
21
|
-
private aqmServiceEntity?: AqmServiceEntities;
|
22
|
-
private aqmServiceEntityString?: string;
|
23
|
-
|
24
|
-
isInited = false;
|
25
|
-
|
26
|
-
constructor(config: Config) {
|
27
|
-
this.logger = config.logger;
|
28
|
-
}
|
29
|
-
|
30
|
-
init(config: InitConfig) {
|
31
|
-
this.aqmServiceEntity = config.aqmServiceEntity;
|
32
|
-
this.aqmServiceEntityString = config.aqmServiceEntityString;
|
33
|
-
|
34
|
-
this.isInited = true;
|
35
|
-
}
|
36
|
-
|
37
|
-
cleanup() {
|
38
|
-
this.removeAllEventListeners();
|
39
|
-
this.aqmServiceEntity = undefined;
|
40
|
-
this.aqmServiceEntityString = undefined;
|
41
|
-
|
42
|
-
this.isInited = false;
|
43
|
-
}
|
44
|
-
|
45
|
-
private listeners: ListenersUnlistenMap<Listeners> = new Map();
|
46
|
-
private listenersOnce: ListenersUnlistenMap<Listeners> = new Map();
|
47
|
-
|
48
|
-
// data events
|
49
|
-
private _addEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T], isOnce: boolean) {
|
50
|
-
type MultiListenerRef = { stopListen: () => boolean };
|
51
|
-
type OnceListenerRef = { stopListenOnce: () => boolean };
|
52
|
-
type ListenerRef = MultiListenerRef | OnceListenerRef;
|
53
|
-
const _listeners = !isOnce ? "listeners" : "listenersOnce";
|
54
|
-
if (!this[_listeners].has(eventName)) {
|
55
|
-
this[_listeners].set(eventName, new Map());
|
56
|
-
}
|
57
|
-
const _map = this[_listeners].get(eventName);
|
58
|
-
const _listen = !isOnce ? "listen" : "listenOnce";
|
59
|
-
const createUnlisten = (listenerRef: ListenerRef) => {
|
60
|
-
// Auto-remove outer once listener
|
61
|
-
let onceWatchListenerRef: OnceListenerRef | null = null;
|
62
|
-
if (isOnce) {
|
63
|
-
onceWatchListenerRef = (this.aqmServiceEntity as any)[eventName]["listenOnce"](() =>
|
64
|
-
this.removeOnceEventListener(eventName, listener)
|
65
|
-
);
|
66
|
-
}
|
67
|
-
//
|
68
|
-
return () => {
|
69
|
-
if (listenerRef) {
|
70
|
-
if (!isOnce) {
|
71
|
-
(listenerRef as MultiListenerRef).stopListen();
|
72
|
-
} else {
|
73
|
-
(listenerRef as OnceListenerRef).stopListenOnce();
|
74
|
-
onceWatchListenerRef && onceWatchListenerRef.stopListenOnce();
|
75
|
-
}
|
76
|
-
const logMsgs = [];
|
77
|
-
logMsgs.push(`UnBound "${eventName}"`);
|
78
|
-
if (isOnce) {
|
79
|
-
logMsgs.push(`Once`);
|
80
|
-
}
|
81
|
-
if (this.aqmServiceEntityString) {
|
82
|
-
logMsgs.push(`from "${this.aqmServiceEntityString}"`);
|
83
|
-
}
|
84
|
-
this.logger?.info(logMsgs.join(" "));
|
85
|
-
}
|
86
|
-
};
|
87
|
-
};
|
88
|
-
|
89
|
-
if (this.aqmServiceEntity) {
|
90
|
-
if (eventName in this.aqmServiceEntity && _listen in (this.aqmServiceEntity as any)[eventName]) {
|
91
|
-
const listenerRef: ListenerRef = (this.aqmServiceEntity as any)[eventName][_listen](listener);
|
92
|
-
_map!.set(listener, createUnlisten(listenerRef));
|
93
|
-
const logMsgs = [];
|
94
|
-
logMsgs.push(`Bound "${eventName}"`);
|
95
|
-
if (isOnce) {
|
96
|
-
logMsgs.push(`Once`);
|
97
|
-
}
|
98
|
-
if (this.aqmServiceEntityString) {
|
99
|
-
logMsgs.push(`to "${this.aqmServiceEntityString}"`);
|
100
|
-
}
|
101
|
-
|
102
|
-
this.logger?.info(logMsgs.join(" "));
|
103
|
-
} else {
|
104
|
-
this.logger?.warn(`EventName "${eventName}" is not recognized, so won't be subscribed...`);
|
105
|
-
}
|
106
|
-
} else {
|
107
|
-
this.logger?.error(`"${this.aqmServiceEntityString}" is not ready yet. .init(...) first...`);
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
private _removeEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T], isOnce: boolean) {
|
112
|
-
const _listeners = !isOnce ? "listeners" : "listenersOnce";
|
113
|
-
if (this[_listeners].has(eventName)) {
|
114
|
-
const _map = this[_listeners].get(eventName);
|
115
|
-
if (_map) {
|
116
|
-
if (_map.has(listener)) {
|
117
|
-
const unlisten = _map!.get(listener);
|
118
|
-
unlisten!();
|
119
|
-
_map!.delete(listener);
|
120
|
-
}
|
121
|
-
if (_map.size < 1) {
|
122
|
-
this[_listeners].delete(eventName);
|
123
|
-
}
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
127
|
-
|
128
|
-
addEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T]) {
|
129
|
-
this._addEventListener(eventName, listener, false);
|
130
|
-
}
|
131
|
-
|
132
|
-
addOnceEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T]) {
|
133
|
-
this._addEventListener(eventName, listener, true);
|
134
|
-
}
|
135
|
-
|
136
|
-
removeEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T]) {
|
137
|
-
this._removeEventListener(eventName, listener, false);
|
138
|
-
}
|
139
|
-
|
140
|
-
removeOnceEventListener<T extends Events<Listeners>>(eventName: T, listener: Listeners[T]) {
|
141
|
-
this._removeEventListener(eventName, listener, true);
|
142
|
-
}
|
143
|
-
|
144
|
-
removeAllEventListeners() {
|
145
|
-
const listeners = ["listeners", "listenersOnce"] as const;
|
146
|
-
listeners.forEach(_listenrs => {
|
147
|
-
this[_listenrs].forEach((_map, eventName) => {
|
148
|
-
_map.forEach((unlisten, listener) => unlisten());
|
149
|
-
_map.clear();
|
150
|
-
});
|
151
|
-
this[_listenrs].clear();
|
152
|
-
});
|
153
|
-
}
|
154
|
-
}
|
155
|
-
|
156
|
-
export const createServiceEvents = <Listeners>(config: Config) => new AqmServiceEntityEvents<Listeners>(config);
|